Skip to content

Commit

Permalink
Add informative error message if no defects parsed, and test
Browse files Browse the repository at this point in the history
  • Loading branch information
kavanase committed Feb 8, 2024
1 parent 5d8ebf5 commit 938a763
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 6 deletions.
12 changes: 12 additions & 0 deletions doped/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,9 @@ def __init__(
f"files are present and/or specify `bulk_path` manually."
)

# remove trailing '/.' from bulk_path if present:
self.bulk_path = self.bulk_path.rstrip("/.")

self.defect_dict = {}
self.bulk_corrections_data = { # so we only load and parse bulk data once
"bulk_locpot_dict": None,
Expand Down Expand Up @@ -912,6 +915,15 @@ def _mention_bulk_path_subfolder_for_correction_warnings(warning: str) -> str:
if defect_list:
warnings.warn(f"Defects: {defect_list} each encountered the same warning:\n{warning}")

if not parsed_defect_entries:
subfolder_string = f" and `subfolder`: '{self.subfolder}'" if self.subfolder != "." else ""
raise ValueError(
f"No defect calculations in `output_path` '{self.output_path}' were successfully parsed, "
f"using `bulk_path`: {self.bulk_path}{subfolder_string}. Please check the correct "
f"defect/bulk paths and subfolder are being set, and that the folder structure is as "
f"expected (see `DefectsParser` docstring)."
)

# get any defect entries in parsed_defect_entries that share the same name (without charge):
# first get any entries with duplicate names:
entries_to_rename = [ # TODO: Add test for this:
Expand Down
2 changes: 1 addition & 1 deletion doped/utils/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ def _get_formation_energy_lines(defect_thermodynamics, dft_chempots, xlim):


def _get_ylim_from_y_range_vals(y_range_vals, ymin=0, auto_labels=False):
window = max(y_range_vals) - min(y_range_vals)
window = max(y_range_vals) - min(*y_range_vals, ymin)
spacer = 0.1 * window
ylim = (ymin, max(y_range_vals) + spacer)
if auto_labels: # need to manually set xlim or ylim if labels cross axes!!
Expand Down
2 changes: 1 addition & 1 deletion examples/CdTe/CdTe_example_thermo.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions tests/data/CdTe_defect_gen.json
100644 → 100755

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion tests/data/cu_defect_gen.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion tests/data/ytos_defect_gen.json
100644 → 100755

Large diffs are not rendered by default.

31 changes: 30 additions & 1 deletion tests/test_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,26 @@ def test_DefectsParser_corrections_errors_warning(self):
style=f"{module_path}/../doped/utils/doped.mplstyle",
savefig_kwargs={"transparent": True, "bbox_inches": "tight"},
)
def test_DefectsParser_YTOS(self):
def test_DefectsParser_YTOS_default_bulk(self):
# bulk path needs to be specified for YTOS as it's not the default name:
dp = DefectsParser(
output_path=self.YTOS_EXAMPLE_DIR,
dielectric=self.ytos_dielectric,
)
self._check_DefectsParser(dp)
thermo = dp.get_defect_thermodynamics()
dumpfn(
thermo, os.path.join(self.YTOS_EXAMPLE_DIR, "YTOS_example_thermo.json")
) # for test_plotting
return thermo.plot() # no chempots for YTOS formation energy plot test

@pytest.mark.mpl_image_compare(
baseline_dir=f"{data_dir}/remote_baseline_plots",
filename="YTOS_example_defects_plot.png",
style=f"{module_path}/../doped/utils/doped.mplstyle",
savefig_kwargs={"transparent": True, "bbox_inches": "tight"},
)
def test_DefectsParser_YTOS_explicit_bulk(self):
# bulk path needs to be specified for YTOS as it's not the default name:
dp = DefectsParser(
output_path=self.YTOS_EXAMPLE_DIR,
Expand All @@ -456,6 +475,16 @@ def test_DefectsParser_YTOS(self):
) # for test_plotting
return thermo.plot() # no chempots for YTOS formation energy plot test

def test_DefectsParser_no_defects_parsed_error(self):
with self.assertRaises(ValueError) as exc:
DefectsParser(output_path=self.YTOS_EXAMPLE_DIR, subfolder="vasp_gam")
assert (
f"No defect calculations in `output_path` '{self.YTOS_EXAMPLE_DIR}' were successfully parsed, "
f"using `bulk_path`: {self.YTOS_EXAMPLE_DIR}/Bulk and `subfolder`: 'vasp_gam'. Please check "
f"the correct defect/bulk paths and subfolder are being set, and that the folder structure is "
f"as expected (see `DefectsParser` docstring)." in str(exc.exception)
)

@pytest.mark.mpl_image_compare(
baseline_dir=f"{data_dir}/remote_baseline_plots",
filename="O_Se_example_defects_plot.png",
Expand Down
5 changes: 4 additions & 1 deletion tests/test_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -983,11 +983,11 @@ def _check_editing_defect_gen(self, random_defect_entry_name, defect_gen):
def _generate_and_test_no_warnings(self, structure, min_image_distance=None, **kwargs):
original_stdout = sys.stdout # Save a reference to the original standard output
sys.stdout = StringIO() # Redirect standard output to a stringIO object.
w = None
try:
with warnings.catch_warnings(record=True) as w:
warnings.resetwarnings()
defect_gen = DefectsGenerator(structure, **kwargs)
print([str(warning.message) for warning in w]) # for debugging
if min_image_distance is None:
assert not w
else:
Expand All @@ -1003,6 +1003,9 @@ def _generate_and_test_no_warnings(self, structure, min_image_distance=None, **k
finally:
sys.stdout = original_stdout # Reset standard output to its original value.

if w:
print([str(warning.message) for warning in w]) # for debugging

return defect_gen, output

def test_extrinsic(self):
Expand Down

0 comments on commit 938a763

Please sign in to comment.