Skip to content

Commit

Permalink
Minor tests updates
Browse files Browse the repository at this point in the history
  • Loading branch information
kavanase committed Jan 21, 2025
1 parent 62ae081 commit 8fa321e
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 32 deletions.
2 changes: 1 addition & 1 deletion doped/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ def __init__(
if self.bulk_path is None: # determine bulk_path to use
if len(possible_bulk_folders) == 1:
self.bulk_path = os.path.join(self.output_path, possible_bulk_folders[0])
elif len([dir for dir in possible_bulk_folders if dir.endswith("_bulk")]) == 1:
elif len([dir for dir in possible_bulk_folders if str(dir).lower().endswith("_bulk")]) == 1:
self.bulk_path = os.path.join(
self.output_path,
next(iter(dir for dir in possible_bulk_folders if str(dir).lower().endswith("_bulk"))),
Expand Down
25 changes: 16 additions & 9 deletions doped/thermodynamics.py
Original file line number Diff line number Diff line change
Expand Up @@ -3768,12 +3768,12 @@ def _get_constrained_concentrations(

def _get_in_gap_fermi_level_stability_window(self, defect_entry: Union[str, DefectEntry]) -> float:
"""
Convenience method to calculate the maximum difference between Fermi
levels at which ``defect_entry`` is the.
Convenience method to calculate the maximum difference between a Fermi
level at which ``defect_entry`` is the ground-state charge state, and
the band edges.
ground-state charge state, and the band edges (i.e. the
max of (CBM - lowest TL) and (highest TL - VBM) where
TL is any transition level involving ``defect_entry``).
i.e. taken from the minimum of (CBM - lowest TL) and (highest TL - VBM)
where TL is any transition level involving ``defect_entry``.
Args:
defect_entry (str or DefectEntry):
Expand Down Expand Up @@ -3946,7 +3946,7 @@ def _add_effective_dopant_concentration(
{
"Defect": "Dopant",
"Charge": int(np.sign(effective_dopant_concentration)),
"Formation Energy (eV)": "N/A",
"Formation Energy (eV)": np.nan,
"Concentration (cm^-3)": np.abs(effective_dopant_concentration),
"Charge State Population": "100.0%",
},
Expand All @@ -3957,7 +3957,11 @@ def _add_effective_dopant_concentration(

for col in conc_df.columns:
if col not in eff_dopant_df.columns:
eff_dopant_df[col] = "N/A" # e.g. concentration per site, if per_site=True
# if string, set to "N/A":
if isinstance(conc_df[col].iloc[0], str):
eff_dopant_df[col] = "N/A"
else:
eff_dopant_df[col] = np.nan # e.g. concentration per site, if per_site=True

columns_to_drop = [col for col in eff_dopant_df.columns if col not in conc_df.columns]
eff_dopant_df = eff_dopant_df.drop(columns=columns_to_drop)
Expand All @@ -3969,7 +3973,10 @@ def _group_defect_charge_state_concentrations(
conc_df: pd.DataFrame, per_site: bool = False, skip_formatting: bool = False, lean: bool = False
):
summed_df = conc_df.groupby("Defect").sum(numeric_only=True) # auto-reordered by groupby sum
summed_df = summed_df.loc[conc_df["Defect"].unique()] # retain ordering
defects = (
conc_df["Defect"] if "Defect" in conc_df.columns else conc_df.index.get_level_values("Defect")
)
summed_df = summed_df.loc[defects.unique()] # retain ordering
conc_column = next(k for k in conc_df.columns if k.startswith("Concentration"))
raw_concentrations = (
summed_df["Raw Concentration"]
Expand Down Expand Up @@ -4229,7 +4236,7 @@ def scissor_dos(delta_gap: float, dos: Union[Dos, FermiDos], tol: float = 1e-8,
scissored_dos_dict["efermi"] -= np.float64(delta_gap / 2)

if verbose:
print(f"Orig gap: {dos.get_gap(tol=tol)}, new gap:{dos.get_gap(tol=tol) + delta_gap}")
print(f"Orig gap: {dos.get_gap(tol=tol):.4f}, new gap:{dos.get_gap(tol=tol) + delta_gap:.4f}")
scissored_dos_dict["structure"] = dos.structure.as_dict()
if isinstance(dos, FermiDos):
return FermiDos.from_dict(scissored_dos_dict)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,7 @@ def test_extrinsic_Sb2Se3(self):
# warning about negative corrections when using (fake) isotropic dielectric:
Sb2Se3_O_dp, w = _create_dp_and_capture_warnings(
output_path=f"{self.Sb2Se3_DATA_DIR}/defect",
bulk_path="bulk",
bulk_path=f"{self.Sb2Se3_DATA_DIR}/bulk",
dielectric=40, # fake isotropic dielectric
parse_projected_eigen=False,
)
Expand Down
43 changes: 22 additions & 21 deletions tests/test_thermodynamics.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ def setUpClass(cls):

cls.orig_MgO_defect_thermo = loadfn(os.path.join(cls.MgO_EXAMPLE_DIR, "MgO_thermo.json.gz"))
cls.orig_MgO_defect_dict = loadfn(os.path.join(cls.MgO_EXAMPLE_DIR, "MgO_defect_dict.json.gz"))
cls.MgO_chempots = loadfn(os.path.join(cls.EXAMPLE_DIR, "CompetingPhases/MgO_chempots.json"))
cls.MgO_chempots = loadfn(os.path.join(cls.EXAMPLE_DIR, "MgO/CompetingPhases/MgO_chempots.json"))

cls.Sb2O5_chempots = loadfn(os.path.join(data_dir, "Sb2O5/Sb2O5_chempots.json"))
cls.orig_Sb2O5_defect_thermo = loadfn(os.path.join(data_dir, "Sb2O5/Sb2O5_thermo.json.gz"))
Expand Down Expand Up @@ -2706,13 +2706,13 @@ def test_prune_to_stable_entries(self):
)
== 2
)
for i in ["sub_1_Te_on_Se_1", "sub_1_S_on_Se_1", "sub_1_O_on_Se_1", "inter_5_S_1", "inter_3_Te_1"]:
for i in ["sub_1_Te_on_Se_1", "sub_1_S_on_Se_1", "sub_1_O_on_Se_1", "inter_5_S_1"]:
assert i in self.Se_ext_no_pnict_thermo.defect_entries, f"Checking {i}"

pruned_Se_ext_no_pnict_thermo = self.Se_ext_no_pnict_thermo.prune_to_stable_entries()
assert len(pruned_Se_ext_no_pnict_thermo) == 70
assert len(pruned_Se_ext_no_pnict_thermo.transition_level_map) == 16
for i in ["sub_1_Te_on_Se_1", "sub_1_S_on_Se_1", "sub_1_O_on_Se_1", "inter_5_S_1", "inter_3_Te_1"]:
for i in ["sub_1_Te_on_Se_1", "sub_1_S_on_Se_1", "sub_1_O_on_Se_1", "inter_5_S_1"]:
assert i not in pruned_Se_ext_no_pnict_thermo.defect_entries, f"Checking {i}"
assert (
len(
Expand Down Expand Up @@ -3085,9 +3085,9 @@ def test_get_fermi_level_and_concentrations(self):
assert ("Orig gap:" in output) == kwargs.get("verbose", False)
if kwargs.get("delta_gap") == 0.3 and kwargs.get("verbose", False):
if kwargs.get("tol") == 1e-1:
assert "Orig gap: 2.7513, new gap:3.0513" in output
assert "Orig gap: 2.7565, new gap:3.0565" in output
else:
assert "Orig gap: 1.5126, new gap:1.8126" in output
assert "Orig gap: 1.5178, new gap:1.8178" in output
assert np.isclose(fermi_level, 0.35124, atol=1e-3) # different

assert not w
Expand Down Expand Up @@ -3115,7 +3115,7 @@ def test_get_fermi_level_and_concentrations(self):
)
# Similar values to CdTe_LZ_Te_rich_concentrations.png, slightly different due to no scissoring
assert (
np.isclose(fermi_level, 0.3396, atol=1e-3)
np.isclose(fermi_level, 0.3374, atol=1e-3)
== anneal_at_1000K_quench_at_RT_no_dopants_scissoring
)
assert (
Expand Down Expand Up @@ -3206,23 +3206,24 @@ def test_get_fermi_level_and_concentrations(self):
)
# Note that this check requires ``skip_formatting`` to be True as we don't format the
# dopant values here:
expected_df = defect_thermo.get_equilibrium_concentrations(
fermi_level=annealing_fermi_level,
limit="Te-rich",
temperature=kwargs.get("annealing_temperature", 1000),
**{
k: v
for k, v in kwargs.items()
if k not in ["return_annealing_values", "effective_dopant_concentration"]
},
)
expected_df = _add_effective_dopant_concentration(
defect_thermo.get_equilibrium_concentrations(
fermi_level=annealing_fermi_level,
limit="Te-rich",
temperature=kwargs.get("annealing_temperature", 1000),
**{
k: v
for k, v in kwargs.items()
if k not in ["return_annealing_values", "effective_dopant_concentration"]
},
),
expected_df,
kwargs.get("effective_dopant_concentration"),
)
if kwargs.get("per_charge", True):
conc_df_to_compare = conc_df.drop(columns=["Total Concentration (cm^-3)"])
# replace NaNs with "N/A" (Dopant per site conc):
conc_df_to_compare = conc_df_to_compare.fillna("N/A")
else:
conc_df_to_compare = conc_df
print(conc_df_to_compare, expected_df) # for debugging
print(conc_df_to_compare.columns, expected_df.columns) # for debugging
pd.testing.assert_frame_equal(conc_df_to_compare, expected_df)
Expand Down Expand Up @@ -3394,7 +3395,7 @@ def test_get_fermi_level_and_concentrations(self):
"No chemical potentials supplied, so using 0 for all chemical potentials" in str(warn.message)
for warn in w
)
assert np.isclose(results[0], 1.1319, atol=1e-3)
assert np.isclose(results[0], 1.2737, atol=1e-3)

defect_thermo = deepcopy(self.defect_thermo)
defect_thermo.chempots = None
Expand All @@ -3413,7 +3414,7 @@ def test_get_in_gap_fermi_level_stability_window(self):
("v_Cd_0", 0.35),
(self.defect_thermo.defect_entries["v_Cd_0"], 0.35),
("v_Cd_-2", 1.15),
("Te_Cd_0", 1.374), # this case, of being bounded by other charges on both sides,
("Te_Cd_0", 1.162), # this case, of being bounded by other charges on both sides,
# wasn't tested with CdTe_example_thermo in DefectThermodynamicsTestCase
]:
assert np.isclose(
Expand Down Expand Up @@ -3642,7 +3643,7 @@ def _array_from_conc_df(name):
)
ax.plot(
self.anneal_temperatures,
_array_from_conc_df("Te_i_Td_Te2.83"),
_array_from_conc_df("Te_i_Td_Te2.83_a"),
marker="o",
label="$Te_i$",
linestyle=":",
Expand Down

0 comments on commit 8fa321e

Please sign in to comment.