Skip to content

Commit cc1644a

Browse files
committed
Fix motif and composition.
1 parent 6747884 commit cc1644a

File tree

2 files changed

+88
-33
lines changed

2 files changed

+88
-33
lines changed

jarvis/core/atoms.py

Lines changed: 82 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
device = "cpu"
3333
if torch.cuda.is_available():
3434
device = torch.device("cuda")
35+
device = "cpu"
3536
except Exception:
3637
pass
3738
amu_gm = 1.66054e-24
@@ -638,11 +639,14 @@ def from_xyz(self, filename="dsgdb9nsd_057387.xyz", box_size=40):
638639
return atoms
639640

640641
@classmethod
641-
def from_poscar(self, filename="POSCAR"):
642+
def from_poscar(self, filename="POSCAR", string=""):
642643
"""Read POSCAR/CONTCAR file from to make Atoms object."""
643644
from jarvis.io.vasp.inputs import Poscar
644645

645-
return Poscar.from_file(filename).atoms
646+
if string != "":
647+
return Poscar.from_string(string).atoms
648+
else:
649+
return Poscar.from_file(filename).atoms
646650

647651
@property
648652
def check_polar(self):
@@ -1376,7 +1380,7 @@ def get_mineral_prototype_name(
13761380
# name+="_"+str(com_positions)
13771381
return name
13781382

1379-
def get_basic_polyhdra_motif(self, thresh=0.5, cutoff=4):
1383+
def get_basic_polyhdra_motif(self, thresh=0.5, cutoff=4, extra_cutoff=4):
13801384
"""Get chemical environment around atoms."""
13811385

13821386
def classify_coordination_environment(num_neighbors):
@@ -1404,22 +1408,22 @@ def classify_coordination_environment(num_neighbors):
14041408
return "Other"
14051409

14061410
nbr_env = []
1407-
for ii, i in enumerate(self.get_all_neighbors(r=cutoff + 2)):
1408-
counter = Counter([round(j[2], 3) for j in i])
1409-
counter = dict(
1410-
sorted(
1411-
counter.items(), key=lambda item: item[0], reverse=False
1412-
)
1413-
)
1414-
asc_bonds = list(counter.keys())
1415-
# print('asc_bonds',asc_bonds)
1416-
min_bond = asc_bonds[0] # min(list(counter.keys()))
1417-
num_neighbors = counter[min_bond]
1418-
# Add second neighbors if too close
1419-
if min_bond + thresh >= asc_bonds[1]:
1420-
num_neighbors += counter[asc_bonds[1]]
1411+
for ii, i in enumerate(
1412+
self.get_all_neighbors(r=cutoff + extra_cutoff)
1413+
):
1414+
sorted_i = sorted(i, key=lambda x: x[2])
1415+
num_neighbors = 0
1416+
min_bond = sorted_i[0][2]
1417+
info = []
1418+
for j in sorted_i:
1419+
if j[2] <= min_bond + thresh:
1420+
info.append(self.elements[j[1]])
1421+
num_neighbors = len(info)
1422+
info_els = Counter(info)
1423+
tmp = Composition.from_dict(info_els).formula
14211424
env = classify_coordination_environment(num_neighbors)
1422-
rep = self.elements[ii] + "X" + str(num_neighbors)
1425+
rep = self.elements[ii] + tmp
1426+
# rep = self.elements[ii] + "X" + str(num_neighbors)
14231427
info = [self.elements[ii], env, num_neighbors, rep]
14241428
if info not in nbr_env and env != "Other":
14251429
nbr_env.append(info)
@@ -1514,6 +1518,8 @@ def describe(
15141518
model="",
15151519
polyhedra_thresh=0.5,
15161520
add_crystal_info=False,
1521+
add_wyck_descs=False,
1522+
add_same_el_bonds=False,
15171523
):
15181524
"""Describe for NLP applications."""
15191525
from jarvis.analysis.diffraction.xrd import XRD
@@ -1583,6 +1589,18 @@ def describe(
15831589
}
15841590
wyck_descs = ""
15851591
if include_spg:
1592+
polar_point_groups = [
1593+
"1",
1594+
"2",
1595+
"3",
1596+
"4",
1597+
"6",
1598+
"m",
1599+
"mm2",
1600+
"3m",
1601+
"4mm",
1602+
"6mm",
1603+
]
15861604
from jarvis.analysis.structure.spacegroup import (
15871605
get_wyckoff_position_operators,
15881606
)
@@ -1593,13 +1611,17 @@ def describe(
15931611
struct_info["spg_symbol"] = spg.space_group_symbol
15941612
struct_info["crystal_system"] = spg.crystal_system
15951613
struct_info["point_group"] = spg.point_group_symbol
1614+
if spg.point_group_symbol in polar_point_groups:
1615+
struct_info["polar"] = True
1616+
else:
1617+
struct_info["polar"] = False
15961618
struct_info["wyckoff"] = ", ".join(
15971619
list(set(spg._dataset["wyckoffs"]))
15981620
)
15991621
struct_info["natoms_primitive"] = spg.primitive_atoms.num_atoms
1600-
struct_info[
1601-
"natoms_conventional"
1602-
] = spg.conventional_standard_structure.num_atoms
1622+
struct_info["natoms_conventional"] = (
1623+
spg.conventional_standard_structure.num_atoms
1624+
)
16031625
p = inflect.engine()
16041626
# Multiplicity
16051627
wyck_mult = get_wyckoff_position_operators(
@@ -1670,6 +1692,9 @@ def describe(
16701692

16711693
p = struct_info["bond_distances"]
16721694
for ii, (kk, vv) in enumerate(p.items()):
1695+
elements_in_bond = kk.split("-")
1696+
# if add_same_el_bonds and elements_in_bond[0]!=elements_in_bond[1]:
1697+
# print('kk,vv',kk,vv)
16731698
if ii == len(p) - 1:
16741699
punc = " Å."
16751700
else:
@@ -1701,7 +1726,14 @@ def describe(
17011726
+ str(max(bnd))
17021727
+ " Å."
17031728
)
1704-
bond_desc += txt
1729+
if elements_in_bond[0] != elements_in_bond[1]:
1730+
bond_desc += txt
1731+
if (
1732+
add_same_el_bonds
1733+
and elements_in_bond[0] == elements_in_bond[1]
1734+
):
1735+
1736+
bond_desc += txt
17051737
line2 = (
17061738
chem_info["atomic_formula"]
17071739
+ " crystallizes in the "
@@ -1739,7 +1771,7 @@ def describe(
17391771
cutoff=cutoff, thresh=polyhedra_thresh
17401772
)
17411773
info["motifs"] = motifs
1742-
motif_desc = ""
1774+
motif_desc = " "
17431775
for ii, i in enumerate(motifs):
17441776
if ii != len(motifs) - 1:
17451777
motif_desc += (
@@ -1770,7 +1802,7 @@ def describe(
17701802
+ " "
17711803
+ str(struct_info["spg_symbol"])
17721804
+ " spacegroup."
1773-
+ wyck_descs
1805+
# + wyck_descs
17741806
+ bond_desc
17751807
+ motif_desc
17761808
)
@@ -1782,7 +1814,7 @@ def describe(
17821814
+ " "
17831815
+ str(struct_info["spg_symbol"])
17841816
+ " spacegroup."
1785-
+ wyck_descs
1817+
# + wyck_descs
17861818
+ bond_desc
17871819
+ motif_desc
17881820
)
@@ -1810,6 +1842,8 @@ def describe(
18101842
line3 = line3.replace(" ", " ")
18111843
if add_crystal_info:
18121844
line3 += crystal_str
1845+
if add_wyck_descs:
1846+
line3 += wyck_descs
18131847
info["crystal_str"] = crystal_str
18141848
info["desc_1"] = line1
18151849
info["desc_2"] = line2
@@ -2477,18 +2511,18 @@ def to_optimade(
24772511
info_at["cartesian_site_positions"] = atoms.cart_coords[order].tolist()
24782512
info_at["nperiodic_dimensions"] = 3
24792513
# info_at["species"] = atoms.elements
2480-
info_at[
2481-
"species"
2482-
] = self.get_optimade_species() # dict(atoms.composition.to_dict())
2514+
info_at["species"] = (
2515+
self.get_optimade_species()
2516+
) # dict(atoms.composition.to_dict())
24832517
info_at["elements_ratios"] = list(
24842518
atoms.composition.atomic_fraction.values()
24852519
)
24862520
info_at["structure_features"] = []
24872521
info_at["last_modified"] = str(now)
24882522
# info_at["more_data_available"] = True
2489-
info_at[
2490-
"chemical_formula_descriptive"
2491-
] = atoms.composition.reduced_formula
2523+
info_at["chemical_formula_descriptive"] = (
2524+
atoms.composition.reduced_formula
2525+
)
24922526
info_at["dimension_types"] = [1, 1, 1]
24932527
info["attributes"] = info_at
24942528
return info
@@ -2586,6 +2620,23 @@ def build_xanes_poscar(
25862620
return atoms
25872621

25882622

2623+
if __name__ == "__main__":
2624+
pos = """MgB2
2625+
1.0
2626+
1.5367454354207384 -2.661721209337192 0.0
2627+
1.5367454354207384 2.661721209337192 0.0
2628+
0.0 0.0 3.5146401326518166
2629+
Mg B
2630+
1 2
2631+
Cartesian
2632+
0.0 0.0 0.0
2633+
1.53675 -0.8872417744799828 1.75732
2634+
1.53675 0.8872417744799828 1.75732
2635+
"""
2636+
atoms = Atoms.from_poscar(string=pos)
2637+
import pprint
2638+
2639+
pprint.pprint(atoms.describe())
25892640
# ['Mn ', 'Mn ', 'Ru ', 'U ']
25902641
#
25912642
# def clear_elements(atoms=None):

jarvis/core/composition.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,14 @@ def formula(self):
156156
form = ""
157157
for specie, count in self._content.items():
158158
if float(count).is_integer():
159-
form = form + str(specie) + str(int(count))
159+
# form = form + str(specie) + str(int(count))
160+
if count == 1:
161+
form = form + specie
162+
else:
163+
form = form + specie + str(int(count))
160164
else:
161165
form = form + str(specie) + str(count)
162-
return form.replace("1", "")
166+
return form # .replace("1", "")
163167

164168
@property
165169
def atomic_fraction(self):

0 commit comments

Comments
 (0)