• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

materialsproject / pymatgen / 3968792566

pending completion
3968792566

push

github

Shyue Ping Ong
Merge branch 'master' of github.com:materialsproject/pymatgen

600 of 600 new or added lines in 370 files covered. (100.0%)

80392 of 102009 relevant lines covered (78.81%)

0.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.33
/pymatgen/io/feff/tests/test_inputs.py
1
# Copyright (c) Pymatgen Development Team.
2
# Distributed under the terms of the MIT License.
3

4

5
from __future__ import annotations
1✔
6

7
import os
1✔
8
import unittest
1✔
9

10
import numpy as np
1✔
11

12
from pymatgen.core import Molecule, Structure
1✔
13
from pymatgen.io.cif import CifParser
1✔
14
from pymatgen.io.feff.inputs import Atoms, Header, Paths, Potential, Tags
1✔
15
from pymatgen.util.testing import PymatgenTest
1✔
16

17
header_string = """* This FEFF.inp file generated by pymatgen
1✔
18
TITLE comment: From cif file
19
TITLE Source:  CoO19128.cif
20
TITLE Structure Summary:  Co2 O2
21
TITLE Reduced formula:  CoO
22
TITLE space group: (Cmc2_1), space number:  (36)
23
TITLE abc:  3.297078   3.297078   5.254213
24
TITLE angles: 90.000000  90.000000 120.000000
25
TITLE sites: 4
26
* 1 Co     0.666666     0.333332     0.496324
27
* 2 Co     0.333333     0.666667     0.996324
28
* 3 O     0.666666     0.333332     0.878676
29
* 4 O     0.333333     0.666667     0.378675"""
30

31

32
class HeaderTest(unittest.TestCase):
1✔
33
    def test_init(self):
1✔
34
        filepath = os.path.join(PymatgenTest.TEST_FILES_DIR, "HEADER")
1✔
35
        header = Header.header_string_from_file(filepath)
1✔
36
        h = header.splitlines()
1✔
37
        hs = header_string.splitlines()
1✔
38
        for i, line in enumerate(h):
1✔
39
            self.assertEqual(line, hs[i])
1✔
40
        self.assertEqual(
1✔
41
            header_string.splitlines(),
42
            header.splitlines(),
43
            "Failed to read HEADER file",
44
        )
45

46
    def test_from_string(self):
1✔
47
        header = Header.from_string(header_string)
1✔
48
        self.assertEqual(
1✔
49
            header.struct.composition.reduced_formula,
50
            "CoO",
51
            "Failed to generate structure from HEADER string",
52
        )
53

54
    def test_get_string(self):
1✔
55
        cif_file = os.path.join(PymatgenTest.TEST_FILES_DIR, "CoO19128.cif")
1✔
56
        h = Header.from_cif_file(cif_file)
1✔
57
        head = str(h)
1✔
58
        self.assertEqual(
1✔
59
            head.splitlines()[3].split()[-1],
60
            header_string.splitlines()[3].split()[-1],
61
            "Failed to generate HEADER from structure",
62
        )
63

64
    def test_as_dict_and_from_dict(self):
1✔
65
        file_name = os.path.join(PymatgenTest.TEST_FILES_DIR, "HEADER")
1✔
66
        header = Header.from_file(file_name)
1✔
67
        d = header.as_dict()
1✔
68
        header2 = Header.from_dict(d)
1✔
69
        self.assertEqual(str(header), str(header2), "Header failed to and from dict test")
1✔
70

71

72
class FeffAtomsTest(unittest.TestCase):
1✔
73
    @classmethod
1✔
74
    def setUpClass(cls):
1✔
75
        r = CifParser(os.path.join(PymatgenTest.TEST_FILES_DIR, "CoO19128.cif"))
1✔
76
        cls.structure = r.get_structures()[0]
1✔
77
        cls.atoms = Atoms(cls.structure, "O", 12.0)
1✔
78

79
    def test_absorbing_atom(self):
