ipyvasp 0.9.6__py2.py3-none-any.whl → 0.9.8__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
@@ -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,49 @@ 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
+ index : int
1576
+ x : float
1577
+ y : float
1578
+ z : float
1579
+
1580
+ @property
1581
+ def p(self): return np.array([self.x,self.y,self.z]) # for robust operations
1582
+
1583
+ class _AtomLabel(str):
1584
+ "Object passed to `fmt_label` in plotting. `number` and `symbol` are additional attributes and `to_latex` is a method."
1585
+ @property
1586
+ def number(self): return int(self.split()[1])
1587
+ @property
1588
+ def symbol(self): return self.split()[0]
1589
+ def to_latex(self): return "{}$_{{{}}}$".format(*self.split())
1572
1590
 
1573
- if len(inspect.signature(func).parameters) != 4:
1591
+ def _validate_func(func):
1592
+ if not callable(func):
1593
+ raise ValueError("`func` must be a callable function with single parameter `Atom(symbol,index,x,y,z)`.")
1594
+
1595
+ if len(inspect.signature(func).parameters) != 1:
1574
1596
  raise ValueError(
1575
- "`func` takes exactly 4 arguments: (index,x,y,z) in fractional coordinates"
1597
+ "`func` takes exactly 1 argument: `Atom(symbol,index,x,y,z)` in fractional coordinates"
1598
+ )
1599
+
1600
+ ret = func(_Atom('',0,0,0,0))
1601
+ if not isinstance(ret, (bool, np.bool_)):
1602
+ raise ValueError(
1603
+ f"`func` must be a function that returns a bool, got {type(ret)}."
1576
1604
  )
1577
1605
 
1578
- if not isinstance(func(0, 0, 0, 0), bool):
1579
- raise TypeError("`func` should return a boolean value.")
1580
-
1606
+ def _masked_data(poscar_data, func):
1607
+ "Returns indices of sites which satisfy the func."
1608
+ _validate_func(func)
1581
1609
  eqv_inds = tuple(getattr(poscar_data.metadata, "eqv_indices",[]))
1582
1610
 
1583
1611
  pick = []
1584
1612
  for i, pos in enumerate(poscar_data.positions):
1585
1613
  idx = eqv_inds[i] if eqv_inds else i # map to original index
1586
- if func(idx, *pos):
1614
+ if func(_Atom(poscar_data.symbols[i], idx, *pos)): # symbols based on i, not eqv_idx
1587
1615
  pick.append(i)
1588
1616
  return pick # could be duplicate indices
1589
1617
 
@@ -1604,8 +1632,8 @@ def _filter_pairs(labels, pairs, dist, bond_length):
1604
1632
  # Return all pairs otherwise
1605
1633
  return pairs # None -> auto calculate bond_length, number -> use that number
1606
1634
 
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`.
1635
+ def filter_atoms(poscar_data, func, tol = 0.01):
1636
+ """Filter atomic sites based on a function that acts on an atom such as `lambda a: (a.p < 1/2).all()`. `p` is additional property to get array([x,y,z]) togther.
1609
1637
  This may include equivalent sites, so it should be used for plotting purpose only, e.g. showing atoms on a plane.
1610
1638
  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
1639
 
@@ -1804,13 +1832,13 @@ def iplot_lattice(
1804
1832
  return fig
1805
1833
 
1806
1834
 
1807
- def _validate_label_func(fmt_label, parameter):
1835
+ def _validate_label_func(fmt_label,label):
1808
1836
  if not callable(fmt_label):
1809
1837
  raise ValueError("fmt_label must be a callable function.")
1810
1838
  if len(inspect.signature(fmt_label).parameters.values()) != 1:
1811
- raise ValueError("fmt_label must have only one argument.")
1839
+ raise ValueError("fmt_label must have only one argument that accepts a str like 'Ga 1'.")
1812
1840
 
1813
- test_out = fmt_label(parameter)
1841
+ test_out = fmt_label(_AtomLabel(label))
1814
1842
  if isinstance(test_out, (list, tuple)):
1815
1843
  if len(test_out) != 2:
1816
1844
  raise ValueError(
@@ -1903,7 +1931,7 @@ def splot_lattice(
1903
1931
  bond_kws : dict
1904
1932
  Keyword arguments to pass to `LineCollection`/`Line3DCollection` for plotting bonds.
1905
1933
  fmt_label : callable
1906
- If given, each site label is passed to it like fmt_label('Ga 1').
1934
+ 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`, e.g. `lambda lab: lab.to_latex()`.
1907
1935
  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
