1# coding: utf-8
2"""Test for output files"""
3import os
4import abipy.data as abidata
5
6from abipy import abilab
7from abipy.core.testing import AbipyTest
8from abipy.abio.outputs import AbinitOutputFile, AbinitLogFile, AboRobot
9
10
11class AbinitLogFileTest(AbipyTest):
12
13    def test_abinit_logfile(self):
14        """"Testing AbinitLogFile."""
15        log_path = abidata.ref_file("refs/abinit.log")
16        with AbinitLogFile(log_path) as abilog:
17            repr(abilog); str(abilog)
18            assert abilog.to_string(verbose=2)
19            assert len(abilog.events) == 2
20            if self.has_nbformat():
21                abilog.write_notebook(nbpath=self.get_tmpname(text=True))
22
23
24class AbinitOutputTest(AbipyTest):
25
26    def test_gs_output(self):
27        """Testing AbinitOutputFile with GS calculation."""
28        abo_path = abidata.ref_file("refs/si_ebands/run.abo")
29        with AbinitOutputFile(abo_path) as abo:
30            repr(abo); str(abo)
31            assert abo.to_string(verbose=2)
32            assert abo.version == "8.0.6"
33            assert abo.run_completed
34            assert not abo.dryrun_mode
35            assert abo.ndtset == 2
36            assert abo.has_same_initial_structures
37            assert abo.has_same_final_structures
38            assert len(abo.initial_structures) == 2
39            assert abo.initial_structure is not None
40            assert abo.initial_structure.abi_spacegroup is not None
41            assert abo.initial_structure == abo.final_structure
42            abo.diff_datasets(1, 2, dryrun=True)
43
44            # Test the parsing of dimension and spginfo
45            dims_dataset, spginfo_dataset = abo.get_dims_spginfo_dataset()
46            assert len(dims_dataset) == 2 and list(dims_dataset.keys()) == [1, 2]
47            dims1 = dims_dataset[1]
48            assert dims1["iscf"] == 7
49            assert dims1["nfft"] == 5832
50            self.assert_almost_equal(dims1["mem_per_proc_mb"], 3.045)
51            self.assert_almost_equal(dims1["wfk_size_mb"], 0.717)
52            self.assert_almost_equal(dims1["denpot_size_mb"], 0.046)
53            assert spginfo_dataset[1]["spg_symbol"] == "Fd-3m"
54            assert spginfo_dataset[1]["spg_number"] == 227
55            assert spginfo_dataset[1]["bravais"] == "Bravais cF (face-center cubic)"
56            dims2 = dims_dataset[2]
57            assert dims2["iscf"] == -2
58            assert dims2["n1xccc"] == 2501
59            self.assert_almost_equal(dims2["mem_per_proc_mb"], 1.901)
60            self.assert_almost_equal(dims2["wfk_size_mb"], 0.340)
61            self.assert_almost_equal(dims2["denpot_size_mb"], 0.046)
62
63            str(abo.events)
64            gs_cycle = abo.next_gs_scf_cycle()
65            assert gs_cycle is not None
66            assert len(abo.get_all_gs_scf_cycles()) == 1
67
68            if self.has_matplotlib():
69                assert gs_cycle.plot(show=False)
70
71            abo.seek(0)
72            assert abo.next_d2de_scf_cycle() is None
73
74            timer = abo.get_timer()
75            assert len(timer) == 1
76            assert str(timer.summarize())
77
78            if self.has_matplotlib():
79                abo.compare_gs_scf_cycles([abo_path], show=False)
80                timer.plot_all(show=False)
81                abo.plot(show=False)
82
83            if self.has_panel():
84                assert hasattr(abo.get_panel(), "show")
85
86            if self.has_nbformat():
87                abo.write_notebook(nbpath=self.get_tmpname(text=True))
88                timer.write_notebook(nbpath=self.get_tmpname(text=True))
89
90    def test_ph_output(self):
91        """Testing AbinitOutputFile with phonon calculations."""
92        abo_path = abidata.ref_file("refs/gs_dfpt.abo")
93        with AbinitOutputFile(abo_path) as abo:
94            repr(abo); str(abo)
95            assert abo.to_string(verbose=2)
96
97            assert abo.version == "8.3.2"
98            assert abo.run_completed
99            assert not abo.dryrun_mode
100            assert abo.ndtset == 3
101            assert abo.has_same_initial_structures
102            assert abo.has_same_final_structures
103            assert len(abo.initial_structures) == 3
104            assert abo.initial_structure is not None
105            assert abo.initial_structure.abi_spacegroup is not None
106            assert abo.initial_structure == abo.final_structure
107
108            gs_cycle = abo.next_gs_scf_cycle()
109            assert gs_cycle is not None
110
111            ph_cycle = abo.next_d2de_scf_cycle()
112            assert ph_cycle is not None
113
114            if self.has_matplotlib():
115                assert ph_cycle.plot(show=False)
116                assert abo.compare_d2de_scf_cycles([abo_path], show=False)
117                abo.plot(show=False)
118
119            if self.has_nbformat():
120                abo.write_notebook(nbpath=self.get_tmpname(text=True))
121
122            # Call these functions at end to avoid seek(0).
123            assert len(abo.get_all_gs_scf_cycles()) == 1
124            assert len(abo.get_all_d2de_scf_cycles()) == 3
125
126    def test_dryrun_output(self):
127        """Testing AbinitOutputFile with file produced in dry-run mode."""
128        with abilab.abiopen(abidata.ref_file("refs/dryrun.abo")) as abo:
129            repr(abo); str(abo)
130            assert abo.to_string(verbose=2)
131            assert abo.dryrun_mode
132            assert abo.ndtset == 1
133            assert abo.has_same_initial_structures
134            assert abo.has_same_final_structures
135            assert len(abo.initial_structures) == 1
136
137            assert abo.initial_structure.abi_spacegroup is not None
138
139            # This to test get_dims_spginfo_dataset with one dataset.
140            dims_dataset, spg_dataset = abo.get_dims_spginfo_dataset()
141            assert len(dims_dataset) == 1
142            dims = dims_dataset[1]
143            assert dims["nsppol"] == 1
144            assert dims["nsym"] == 48
145            assert dims["nkpt"] == 29
146            self.assert_almost_equal(dims["mem_per_proc_mb"], 3.389)
147            self.assert_almost_equal(dims["wfk_size_mb"], 0.717)
148            self.assert_almost_equal(dims["denpot_size_mb"], 0.046)
149            assert spg_dataset[1]["spg_symbol"] == "Fd-3m"
150            assert spg_dataset[1]["spg_number"] == 227
151            assert spg_dataset[1]["bravais"] == "Bravais cF (face-center cubic)"
152
153    def test_abinit_output_with_ctrlm(self):
154        """Testing AbinitOutputFile with file containing CTRL+M char."""
155        test_dir = os.path.join(os.path.dirname(__file__), "..", "..", 'test_files')
156        with abilab.abiopen(os.path.join(test_dir, "ctrlM_run.abo")) as abo:
157            assert abo.version == "8.7.1"
158            assert abo.run_completed
159            assert abo.to_string(verbose=2)
160            assert abo.ndtset == 1
161            assert abo.initial_structure.abi_spacegroup is not None
162            assert abo.initial_structure.abi_spacegroup.spgid == 142
163            assert abo.proc0_cputime == 0.7
164            assert abo.proc0_walltime == 0.7
165            assert abo.overall_cputime == 0.7
166            assert abo.overall_walltime == 0.7
167
168            # Test the parsing of dimension and spginfo
169            dims_dataset, spginfo_dataset = abo.get_dims_spginfo_dataset()
170            dims1 = dims_dataset[1]
171            assert dims1["mqgrid"] == 5580
172            assert spginfo_dataset[1]["spg_symbol"] == "I4_1/acd"
173            assert spginfo_dataset[1]["spg_number"] == 142
174
175    def test_all_outputs_in_tests(self):
176        """
177        Try to parse all Abinit output files inside the Abinit `tests` directory.
178        Requires $ABINIT_HOME_DIR env variable.
179        """
180        abi_homedir = os.environ.get("ABINIT_HOME_DIR")
181        if abi_homedir is not None:
182            #raise self.SkipTest("Environment variable `ABINIT_HOME_DIR` is required for this test.")
183            abitests_dir = os.path.join(abi_homedir, "tests")
184        else:
185            abitests_dir = os.path.join(abidata.dirpath, "refs")
186
187        from abipy.abio.outputs import validate_output_parser
188        assert os.path.exists(abitests_dir)
189        retcode = validate_output_parser(abitests_dir=abitests_dir)
190        assert retcode == 0
191
192    def test_aborobot(self):
193        """Testing AboRobot."""
194        abo_paths = abidata.ref_files("refs/si_ebands/run.abo", "refs/gs_dfpt.abo")
195        with AboRobot.from_files(abo_paths) as robot:
196            repr(robot); str(robot)
197            assert robot.to_string(verbose=2)
198            assert robot._repr_html_()
199            dims = robot.get_dims_dataframe()
200            df = robot.get_dataframe(with_geo=True)
201            time_df = robot.get_time_dataframe()
202            self.assert_equal(time_df["overall_walltime"].values, [4.0, 26.1])
203
204            if self.has_nbformat():
205                robot.write_notebook(nbpath=self.get_tmpname(text=True))
206