-
Notifications
You must be signed in to change notification settings - Fork 874
/
pmg_structure.py
122 lines (100 loc) · 3.59 KB
/
pmg_structure.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/env python
"""
Implementation for `pmg structure` CLI.
"""
from __future__ import annotations
import sys
from tabulate import tabulate
from pymatgen.analysis.structure_matcher import ElementComparator, StructureMatcher
from pymatgen.core.structure import Structure
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
__author__ = "Shyue Ping Ong"
__copyright__ = "Copyright 2012, The Materials Project"
__version__ = "4.0"
__maintainer__ = "Shyue Ping Ong"
__email__ = "[email protected]"
__date__ = "Aug 13 2016"
def convert_fmt(args):
"""
Convert files from one format to another
Args:
args (dict): Args from argparse.
"""
if len(args.filenames) != 2:
print("File format conversion takes in only two filenames.")
struct = Structure.from_file(args.filenames[0], primitive="prim" in args.filenames[1].lower())
struct.to(filename=args.filenames[1])
def analyze_symmetry(args):
"""
Analyze symmetry of structures in files.
Args:
args (dict): Args from argparse.
"""
tolerance = args.symmetry
t = []
for filename in args.filenames:
struct = Structure.from_file(filename, primitive=False)
finder = SpacegroupAnalyzer(struct, tolerance)
dataset = finder.get_symmetry_dataset()
t.append([filename, dataset["international"], dataset["number"], dataset["hall"]])
print(tabulate(t, headers=["Filename", "Int Symbol", "Int number", "Hall"]))
def analyze_localenv(args):
"""
Analyze local env of structures in files.
Args:
args (dict): Args for argparse.
"""
bonds = {}
for bond in args.localenv:
toks = bond.split("=")
species = toks[0].split("-")
bonds[(species[0], species[1])] = float(toks[1])
for filename in args.filenames:
print(f"Analyzing {filename}...")
data = []
s = Structure.from_file(filename)
for i, site in enumerate(s):
for species, dist in bonds.items():
if species[0] in [sp.symbol for sp in site.species]:
dists = [
d for nn, d in s.get_neighbors(site, dist) if species[1] in [sp.symbol for sp in nn.species]
]
dists = ", ".join(f"{d:.3f}" for d in sorted(dists))
data.append([i, species[0], species[1], dists])
print(tabulate(data, headers=["#", "Center", "Ligand", "Dists"]))
def compare_structures(args):
"""
Compare structures in files for similarity using structure matcher.
Args:
args (dict): Args from argparse.
"""
filenames = args.filenames
if len(filenames) < 2:
print("You need more than one structure to compare!")
sys.exit(-1)
try:
structures = [Structure.from_file(fn) for fn in filenames]
except Exception as ex:
print("Error converting file. Are they in the right format?")
print(str(ex))
sys.exit(-1)
m = StructureMatcher() if args.group == "species" else StructureMatcher(comparator=ElementComparator())
for idx, grp in enumerate(m.group_structures(structures)):
print(f"Group {idx}: ")
for s in grp:
print(f"- {filenames[structures.index(s)]} ({s.formula})")
print()
def analyze_structures(args):
"""
Master function to handle which operation to perform.
Args:
args (dict): Args from argparse.
"""
if args.convert:
convert_fmt(args)
elif args.symmetry:
analyze_symmetry(args)
elif args.group:
compare_structures(args)
elif args.localenv:
analyze_localenv(args)