Skip to content

Commit

Permalink
Update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kavanase committed Jun 10, 2024
1 parent 23dc8f9 commit 2990040
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 16 deletions.
10 changes: 8 additions & 2 deletions doped/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1223,9 +1223,15 @@ def __repr__(self):
def __eq__(self, other):
"""
Determine whether two ``DefectEntry`` objects are equal, by comparing
self.name and self.sc_entry.
``self.name``, ``self.sc_entry``, ``self.bulk_entry`` and
``self.corrections`` (i.e. name and energy match).
"""
return self.name == other.name and self.sc_entry == other.sc_entry
return (
self.name == other.name
and self.sc_entry == other.sc_entry
and self.bulk_entry == other.bulk_entry
and self.corrections == other.corrections
)

@property
def bulk_entry_energy(self):
Expand Down
12 changes: 8 additions & 4 deletions doped/thermodynamics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1303,8 +1303,9 @@ def get_equilibrium_concentrations(
conc_df = pd.DataFrame(energy_concentration_list)

if per_charge:
if skip_formatting:
if lean:
return conc_df

conc_df["Charge State Population"] = conc_df["Raw Concentration"] / conc_df.groupby("Defect")[
"Raw Concentration"
].transform("sum")
Expand Down Expand Up @@ -1688,15 +1689,16 @@ def get_quenched_fermi_level_and_concentrations(
)

def _get_constrained_concentrations(
fermi_level, per_charge=True, per_site=False, skip_formatting=False
fermi_level, per_charge=True, per_site=False, skip_formatting=False, lean=True
):
conc_df = self.get_equilibrium_concentrations(
chempots=chempots,
limit=limit,
el_refs=el_refs,
temperature=quenched_temperature,
fermi_level=fermi_level,
lean=True,
skip_formatting=True,
lean=lean,
)
conc_df["Total Concentration (cm^-3)"] = conc_df["Defect"].map(total_concentrations)
conc_df["Concentration (cm^-3)"] = ( # set total concentration to match annealing conc
Expand Down Expand Up @@ -1768,7 +1770,9 @@ def _get_constrained_total_q(fermi_level):
eq_fermi_level,
e_conc,
h_conc,
_get_constrained_concentrations(eq_fermi_level, per_charge, per_site, skip_formatting),
_get_constrained_concentrations(
eq_fermi_level, per_charge, per_site, skip_formatting, lean=False
), # not lean for final output
)

def get_formation_energy(
Expand Down
38 changes: 28 additions & 10 deletions tests/test_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import copy
import filecmp
import json
import operator
import os
import random
Expand All @@ -21,7 +20,6 @@
import numpy as np
import pytest
from ase.build import bulk, make_supercell
from monty.json import MontyEncoder
from monty.serialization import dumpfn, loadfn
from pymatgen.analysis.defects.core import DefectType
from pymatgen.analysis.structure_matcher import ElementComparator, StructureMatcher
Expand Down Expand Up @@ -62,6 +60,28 @@ def _potcars_available() -> bool:
return False


def _compare_attributes(obj1, obj2, exclude=None):
"""
Check that two objects are equal by comparing their public
attributes/properties.
"""
if exclude is None:
exclude = set() # Create an empty set if no exclusions

for attr in dir(obj1):
if attr.startswith("_") or attr in exclude or callable(getattr(obj1, attr)):
continue # Skip private, excluded, and callable attributes

print(attr)
val1 = getattr(obj1, attr)
val2 = getattr(obj2, attr)

if isinstance(val1, np.ndarray):
assert np.allclose(val1, val2)
else:
assert val1 == val2


class DefectsGeneratorTest(unittest.TestCase):
def setUp(self):
# don't run heavy tests on GH Actions, these are run locally (too slow without multiprocessing etc)
Expand Down Expand Up @@ -667,7 +687,7 @@ def _save_defect_gen_jsons(self, defect_gen):
if_present_rm("test.json")
if_present_rm("test_defect_gen.json")

def _load_and_test_defect_gen_jsons(self, defect_gen): # , gen_check): - shouldn't need this as we
def _load_and_test_defect_gen_jsons(self, defect_gen):
# test that the jsons are identical (except for ordering)
formula, _fu = defect_gen.primitive_structure.composition.get_reduced_formula_and_factor(
iupac_ordering=True
Expand All @@ -683,9 +703,7 @@ def _load_and_test_defect_gen_jsons(self, defect_gen): # , gen_check): - should

# test it's the same as the original:
# here we compare using json dumps because the ordering can change slightly when saving to json
assert json.dumps(defect_gen_from_json, sort_keys=True, cls=MontyEncoder) == json.dumps(
defect_gen, sort_keys=True, cls=MontyEncoder
)
_compare_attributes(defect_gen, defect_gen_from_json)
if_present_rm("test.json")
if_present_rm("test_loadfn.json")
if_present_rm(default_json_filename)
Expand Down Expand Up @@ -2016,7 +2034,7 @@ def test_defects_generator_CdTe(self):
for warning in w
if ("`calculation_metadata` attribute is not set") not in str(warning.message)
]
assert len(non_ignored_warnings) == 0 # no warnings for CdTe, scalar matrix
assert not non_ignored_warnings # no warnings for CdTe, scalar matrix

def test_defects_generator_CdTe_supercell_input(self):
CdTe_defect_gen, output = self._generate_and_test_no_warnings(self.CdTe_bulk_supercell)
Expand Down Expand Up @@ -3246,10 +3264,10 @@ def test_agsbte2(self):
self.sqs_agsbte2, generate_supercell=False
)
# same output regardless of `generate_supercell` because input supercell satisfies constraints
with pytest.raises(AssertionError):
_compare_attributes(agsbte2_defect_gen_a, agsbte2_defect_gen_b)
agsbte2_defect_gen_a.generate_supercell = False # adjust one difference to make equal overall
assert json.dumps(agsbte2_defect_gen_a, sort_keys=True, cls=MontyEncoder) == json.dumps(
agsbte2_defect_gen_b, sort_keys=True, cls=MontyEncoder
)
_compare_attributes(agsbte2_defect_gen_a, agsbte2_defect_gen_b)
assert np.allclose(
agsbte2_defect_gen_a.supercell_matrix,
np.array([[3.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
Expand Down

0 comments on commit 2990040

Please sign in to comment.