1✔
80
        atoms_1 = Atoms(self.structure, 0, 10.0)
1✔
81
        atoms_2 = Atoms(self.structure, 2, 10.0)
1✔
82
        self.assertEqual(atoms_1.absorbing_atom, "Co")
1✔
83
        self.assertEqual(atoms_2.absorbing_atom, "O")
1✔
84

85
    def test_single_absorbing_atom(self):
1✔
86
        """
87
        When there is only one absorbing atom in the structure, it should not appear
88
        in the pot_dict to avoid an error
89
        """
90
        # one Zn+2, 9 triflate, plus water
91
        xyz = os.path.join(PymatgenTest.TEST_FILES_DIR, "feff_radial_shell.xyz")
1✔
92
        m = Molecule.from_file(xyz)
1✔
93
        m.set_charge_and_spin(-7)
1✔
94
        atoms = Atoms(m, "Zn", 9)
1✔
95
        # Zn should not appear in the pot_dict
96
        assert not atoms.pot_dict.get("Zn", False)
1✔
97

98
    def test_absorber_line(self):
1✔
99
        atoms_lines = self.atoms.get_lines()
1✔
100
        # x
101
        self.assertAlmostEqual(float(atoms_lines[0][0]), 0.0)
1✔
102
        # y
103
        self.assertAlmostEqual(float(atoms_lines[0][1]), 0.0)
1✔
104
        # z
105
        self.assertAlmostEqual(float(atoms_lines[0][2]), 0.0)
1✔
106
        # ipot
107
        self.assertEqual(int(atoms_lines[0][3]), 0)
1✔
108
        # atom symbol
109
        self.assertEqual(atoms_lines[0][4], "O")
1✔
110
        # distance
111
        self.assertAlmostEqual(float(atoms_lines[0][5]), 0.0)
1✔
112
        # id
113
        self.assertEqual(int(atoms_lines[0][6]), 0)
1✔
114

115
    def test_distances(self):
1✔
116
        atoms_1 = self.atoms.get_lines()
1✔
117
        distances_1 = [float(a[5]) for a in atoms_1]
1✔
118
        atoms_2 = Atoms.atoms_string_from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "ATOMS"))
1✔
119
        atoms_2 = atoms_2.splitlines()[3:]
1✔
120
        distances_2 = [float(a.split()[5]) for a in atoms_2]
1✔
121
        np.testing.assert_allclose(distances_1, distances_2, rtol=1e-5)
1✔
122

123
    def test_atoms_from_file(self):
1✔
124
        filepath = os.path.join(PymatgenTest.TEST_FILES_DIR, "ATOMS")
1✔
125
        atoms = Atoms.atoms_string_from_file(filepath)
1✔
126
        self.assertEqual(atoms.splitlines()[3].split()[4], "O", "failed to read ATOMS file")
1✔
127

128
    def test_get_string(self):
1✔
129
        header = Header.from_string(header_string)
1✔
130
        struct = header.struct
1✔
131
        central_atom = "O"
1✔
132
        a = Atoms(struct, central_atom, radius=10.0)
1✔
133
        atoms = str(a)
1✔
134
        self.assertEqual(
1✔
135
            atoms.splitlines()[3].split()[4],
136
            central_atom,
137
            "failed to create ATOMS string",
138
        )
139

140
    def test_as_dict_and_from_dict(self):
1✔
141
        file_name = os.path.join(PymatgenTest.TEST_FILES_DIR, "HEADER")
1✔
142
        header = Header.from_file(file_name)
1✔
143
        struct = header.struct
1✔
144
        atoms = Atoms(struct, "O", radius=10.0)
1✔
145
        d = atoms.as_dict()
1✔
146
        atoms2 = Atoms.from_dict(d)
1✔
147
        self.assertEqual(str(atoms), str(atoms2), "Atoms failed to and from dict test")
1✔
148

149
    def test_cluster_from_file(self):
1✔
150
        self.atoms.write_file("ATOMS_test")
