Skip to content

Commit 919b7e3

Browse files
authored
JDFTXOutfile none_on_error oversight fix (#4399)
* Fixing oversight where attributes are incorrect retrieved if the final outfile slice is `None`, removing commented out code * Testing for nonetype fix, expanding generic assert_same_value function
1 parent 78fb799 commit 919b7e3

File tree

4 files changed

+34
-55
lines changed

4 files changed

+34
-55
lines changed

src/pymatgen/io/jdftx/jdftxoutfileslice.py

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -826,40 +826,6 @@ def _create_settings_dict(self, text: list[str], start_flag: str) -> dict:
826826
settings_dict[key] = value
827827
return settings_dict
828828

829-
# def _get_settings_object(
830-
# self,
831-
# text: list[str],
832-
# settings_class: type[JMinSettingsElectronic | JMinSettingsFluid | JMinSettingsIonic | JMinSettingsLattice],
833-
# ) -> JMinSettingsElectronic | JMinSettingsFluid | JMinSettingsIonic | JMinSettingsLattice:
834-
# """Get appropriate JMinSettings mutant.
835-
836-
# Get the settings object from the out file text.
837-
838-
# Args:
839-
# text (list[str]): Output of read_file for out file.
840-
# settings_class (Type[JMinSettings]): Settings class to create object from.
841-
842-
# Returns:
843-
# JMinSettingsElectronic | JMinSettingsFluid | JMinSettingsIonic | JMinSettingsLattice: Settings object.
844-
# """
845-
# settings_dict = self._create_settings_dict(text, settings_class.start_flag)
846-
# return settings_class(params=settings_dict) if len(settings_dict) else None
847-
848-
# def _set_min_settings(self, text: list[str]) -> None:
849-
# """Set the settings objects from the out file text.
850-
851-
# Set the settings objects from the out file text.
852-
853-
# Args:
854-
# text (list[str]): Output of read_file for out file.
855-
# """
856-
# self.jsettings_fluid = self._get_settings_object(text, JMinSettingsFluid)
857-
# self.jsettings_electronic = self._get_settings_object(text, JMinSettingsElectronic)
858-
# self.jsettings_lattice = self._get_settings_object(text, JMinSettingsLattice)
859-
# self.jsettings_ionic = self._get_settings_object(text, JMinSettingsIonic)
860-
# # if self.jsettings_lattice is not None and "niterations" in self.jsettings_lattice.params:
861-
# # self.constant_lattice = int(self.jsettings_lattice.params["niterations"]) == 0
862-
863829
def _set_geomopt_vars(self, text: list[str]) -> None:
864830
"""Set the geom_opt and geom_opt_type class variables.
865831
@@ -890,19 +856,6 @@ def _set_geomopt_vars(self, text: list[str]) -> None:
890856
self.geom_opt = False
891857
self.geom_opt_type = "single point"
892858
self.geom_opt_label = "IonicMinimize"
893-
# # Attempts to set all self.jsettings_x class variables
894-
# self._set_min_settings(text)
895-
# if self.jsettings_ionic is None or self.jsettings_lattice is None:
896-
# raise ValueError("Unknown issue in setting settings objects")
897-
# if int(self.jsettings_lattice.params["niterations"]) > 0:
898-
# self.geom_opt = True
899-
# self.geom_opt_type = "lattice"
900-
# elif int(self.jsettings_ionic.params["niterations"]) > 0:
901-
# self.geom_opt = True
902-
# self.geom_opt_type = "ionic"
903-
# else:
904-
# self.geom_opt = False
905-
# self.geom_opt_type = "single point"
906859

907860
def _get_initial_structure(self, text: list[str]) -> Structure | None:
908861
"""Get the initial structure from the out file text.
@@ -982,11 +935,6 @@ def _set_backup_vars(self, text: list[str]) -> None:
982935
mval = float(_val)
983936
else:
984937
mval = None
985-
# val = None
986-
# for line in lines[::-1]:
987-
# val = get_colon_val(text[line], "mu:")
988-
# if val is not None:
989-
# break
990938
self._mu_backup = mval
991939

992940
def _set_orb_fillings_nobroad(self, nspin: float) -> None:

src/pymatgen/io/jdftx/outputs.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -559,9 +559,14 @@ def from_file(
559559
return cls(slices=slices)
560560

561561
def __post_init__(self):
562-
if len(self.slices):
562+
last_slice = None
563+
for slc in self.slices[::-1]:
564+
if slc is not None:
565+
last_slice = slc
566+
break
567+
if last_slice is not None:
563568
for var in _jof_atr_from_last_slice:
564-
setattr(self, var, getattr(self.slices[-1], var))
569+
setattr(self, var, getattr(last_slice, var))
565570
self.trajectory = self._get_trajectory()
566571

567572
def _get_trajectory(self) -> Trajectory | None:

tests/io/jdftx/shared_test_utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from pathlib import Path
1111

1212
import pytest
13+
from numpy import allclose, ndarray
1314

1415
from pymatgen.util.testing import TEST_FILES_DIR
1516

@@ -27,6 +28,8 @@ def assert_same_value(testval, knownval):
2728
assert_same_value(testval[k], knownval[k])
2829
elif testval is None:
2930
assert knownval is None
31+
elif isinstance(testval, ndarray):
32+
assert allclose(testval, knownval)
3033
else:
3134
assert testval == knownval
3235
else:

tests/io/jdftx/test_jdftxoutfile.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
import pytest
66

7-
from pymatgen.io.jdftx.outputs import JDFTXOutfile
7+
from pymatgen.io.jdftx._output_utils import read_outfile_slices
8+
from pymatgen.io.jdftx.jdftxoutfileslice import JDFTXOutfileSlice
9+
from pymatgen.io.jdftx.outputs import JDFTXOutfile, _jof_atr_from_last_slice
810

911
from .outputs_test_utils import (
1012
etot_etype_outfile_known_simple,
@@ -27,6 +29,7 @@
2729
problem2_outfile_known_simple,
2830
problem2_outfile_path,
2931
)
32+
from .shared_test_utils import assert_same_value
3033

3134
if TYPE_CHECKING:
3235
from pathlib import Path
@@ -71,3 +74,23 @@ def test_JDFTXOutfile_default_struc_inheritance(filename: Path, latknown: dict):
7174
for i in range(3):
7275
for j in range(3):
7376
assert pytest.approx(lattice[i][j]) == latknown[f"{i}{j}"]
77+
78+
79+
# Make sure all possible exceptions are caught when none_on_error is True
80+
@pytest.mark.parametrize(("ex_outfile_path"), [(partial_lattice_init_outfile_path)])
81+
def test_none_on_partial(ex_outfile_path: Path):
82+
texts = read_outfile_slices(str(ex_outfile_path))
83+
texts0 = texts[:-1]
84+
85+
slices = [
86+
JDFTXOutfileSlice._from_out_slice(text, is_bgw=False, none_on_error=False) for i, text in enumerate(texts0)
87+
]
88+
outfile1 = JDFTXOutfile(slices=slices)
89+
slices.append(None)
90+
outfile2 = JDFTXOutfile(slices=slices)
91+
assert isinstance(outfile2, JDFTXOutfile)
92+
for var in _jof_atr_from_last_slice:
93+
assert_same_value(
94+
getattr(outfile1, var),
95+
getattr(outfile2, var),
96+
)

0 commit comments

Comments
 (0)