ipyvasp 0.8.9__py2.py3-none-any.whl → 0.9.0__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
@@ -1447,9 +1447,9 @@ def _fix_sites(
1447
1447
  pos = pos + (txyz - txyz.astype(int))
1448
1448
 
1449
1449
  # Fix coordinates of sites distributed on edges and faces
1450
- pos -= (pos > (1 - tol)).astype(
1451
- int
1452
- ) # Move towards orign for common fixing like in joining POSCARs
1450
+ if not hasattr(poscar_data.metadata, 'source_indices'): # no more fixing over there
1451
+ pos -= (pos > (1 - tol)).astype(int) # Move towards orign for common fixing like in joining POSCARs
1452
+
1453
1453
  out_dict["positions"] = pos
1454
1454
  out_dict["metadata"]["comment"] = "Modified by ipyvasp"
1455
1455
 
@@ -1460,45 +1460,14 @@ def _fix_sites(
1460
1460
  vpos = pos[v]
1461
1461
  vlabs = labels[v]
1462
1462
  inds = np.array(v)
1463
- cond_ops = [
1464
- (
1465
- ((vpos[:, 0] + 1) < (tol + 1)),
1466
- [[1, 0, 0]],
1467
- ), # Add 1 to x if within tol
1468
- (
1469
- ((vpos[:, 1] + 1) < (tol + 1)),
1470
- [[0, 1, 0]],
1471
- ), # Add 1 to y on modified and if within tol
1472
- (
1473
- ((vpos[:, 2] + 1) < (tol + 1)),
1474
- [[0, 0, 1]],
1475
- ), # Add 1 to z and if within tol
1476
- (
1477
- ((vpos[:, 0:2] + 1) < (tol + 1)).all(axis=1),
1478
- [[1, 1, 0]],
1479
- ), # Add 1 to x and y if within tol
1480
- (
1481
- ((vpos[:, 1:3] + 1) < (tol + 1)).all(axis=1),
1482
- [[0, 1, 1]],
1483
- ), # Add 1 to y and z if within tol
1484
- (
1485
- ((vpos[:, [0, 2]] + 1) < (tol + 1)).all(axis=1),
1486
- [[1, 0, 1]],
1487
- ), # Add 1 to x and z if within tol
1488
- (
1489
- ((vpos + 1) < (tol + 1)).all(axis=1),
1490
- [[1, 1, 1]],
1491
- ), # Add 1 to all if within tol
1492
- ]
1493
- spos = [vpos[c] + op for c, op in cond_ops]
1494
- slab = [vlabs[c] for c, op in cond_ops]
1495
- sinds = [inds[c] for c, op in cond_ops]
1496
-
1497
- new_dict[k] = {
1498
- "pos": np.vstack([vpos, *spos]),
1499
- "lab": np.hstack([vlabs, *slab]),
1500
- "inds": np.hstack([inds, *sinds]),
1501
- }
1463
+
1464
+ ivpos = np.concatenate([np.indices((len(vpos),)).reshape((-1,1)),vpos],axis=1) # track of indices
1465
+ ivpos = np.array([ivpos + [0, *p] for p in set(product([-1,0,1],[-1,0,1],[-1,0,1]))]).reshape((-1,4))
1466
+ ivpos = ivpos[(ivpos[:,1:] > -tol).all(axis=1) & (ivpos[:,1:] < 1 + tol).all(axis=1)]
1467
+ ivpos = ivpos[ivpos[:,0].argsort()]
1468
+ idxs = ivpos[:,0].ravel().astype(int).tolist()
1469
+
1470
+ new_dict[k] = {"pos": ivpos[:,1:], "lab": vlabs[idxs], "inds": inds[idxs]}
1502
1471
  new_dict[k]["range"] = range(start, start + len(new_dict[k]["pos"]))
1503
1472
  start += len(new_dict[k]["pos"])
1504
1473
 
@@ -1622,41 +1591,35 @@ def _filter_pairs(labels, pairs, dist, bond_length):
1622
1591
  # Return all pairs otherwise
1623
1592
  return pairs # None -> auto calculate bond_length, number -> use that number
1624
1593
 
1625
-
1626
1594
  def filter_sites(poscar_data, func, tol = 0.01):
1627
1595
  """Filter sites based on a function that acts on index and fractional positions such as `lambda i,x,y,z: condition`.
1628
- This may include equivalent sites, so it should be used for plotting purpose only, e.g. showing atoms on a plane."""
1596
+ This may include equivalent sites, so it should be used for plotting purpose only, e.g. showing atoms on a plane.
1597
+ 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]`.
1598
+ """
1599
+ if hasattr(poscar_data.metadata, 'source_indices'):
1600
+ raise ValueError("Cannot filter an already filtered POSCAR data.")
1601
+
1602
+ poscar_data = _fix_sites(poscar_data, tol = tol, eqv_sites=True)
1629
1603
  idxs = _masked_data(poscar_data, func)
1630
1604
  data = poscar_data.to_dict()
1631
- all_pos, npos = [], []
1605
+ all_pos, npos, eqv_labs, finds = [], [0,],[],[]
1632
1606
  for value in poscar_data.types.values():
1633
- indices = [i for i in value if i in idxs]
1634
- others = [j for j in value if not (j in indices)]
1607
+ indices = [i for i in value if i in idxs] # search from value make sure only non-equivalent sites added
1608
+ finds.extend(poscar_data.metadata.eqv_indices[indices])
1609
+ eqv_labs.extend(poscar_data.labels[indices])
1635
1610
  pos = data['positions'][indices]
1636
- qos = data['positions'][others] # need edge items to include
1637
-
1638
- if qos.size:
1639
- qos = np.concatenate([[[i] for i in others], qos], axis=1) # need to keep index
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
- qos = qos[(qos[:,1:] < 1 + tol).all(axis=1) & (qos[:,1:] > -tol).all(axis=1)]# only in cell range
1642
- qos = qos[[func(*q) for q in qos]] # masked only those are true
1643
-
1644
- if qos.size:
1645
- pos = np.concatenate([pos, qos[:,1:]],axis=0)
1646
-
1647
1611
  all_pos.append(pos)
1648
1612
  npos.append(len(pos))
1649
1613
 
1650
1614
  if not np.sum(npos):
1651
1615
  raise ValueError("No sites found with given filter func!")
1652
1616
 
1653
- if not 'prev_positions' in data['metadata']: # keep always the starting one
1654
- data['metadata']['prev_positions'] = poscar_data.positions
1655
- data['metadata']['prev_types'] = poscar_data.types
1656
-
1657
1617
  data['positions'] = np.concatenate(all_pos, axis = 0)
1618
+ data['metadata']['source_indices'] = np.array(finds)
1619
+ data['metadata']['eqv_labels'] = np.array(eqv_labs) # need these for compare to previous
1620
+ data['metadata'].pop('eqv_indices', None) # no need of this
1658
1621
 
1659
- ranges = np.cumsum([0, *npos])
1622
+ ranges = np.cumsum(npos)
1660
1623
  data['types'] = {key: range(i,j) for key, i,j in zip(data['types'],ranges[:-1],ranges[1:]) if range(i,j)} # avoid empty
1661
1624
  return serializer.PoscarData(data)
1662
1625
 
ipyvasp/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.8.9"
1
+ __version__ = "0.9.0"
ipyvasp/lattice.py CHANGED
@@ -85,6 +85,7 @@ def ngl_viewer(
85
85
  plot_vectors=True,
86
86
  dashboard=False,
87
87
  origin=(0, 0, 0),
88
+ eqv_sites = True,
88
89
  ):
89
90
  """Display structure in Jupyter notebook using nglview.
90
91
 
@@ -135,7 +136,7 @@ def ngl_viewer(
135
136
 
136
137
  # Only show equivalent sites if plotting cell, only shift origin otherwise
137
138
  poscar = POSCAR( # don't change instance itself, make new one
138
- data=plat._fix_sites(poscar.data, eqv_sites=True if plot_cell else False, origin=origin)
139
+ data=plat._fix_sites(poscar.data, eqv_sites=eqv_sites, origin=origin)
139
140
  )
140
141
 
141
142
  _types = poscar.data.types.to_dict()
@@ -187,7 +188,8 @@ def weas_viewer(poscar,
187
188
  bond_length=None,
188
189
  model_style = 1,
189
190
  plot_cell=True,
190
- origin = (0,0,0)
191
+ origin = (0,0,0),
192
+ eqv_sites = True,
191
193
  ):
192
194
  """
193
195
  sizes : float or dict of type -> float
@@ -215,7 +217,7 @@ def weas_viewer(poscar,
215
217
 
216
218
  # Only show equivalent sites if plotting cell, only shift origin otherwise
217
219
  poscar = POSCAR( # don't change instance itself, make new one
218
- data=plat._fix_sites(poscar.data, eqv_sites=True if plot_cell else False, origin=origin)
220
+ data=plat._fix_sites(poscar.data, eqv_sites=eqv_sites, origin=origin)
219
221
  )
220
222
 
221
223
  w = WeasWidget(from_ase=poscar.to_ase())
@@ -565,6 +567,11 @@ class POSCAR:
565
567
  def data(self):
566
568
  "Data object in POSCAR."
567
569
  return self._data
570
+
571
+ @property
572
+ def metadata(self):
573
+ "Metadata associated with this POSCAR."
574
+ return self._data.metadata
568
575
 
569
576
  def copy(self):
570
577
  "Copy POSCAR object. It avoids accidental changes to numpy arrays in original object."
@@ -674,8 +681,8 @@ class POSCAR:
674
681
 
675
682
  @_sub_doc(plat.filter_sites)
676
683
  @_sig_kwargs(plat.filter_sites,("poscar_data",))
677
- def filter_sites(self, func):
678
- return self.__class__(data = plat.filter_sites(self.data, func))
684
+ def filter_sites(self, func, tol=0.01):
685
+ return self.__class__(data = plat.filter_sites(self.data, func,tol=tol))
679
686
 
680
687
  @_sub_doc(plat.set_origin)
681
688
  def set_origin(self, origin):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ipyvasp
3
- Version: 0.8.9
3
+ Version: 0.9.0
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,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=TaiPj_cbBkmuCd40hM01_grNVLcn2hK70fTCN98GNgU,104018
5
- ipyvasp/_version.py,sha256=Fj0n620aEHCHlsmEXmEGKx9B0YdzMeN3Yc9ZouxRIBU,23
4
+ ipyvasp/_lattice.py,sha256=ASHTQV3QK4mhx7eO3ISLvzm4fTg5KGiQ3iI0BqfmEac,102978
5
+ ipyvasp/_version.py,sha256=Rqk_eJf2ntSg0XlEKqShPvNr_E2rQ3wfdU2Xyp-R4ls,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=Ow9BJa8ceasquLPOqsnpj2ysf45IHta1wLtEXoDHtTw,29642
9
+ ipyvasp/lattice.py,sha256=t7lkewCbN8IFUIKia9Xkc8p0pTDBc_34NIrlWsXENGA,29800
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
@@ -17,9 +17,9 @@ ipyvasp/core/parser.py,sha256=C3CaZsJbPME_ttYlYy4DXeOdL7dnkXs-cHRwFZL6bio,38058
17
17
  ipyvasp/core/plot_toolkit.py,sha256=8t5svyWbOm-PS7ZvIptnK6F46kp6uwoGNdohPv5dQKA,35962
18
18
  ipyvasp/core/serializer.py,sha256=57e2ypF18tJI1zZi9kJiHGMBYgXvYEZpLmgnaaDdSk0,36067
19
19
  ipyvasp/core/spatial_toolkit.py,sha256=8DBYTiBFWJ7OBKuvOPw7UoEVCyNjJhSW0OcudjYZvAw,14748
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,,
20
+ ipyvasp-0.9.0.dist-info/LICENSE,sha256=F3SO5RiAZOMfmMGf1KOuk2g_c4ObvuBJhd9iBLDgXoQ,1263
21
+ ipyvasp-0.9.0.dist-info/METADATA,sha256=q73Rkc1Kx_HfNBgB0LT-4Ca8EFz7wXr_9mgquNeGC9I,2420
22
+ ipyvasp-0.9.0.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
23
+ ipyvasp-0.9.0.dist-info/entry_points.txt,sha256=C7m0Sjmr14wFjflCkWXLzr5N6-cQj8uJC9n82mUtzt8,44
24
+ ipyvasp-0.9.0.dist-info/top_level.txt,sha256=ftziWlMWu_1VpDP1sRTFrkfBnWxAi393HYDVu4wRhUk,8
25
+ ipyvasp-0.9.0.dist-info/RECORD,,