1✔
151
        mol_1 = Atoms.cluster_from_file("ATOMS_test")
1✔
152
        mol_2 = Atoms.cluster_from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "ATOMS"))
1✔
153
        self.assertEqual(mol_1.formula, mol_2.formula)
1✔
154
        self.assertEqual(len(mol_1), len(mol_2))
1✔
155
        os.remove("ATOMS_test")
1✔
156

157

158
class FeffTagsTest(unittest.TestCase):
1✔
159
    def test_init(self):
1✔
160
        filepath = os.path.join(PymatgenTest.TEST_FILES_DIR, "PARAMETERS")
1✔
161
        parameters = Tags.from_file(filepath)
1✔
162
        parameters["RPATH"] = 10
1✔
163
        self.assertEqual(parameters["COREHOLE"], "Fsr", "Failed to read PARAMETERS file")
1✔
164
        self.assertEqual(parameters["LDOS"], [-30.0, 15.0, 0.1], "Failed to read PARAMETERS file")
1✔
165

166
    def test_diff(self):
1✔
167
        filepath1 = os.path.join(PymatgenTest.TEST_FILES_DIR, "PARAMETERS")
1✔
168
        parameters1 = Tags.from_file(filepath1)
1✔
169
        filepath2 = os.path.join(PymatgenTest.TEST_FILES_DIR, "PARAMETERS.2")
1✔
170
        parameters2 = Tags.from_file(filepath2)
1✔
171
        self.assertEqual(
1✔
172
            Tags(parameters1).diff(parameters2),
173
            {
174
                "Different": {},
175
                "Same": {
176
                    "CONTROL": [1, 1, 1, 1, 1, 1],
177
                    "MPSE": [2],
178
                    "OPCONS": "",
179
                    "SCF": [6.0, 0, 30, 0.2, 1],
180
                    "EXCHANGE": [0, 0.0, 0.0, 2],
181
                    "S02": [0.0],
182
                    "COREHOLE": "Fsr",
183
                    "FMS": [8.5, 0],
184
                    "XANES": [3.7, 0.04, 0.1],
185
                    "EDGE": "K",
186
                    "PRINT": [1, 0, 0, 0, 0, 0],
187
                    "LDOS": [-30.0, 15.0, 0.1],
188
                },
189
            },
190
        )
191

192
    def test_as_dict_and_from_dict(self):
1✔
193
        file_name = os.path.join(PymatgenTest.TEST_FILES_DIR, "PARAMETERS")
1✔
194
        tags = Tags.from_file(file_name)
1✔
195
        d = tags.as_dict()
1✔
196
        tags2 = Tags.from_dict(d)
1✔
197
        self.assertEqual(tags, tags2, "Parameters do not match to and from dict")
1✔
198

199
    def test_eels_tags(self):
1✔
200
        ans_1 = {
1✔
201
            "CONTROL": [1, 1, 1, 1, 1, 1],
202
            "COREHOLE": "Fsr",
203
            "EDGE": "K",
204
            "ELNES": {
205
                "ANGLES": "7.6 6.4",
206
                "BEAM_ENERGY": "200 1 0 1",
207
                "ENERGY": "4.0 .04 0.1",
208
                "MESH": "50 1",
209
                "POSITION": "0 0",
210
            },
211
            "EXCHANGE": [0, 0.0, 0.0, 2],
212
            "FMS": [7.5],
213
            "PRINT": [1, 0, 0, 0, 0, 0],
214
            "RPATH": [-1],
215
            "S02": [0.0],
216
            "SCF": [6, 0, 30, 0.2, 5],
217
        }
218
        tags_1 = Tags.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "feff_eels_powder.inp"))
1✔
219
        self.assertEqual(dict(tags_1), ans_1)
1✔
220
        ans_1["ELNES"]["BEAM_ENERGY"] = "200 0 1 1"
1✔
221
        ans_1["ELNES"]["BEAM_DIRECTION"] = "1 0 0"