1936
  plot_cell : bool
1909
1937
  Default is True, plot unit cell with default settings.
@@ -1935,7 +1963,7 @@ def splot_lattice(
1935
1963
  pairs = _filter_pairs(labels, pairs, dist, bond_length)
1936
1964
 
1937
1965
  if fmt_label is not None:
1938
- _validate_label_func(fmt_label, labels[0])
1966
+ _validate_label_func(fmt_label,labels[0])
1939
1967
 
1940
1968
  if plot_cell:
1941
1969
  bz_data = serializer.CellData(
@@ -2002,7 +2030,7 @@ def splot_lattice(
2002
2030
  )
2003
2031
  if fmt_label:
2004
2032
  for i, coord in enumerate(coords):
2005
- lab, textkws = fmt_label(labels[i]), {}
2033
+ lab, textkws = fmt_label(_AtomLabel(labels[i])), {}
2006
2034
  if isinstance(lab, (list, tuple)):
2007
2035
  lab, textkws = lab
2008
2036
  ax.text(*coord, lab, **textkws)
@@ -2027,7 +2055,7 @@ def splot_lattice(
2027
2055
  if fmt_label:
2028
2056
  labels = [labels[i] for i in zorder] # Reorder labels
2029
2057
  for i, coord in enumerate(coords[zorder]):
2030
- lab, textkws = fmt_label(labels[i]), {}
2058
+ lab, textkws = fmt_label(_AtomLabel(labels[i])), {}
2031
2059
  if isinstance(lab, (list, tuple)):
2032
2060
  lab, textkws = lab
2033
2061
  ax.text(*coord[[ix, iy]], lab, **textkws)
@@ -2512,24 +2540,8 @@ def add_atoms(poscar_data, name, positions):
2512
2540
  return serializer.PoscarData(data) # Return new POSCAR
2513
2541
 
2514
2542
 
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
2543
  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)
2544
+ """Replace atoms satisfying a `func(atom) -> bool` with a new `name`. Like `lambda a: a.symbol == 'Ga'`"""
2533
2545
  data = poscar_data.to_dict() # Copy data to avoid modifying original
2534
2546
  mask = _masked_data(poscar_data, func)
2535
2547
  new_types = {**{k: [] for k in poscar_data.types.keys()}, name: []}
@@ -2570,19 +2582,18 @@ def sort_poscar(poscar_data, new_order):
2570
2582
 
2571
2583
  return serializer.PoscarData(data)
2572
2584
 
2573
-
2574
2585
  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.
2586
+ """Remove atoms that satisfy `func(atom) -> bool` on their fractional coordinates like `lambda a: all(a.p < 1/2)`. `p` is additional property to get array([x,y,z]) togther.
2576
2587
  If `fillby` is given, it will fill the removed atoms with atoms from fillby POSCAR.
2577
2588
 
2578
2589
  .. note::
2579
2590
  The coordinates of fillby POSCAR are transformed to basis of given POSCAR, before filling.
2580
2591
  So a good filling is only guaranteed if both POSCARs have smaller lattice mismatch.
2581
2592
  """
2582
- _validate_func(func, 3, bool)
2593
+ _validate_func(func) # need to validate for fillbay
2583
2594
  data = poscar_data.to_dict() # Copy data to avoid modifying original
2584
2595
  positions = data["positions"]
2585
- mask = _masked_data(poscar_data, lambda i, x, y, z: not func(x, y, z))
2596
+ mask = _masked_data(poscar_data, lambda s: not func(s))
2586
2597
 
2587
2598
  new_types = {k: [] for k in poscar_data.types.keys()}
2588
2599
  for k, vs in data["types"].items():
@@ -2601,7 +2612,7 @@ def remove_atoms(poscar_data, func, fillby=None):
2601
2612
 
2602
2613
  def keep_pos(i, x, y, z): # keep positions in basis of given data
2603
2614
  u, v, w = to_basis(poscar_data.basis, to_R3(fillby.basis, [[x, y, z]]))[0]
2604
- return bool(func(u, v, w))
2615
+ return bool(func(_Atom('', 0, u, v, w)))
2605
2616
 
2606
2617
  mask = _masked_data(fillby, keep_pos)
2607
2618
  N_prev = len(data["positions"]) # before filling
ipyvasp/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.9.6"
1
+ __version__ = "0.9.8"
ipyvasp/bsdos.py CHANGED
@@ -35,7 +35,8 @@ from ._enplots import (
35
35
  def _format_input(projections, sys_info):
36
36
  """
37
37
  Format input spins, atoms, orbs and labels according to selected `projections`.
38
- For example: {'Ga-s':(0,[1]),'Ga-p':(0,[1,2,3]),'Ga-d':(0,[4,5,6,7,8])} #for Ga in GaAs, to pick Ga-1, use [0] instead of 0 at first place
38
+ For example: {'Ga-s':(0,[0]),'Ga-px+py':(0,[2,3]),'Ga-all':(0,'all')} #for Ga in GaAs, to pick Ga-1, use [0] instead of 0 at first place
39
+ or {'Ga-s':('Ga','s'),'Ga-px+py':(0,'px+py'),'all-d':('all','d')}
39
40
  In case of 3 items in tuple, the first item is spin index, the second is atoms, the third is orbs.
40
41
  """
41
42
  if not isinstance(projections, dict):
@@ -53,6 +54,11 @@ def _format_input(projections, sys_info):
53
54
  ) # will be error if two ranges there to compare for max
54
55
  norbs = len(sys_info.orbs)
55
56
 
57
+ orbs_map = {} # total if components given
58
+ if 'px' in sys_info.orbs: orbs_map['p'] = range(1,4)
59
+ if 'dxy' in sys_info.orbs: orbs_map['d'] = range(4,9)
60
+ if 'f0' in sys_info.orbs: orbs_map['f'] = range(9,16)
61
+
56
62
  # Set default values for different situations
57
63
  spins, atoms, orbs, labels = [], [], [], []
58
64
 
@@ -78,6 +84,24 @@ def _format_input(projections, sys_info):
78
84
  )
79
85
 
80
86
  spins.append(S) # Only add spins if given
87
+
88
+ if isinstance(A,str):
89
+ if A.lower() == 'all':
90
+ A = range(max_ind + 1)
91
+ else:
92
+ if not A in sys_info.types.keys():
93
+ raise KeyError(f"type {A!r} not found. Available are {list(sys_info.types.keys())}, 'all', or indexing with integeres/list of intergers.")
94
+ A = sys_info.types[A]
95
+
96
+ if isinstance(B,str):
97
+ if B.lower() == 'all':
98
+ B = range(norbs)
99
+ else:
100
+ B = {b:[sys_info.orbs.index(b)] if b in sys_info.orbs else orbs_map.get(b,[]) for b in (a.strip() for a in B.split('+'))}
101
+ for key, value in B.items():
102
+ if not value:
103
+ raise KeyError(f"orbital {key!r} not found. Available are {sys_info.orbs}, 'all' or indexing with integers/list of intergers")
104
+ B = list(sorted(set([i for b in B.values() for i in b]))) # flatten
81
105
 
82
106
  if not isinstance(A, (int, np.integer, list, tuple, range)):
83
107
  raise TypeError(f"{A!r} is not an integer or list/tuple/range of integers.")
@@ -129,7 +153,7 @@ def _format_input(projections, sys_info):
129
153
 
130
154
  if spins and len(atoms) != len(spins):
131
155
  raise ValueError(
132
- "You should provide spin for each projection or none at all. If not provided, spin is picked from corresponding eigenvalues (up/down) for all projections."
156
+ "You should provide spin for each projection or none at all. If not provided, spin is picked from corresponding eigenvalues (up/down) for all projections using 'spin' parameter explicity."
133
157
  )
134
158
 
135
159
  uatoms = np.unique(
@@ -139,7 +163,7 @@ def _format_input(projections, sys_info):
139
163
  uorbs = tuple(uorbs) if len(uorbs) < norbs else -1 # -1 means all orbitals
140
164
  uatoms = tuple(uatoms) if len(uatoms) == (max_ind + 1) else -1 # -1 means all atoms
141
165
  uspins = tuple(spins)
142
-
166
+
143
167
  return (spins, uspins), (atoms, uatoms), (orbs, uorbs), labels
144
168
 
145
169
 
@@ -154,8 +178,8 @@ bands : list/tuple
154
178
  List of indices of bands. If given, this ovverides elim."""
155
179
  _proj_doc = """projections : dict
156
180
  Mapping from str -> [atoms, orbs]. Use dict to select specific projections,
157
- e.g. {'Ga-s': (0,[0]), 'Ga1-p': ([0],[1,2,3])} in case of GaAs. If values of the dict
158
- are callable, they must accept two arguments evals/tdos, occs/idos of from data and
181
+ e.g. {'Ga-s':(0,[0]),'Ga-px+py':(0,[2,3]),'Ga-all':(0,'all')} or {'Ga-s':('Ga','s'),'Ga-px+py':(0,'px+py'),'all-d':('all','d')}.
182
+ If values of the dict are callable, they must accept two arguments evals/tdos, occs/idos of from data and
159
183
  should return array of shape[1:] (all but spin dimension)."""
160
184
 
161
185
 
ipyvasp/core/parser.py CHANGED
@@ -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,11 @@ 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 sites(self):
334
+ "Returns data with types mapped to their positions."
335
+ return Dict2Data({k: self.positions[v] for k,v in self.types.items()})
336
+
332
337
  @property
333
338
  def G(self):
334
339
  """Return metric tensor to be used with fractional coordinates.
@@ -342,6 +347,7 @@ class PoscarData(Dict2Data):
342
347
 
343
348
  def metric(self, points):
344
349
  """Shortcut for `np.linalg.norm(self.to_cartesian(points),axis=<1 or 0>)`. `points` are assumed as fractional coordinates in `self.basis`.
350
+ You can compute metric from any point other than origin by just subtracting that point, e.g. `points - 0.5` will get metric from center of cell (1/2,1/2,1/2).
345
351
  """
346
352
  return np.linalg.norm(self.to_cartesian(points),axis=1 if np.ndim(points) == 2 else 0)
347
353
 
@@ -487,26 +493,28 @@ class PoscarData(Dict2Data):
487
493
  """
488
494
  Returns a dictionary of {'Ga 1': 'T T T', 'As 1': 'T F F',...} for each atom in the poscar data.
489
495
 
490
- `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.
496
+ `func` should be a callable like `func(Atom(symbol,index,x,y,z)) -> (bool, bool, bool)` which turns on/off selective dynamics for each atom based in each dimension.
491
497
 
492
498
  You can visualize selective dynamics sites by their labels as follows:
493
499
 
494
500
 
495
501
  >>> poscar = POSCAR.from_file('POSCAR')
496
- >>> 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
502
+ >>> sd = poscar.data.get_selective_dynamics(lambda a: (True, False, True) if a.index % 2 == 0 else (False, True, False)) # Just an example
497
503
  >>> poscar.splot_lattice(..., fmt_label = lambda lab: sd[lab]) # This will label sites as T T T, F F F, ... and so so on
498
504
  """
499
505
  if not callable(func):
500
506
  raise TypeError(
501
- "`func` should be a callable function(index, [point in fractional coordinates])!"
507
+ "`func` should be a callable with one paramter `Atom(symbol,index, x,y,z)`"
502
508
  )
503
509
 
504
- if len(inspect.signature(func).parameters) != 4:
510
+ if len(inspect.signature(func).parameters) != 1:
505
511
  raise ValueError(
506
- "`func` should be a callable function with four paramters (index, x,y,z) in fractional coordinates."
512
+ "`func` should be a callable function with one paramter `Atom(symbol,index, x,y,z)` in fractional coordinates."
507
513
  )
514
+
515
+ from .._lattice import _Atom # avoids circular import
508
516
 
509
- test_output = func(0, 0, 0, 0)
517
+ test_output = func(_Atom('',0, 0, 0, 0))
510
518
  if (
511
519
  not isinstance(test_output, (list, tuple, np.ndarray))
512
520
  or len(test_output) != 3
@@ -516,13 +524,13 @@ class PoscarData(Dict2Data):
516
524
  )
517
525
 
518
526
  for out in test_output:
519
- if not isinstance(out, bool):
527
+ if not isinstance(out, (bool,np.bool_)):
520
528
  raise ValueError(
521
529
  "`func` should return boolean values in list/tuple/array like (True, False, True)"
522
530
  )
523
531
 
524
532
  sd_list = [
525
- " ".join("T" if s else "F" for s in func(i, *p))
533
+ " ".join("T" if s else "F" for s in func(_Atom(self.symbols[i],i, *p)))
526
534
  for i, p in enumerate(self.positions)
527
535
  ]
528
536
  labels = np.array(
ipyvasp/lattice.py CHANGED
@@ -317,9 +317,9 @@ class POSCAR:
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.index in pc.data.types.Ga) # FINE
321
+ pc.set_boundary([-2,2]).filter_atoms(lambda a: a.index in pc.data.types.Ga) # INCORRECT sites picked
322
+ 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
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.
@@ -358,9 +358,9 @@ class POSCAR:
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):
ipyvasp/widgets.py CHANGED
@@ -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.6
3
+ Version: 0.9.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
@@ -1,25 +1,25 @@
1
1
  ipyvasp/__init__.py,sha256=rlorju9arMtHw1QRYPljday-PyZWJdSCxg4lw3g6t0Q,1409
2
2
  ipyvasp/__main__.py,sha256=eJV1TZSiT8mC_VqAeksNnBI2I8mKMiPkEIlwikbtOjI,216
3
3
  ipyvasp/_enplots.py,sha256=D38paN8zqZgluNAwmCwcocd7-_h_T0HTGolI1eBkDes,37484
4
- ipyvasp/_lattice.py,sha256=GxG0C4lwVGvBYIy3jwR1kahWR7L6kJlqjIiQGgESjcM,104135
5
- ipyvasp/_version.py,sha256=DUP796j17_h9tFqkdOpSu_66sw_6eSK4S2hN7yd9i9o,23
6
- ipyvasp/bsdos.py,sha256=1rG68S-dLEYveIWGK7r8CRa7Qqlqno0l1ncfo2ocihk,30424
4
+ ipyvasp/_lattice.py,sha256=ixvvaMgOjSWFrvJGQC5K9jmq9lfTwrLArYq7Pas7ars,104984
5
+ ipyvasp/_version.py,sha256=4eQCGJV2-GRHX8FlvA_4etK0E4LFj2or592J4aePZoA,23
6
+ ipyvasp/bsdos.py,sha256=JvYvHLqMp3eVaJ0amD-9kxp7FehQIFq3WFUxsO5dj0Q,31794
7
7
  ipyvasp/cli.py,sha256=aWFEVhNmnW8eSOp5uh95JaDwLQ9K9nlCQcbnOSuhWgw,6844
8
8
  ipyvasp/evals_dataframe.py,sha256=-sqxK7LPV6sYDO_XXmZ80FznOaXTkVdbqJKKvTUtMak,20637
9
- ipyvasp/lattice.py,sha256=t4s1qh6IJsoeXcCa9M9IhjAQp2s78lqiGhOfEkCW19s,30638
9
+ ipyvasp/lattice.py,sha256=YA0_wuB_tU5_GyUybRddoOhTwYqG2_-NyKxQe74hm0w,30627
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
13
13
  ipyvasp/utils.py,sha256=rVyD5SkO_Y7ok5W-fJeQys9X8pLLbDK7VOgbAbcE4WU,14227
14
- ipyvasp/widgets.py,sha256=hwCviQn5NmxFz15DTS2nKKJ0kdBq8taGude46KNDOtU,46605
14
+ ipyvasp/widgets.py,sha256=izqe1dffMWJrfojKM5RuqABCmjhNQAIjM3aoJ9tga0w,46605
15
15
  ipyvasp/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- ipyvasp/core/parser.py,sha256=C3CaZsJbPME_ttYlYy4DXeOdL7dnkXs-cHRwFZL6bio,38058
16
+ ipyvasp/core/parser.py,sha256=TmRoIhyIGJ4nr32tb1MAAy5clUZh0CQh-2hP8mnTaVc,38221
17
17
  ipyvasp/core/plot_toolkit.py,sha256=3RoPsND5gPssBSfS5H4TjoZ2Qz7B97vpxeKadc2cRRs,36046
18
- ipyvasp/core/serializer.py,sha256=5QOc2BfGHuwWg3R6xXmdIxc2IwthCUZTEP_3a35GqjM,37623
18
+ ipyvasp/core/serializer.py,sha256=TW14A4rVveTOS0FDmAMjhUVFqraYgXRChnk4ZLVWQKI,38110
19
19
  ipyvasp/core/spatial_toolkit.py,sha256=8DBYTiBFWJ7OBKuvOPw7UoEVCyNjJhSW0OcudjYZvAw,14748
20
- ipyvasp-0.9.6.dist-info/LICENSE,sha256=F3SO5RiAZOMfmMGf1KOuk2g_c4ObvuBJhd9iBLDgXoQ,1263
21
- ipyvasp-0.9.6.dist-info/METADATA,sha256=HEf33s3Gzixg9EH62P9ypR6EunBxw2iws4tcVJGnw3Q,2420
22
- ipyvasp-0.9.6.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
23
- ipyvasp-0.9.6.dist-info/entry_points.txt,sha256=C7m0Sjmr14wFjflCkWXLzr5N6-cQj8uJC9n82mUtzt8,44
24
- ipyvasp-0.9.6.dist-info/top_level.txt,sha256=ftziWlMWu_1VpDP1sRTFrkfBnWxAi393HYDVu4wRhUk,8
25
- ipyvasp-0.9.6.dist-info/RECORD,,
20
+ ipyvasp-0.9.8.dist-info/LICENSE,sha256=F3SO5RiAZOMfmMGf1KOuk2g_c4ObvuBJhd9iBLDgXoQ,1263
21
+ ipyvasp-0.9.8.dist-info/METADATA,sha256=T989kNkzu5aHPsir63uvMsbigxzrcJwpMu76uH3WypM,2420
22
+ ipyvasp-0.9.8.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
23
+ ipyvasp-0.9.8.dist-info/entry_points.txt,sha256=C7m0Sjmr14wFjflCkWXLzr5N6-cQj8uJC9n82mUtzt8,44
24
+ ipyvasp-0.9.8.dist-info/top_level.txt,sha256=ftziWlMWu_1VpDP1sRTFrkfBnWxAi393HYDVu4wRhUk,8
25
+ ipyvasp-0.9.8.dist-info/RECORD,,