1✔
222
        tags_2 = Tags.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "feff_eels_x.inp"))
1✔
223
        self.assertEqual(dict(tags_2), ans_1)
1✔
224

225

226
class FeffPotTest(unittest.TestCase):
1✔
227
    def test_init(self):
1✔
228
        filepath = os.path.join(PymatgenTest.TEST_FILES_DIR, "POTENTIALS")
1✔
229
        feffpot = Potential.pot_string_from_file(filepath)
1✔
230
        d, dr = Potential.pot_dict_from_string(feffpot)
1✔
231
        self.assertEqual(d["Co"], 1, "Wrong symbols read in for Potential")
1✔
232

233
    def test_single_absorbing_atom(self):
1✔
234
        """
235
        When there is only one absorbing atom in the structure, it should not appear
236
        in the pot_dict to avoid an error
237
        """
238
        # one Zn+2, 9 triflate, plus water
239
        xyz = os.path.join(PymatgenTest.TEST_FILES_DIR, "feff_radial_shell.xyz")
1✔
240
        m = Molecule.from_file(xyz)
1✔
241
        m.set_charge_and_spin(-7)
1✔
242
        pot = Potential(m, "Zn")
1✔
243
        # Zn should not appear in the pot_dict
244
        assert not pot.pot_dict.get("Zn", False)
1✔
245
        # Zn should only appear in the first row of the string representation
246
        assert str(pot).count("Zn") == 1
1✔
247

248
    def test_as_dict_and_from_dict(self):
1✔
249
        file_name = os.path.join(PymatgenTest.TEST_FILES_DIR, "HEADER")
1✔
250
        header = Header.from_file(file_name)
1✔
251
        struct = header.struct
1✔
252
        pot = Potential(struct, "O")
1✔
253
        d = pot.as_dict()
1✔
254
        pot2 = Potential.from_dict(d)
1✔
255
        self.assertEqual(str(pot), str(pot2), "Potential to and from dict does not match")
1✔
256

257

258
class PathsTest(unittest.TestCase):
1✔
259
    def setUp(self):
1✔
260
        feo = Structure.from_dict(
1✔
261
            {
262
                "lattice": {
263
                    "a": 3.3960486211791285,
264
                    "alpha": 91.45136142952781,
265
                    "b": 3.410591877060444,
266
                    "beta": 89.27127081348024,
267
                    "c": 10.71766796897646,
268
                    "gamma": 120.14175587658389,
269
                    "matrix": [
270
                        [3.39597035, -0.00828486, 0.02151698],
271
                        [-1.70515997, 2.9534242, -0.04303398],
272
                        [0.06812465, -0.11799566, 10.71680189],
273
                    ],
274
                    "volume": 107.31813123502585,
275
                },
276
                "sites": [
277
                    {
278
                        "abc": [0.33497754, 0.66579918, 0.97174225],
279
                        "label": "Fe",
280
                        "properties": {
281
                            "coordination_no": 4,
282
                            "forces": [-0.01537896, -0.08731049, 0.04884326],
283
                        },
284
                        "species": [{"element": "Fe", "occu": 1}],
285
                        "xyz": [
286
                            0.06847928463257683,
287
                            1.8489508003914767,
288
                            10.392524897825345,
289
                        ],
290
                    },
291
                    {
292
                        "abc": [0.99661905, 0.00734083, 0.22366433],
293
                        "label": "Fe",
294
                        "properties": {
295
                            "coordination_no": 4,
296
                            "forces": [-0.01685376, -0.01008504, 0.05451912],
297
                        },
298
                        "species": [{"element": "Fe", "occu": 1}],
299
                        "xyz": [
300
                            3.387208508781326,
301
                            -0.0129676845693048,
302
                            2.4180946415046494,
303
                        ],
304
                    },
305
                    {
306
                        "abc": [0.00338095, 0.01072178, 0.72366433],
307
                        "label": "Fe",
308
                        "properties": {
309
                            "coordination_no": 4,
310
                            "forces": [0.01716078, 0.00955327, 0.05451912],
311
                        },
312
                        "species": [{"element": "Fe", "occu": 1}],
313
                        "xyz": [
314
                            0.04249863509042039,
315
                            -0.053751296415148794,
316
                            7.754978606437029,
317
                        ],
318
                    },
319
                    {
320
                        "abc": [0.66502246, 0.33082164, 0.47174225],
321
                        "label": "Fe",
322
                        "properties": {
323
                            "coordination_no": 4,
324
                            "forces": [0.08330257, -0.03033668, 0.04884326],
325
                        },
326
                        "species": [{"element": "Fe", "occu": 1}],
327
                        "xyz": [
328
                            1.7264300141777726,
329
                            0.9158834813430974,
330
                            5.055640939524896,
331
                        ],
332
                    },
333
                    {
334
                        "abc": [0.33062914, 0.66733572, 0.77744897],
335
                        "label": "O",
336
                        "properties": {
337
                            "coordination_no": 4,
338
                            "forces": [-0.07726687, -0.00523346, -0.05206924],
339
                        },
340
                        "species": [{"element": "O", "occu": 1}],
341
                        "xyz": [
342
                            0.03785603896498114,
343
                            1.8764506445041333,
344
                            8.310162619639584,
345
                        ],
346
                    },
347
                    {
348
                        "abc": [0.00312189, 0.99229908, 0.52714445],
349
                        "label": "O",
350
                        "properties": {
351
                            "coordination_no": 4,
352
                            "forces": [-0.06744419, 0.00047044, -0.05129314],
353
                        },
354
                        "species": [{"element": "O", "occu": 1}],
355
                        "xyz": [
356
                            -1.6455152924521734,
357
                            2.8684534947950637,
358
                            5.606667232944964,
359
                        ],
360
                    },
361
                    {
362
                        "abc": [0.99687811, 0.98917618, 0.02714445],
363
                        "label": "O",
364
                        "properties": {
365
                            "coordination_no": 4,
366
                            "forces": [0.03331469, 0.05864361, -0.05129314],
367
                        },
368
                        "species": [{"element": "O", "occu": 1}],
369
                        "xyz": [
370
                            1.7005140848662161,
371
                            2.9099949452040543,
372
                            0.2697833114717219,
373
                        ],
374
                    },
375
                    {
376
                        "abc": [0.66937086, 0.33670658, 0.27744897],
377
                        "label": "O",
378
                        "properties": {
379
                            "coordination_no": 4,
380
                            "forces": [0.04316575, 0.06429835, -0.05206924],
381
                        },
382
                        "species": [{"element": "O", "occu": 1}],
383
                        "xyz": [
384
                            1.7179261258365088,
385
                            0.9561539434765862,
386
                            2.9732786612521678,
387
                        ],
388
                    },
389
                ],
390
            }
391
        )
392
        atoms = Atoms(feo, 0, 10.0)
1✔
393
        self.paths = Paths(atoms, [[22, 16, 0], [250, 282, 250, 0]])
1✔
394

395
    def test_paths_string(self):
1✔
396
        lines = [
1✔
397
            "PATH",
398
            "---------------",
399
            "9999 3 1",
400
            "x y z ipot label",
401
            "-3.428830 -3.869922 -5.336884 1 Fe",
402
            "-5.133990 -0.916498 -5.379918 1 Fe",
403
            "0.000000 0.000000 0.000000 0 Fe",
404
            "9998 4 1",
405
            "x y z ipot label",
406
            "5.056157 2.964354 -2.082362 2 O",
407
            "8.473635 0.956940 2.742372 1 Fe",
408
            "5.056157 2.964354 -2.082362 2 O",
409
            "0.000000 0.000000 0.000000 0 Fe",
410
        ]
411
        answer = "\n".join(lines)
1✔
412
        self.assertEqual(answer, str(self.paths))
1✔
413

414

415
if __name__ == "__main__":
1✔
416
    unittest.main()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc