diff --git a/abipy/abio/abivars.py b/abipy/abio/abivars.py index 09765b0c3..fc3241f06 100644 --- a/abipy/abio/abivars.py +++ b/abipy/abio/abivars.py @@ -460,6 +460,45 @@ def write_notebook(self, nbpath=None): return self._write_nb_nbpath(nb, nbpath) + def get_differences(self, other, ignore_vars=None): + """ + Get the differences between this AbinitInputFile and another. + """ + diffs = [] + to_ignore = {"acell", "angdeg", "rprim", "ntypat", "natom", "znucl", "typat", "xred", "xcart", "xangst"} + if ignore_vars is not None: + to_ignore.update(ignore_vars) + if self.ndtset != other.ndtset: + diffs.append(f"Number of datasets in this file is {self.ndtset} " + f"while other file has {other.ndtset} datasets.") + return diffs + for idataset, self_dataset in enumerate(self.datasets): + other_dataset = other.datasets[idataset] + if self_dataset.structure != other_dataset.structure: + diffs.append("Structures are different.") + self_dataset_dict = dict(self_dataset) + other_dataset_dict = dict(other_dataset) + for k in to_ignore: + if k in self_dataset_dict: + del self_dataset_dict[k] + if k in other_dataset_dict: + del other_dataset_dict[k] + common_keys = set(self_dataset_dict.keys()).intersection(other_dataset_dict.keys()) + self_only_keys = set(self_dataset_dict.keys()).difference(other_dataset_dict.keys()) + other_only_keys = set(other_dataset_dict.keys()).difference(self_dataset_dict.keys()) + if self_only_keys: + diffs.append(f"The following variables are in this file but not in other: " + f"{', '.join([str(k) for k in self_only_keys])}") + if other_only_keys: + diffs.append(f"The following variables are in other file but not in this one: " + f"{', '.join([str(k) for k in other_only_keys])}") + for k in common_keys: + if self_dataset_dict[k] != other_dataset_dict[k]: + diffs.append(f"The variable '{k}' is different in the two files:\n" + f" - this file: '{self_dataset_dict[k]}'\n" + f" - other file: '{other_dataset_dict[k]}'") + return diffs + class AbinitInputParser(object): diff --git a/abipy/abio/tests/test_abivars.py b/abipy/abio/tests/test_abivars.py index 1546adb17..2292ee372 100644 --- a/abipy/abio/tests/test_abivars.py +++ b/abipy/abio/tests/test_abivars.py @@ -320,3 +320,82 @@ def test_format_string_abivars(self): assert format_string_abivars("pseudos", ["xxx", "yyy"]) == '\n "xxx,\n yyy"' assert format_string_abivars("pseudos", 'xxx') == '"xxx"' assert format_string_abivars("pseudos", '"xxx"') == '"xxx"' + + def test_get_differences(self): + s1 = """ + ngkpt 2 2 2 + natom 2 + ntypat 2 + typat 1 2 + znucl 48 34 + xred + 0.0000000000 0.0000000000 0.0000000000 + 0.2500000000 0.2500000000 0.2500000000 + acell 1.0 1.0 1.0 + rprim + 0.0000000000 5.8556815705 5.8556815705 + 5.8556815705 0.0000000000 5.8556815705 + 5.8556815705 5.8556815705 0.0000000000 + """ + s2 = """ + ngkpt 2 2 2 + natom 2 + ntypat 2 + typat 1 2 + znucl 48 34 + xred + 0.0000000000 0.0000000000 0.0000000000 + 0.2500000000 0.2500000000 0.2500000000 + acell 0.5 0.5 0.5 + rprim + 0.0000000000 11.711363141 11.711363141 + 11.711363141 0.0000000000 11.711363141 + 11.711363141 11.711363141 0.0000000000 + """ + inp1 = AbinitInputFile.from_string(s1) + inp2 = AbinitInputFile.from_string(s2) + assert inp1.get_differences(inp2) == [] + s1 = "natom 1 ntypat 1 typat 1 znucl 14 xred 0 0 0 ngkpt 2 2 2" + s2 = "natom 1 ntypat 1 typat 1 znucl 14 xred 0 0 0 ngkpt 3 3 3" + s3 = "natom 1 ntypat 1 typat 1 znucl 8 xred 0 0 0 ngkpt 2 2 2" + s4 = "natom 1 ntypat 1 typat 1 znucl 14 xred 0 0 0 ngkpt 2 2 2 ecut 6.0" + inp1 = AbinitInputFile.from_string(s1) + inp2 = AbinitInputFile.from_string(s2) + inp3 = AbinitInputFile.from_string(s3) + inp4 = AbinitInputFile.from_string(s4) + diffs = inp1.get_differences(inp2) + assert len(diffs) == 1 + assert diffs[0] == "The variable 'ngkpt' is different in the two files:\n" \ + " - this file: '2 2 2'\n" \ + " - other file: '3 3 3'" + diffs = inp2.get_differences(inp1) + assert len(diffs) == 1 + assert diffs[0] == "The variable 'ngkpt' is different in the two files:\n" \ + " - this file: '3 3 3'\n" \ + " - other file: '2 2 2'" + diffs = inp1.get_differences(inp2, ignore_vars=['ngkpt']) + assert diffs == [] + diffs = inp1.get_differences(inp3) + assert diffs == ["Structures are different."] + diffs = inp1.get_differences(inp4) + assert diffs == ["The following variables are in other file but not in this one: ecut"] + diffs = inp4.get_differences(inp1) + assert diffs == ["The following variables are in this file but not in other: ecut"] + diffs = inp1.get_differences(inp4, ignore_vars=['ecut']) + assert diffs == [] + diffs = inp2.get_differences(inp4) + assert len(diffs) == 2 + assert "The following variables are in other file but not in this one: ecut" in diffs + assert "The variable 'ngkpt' is different in the two files:\n" \ + " - this file: '3 3 3'\n" \ + " - other file: '2 2 2'" in diffs + diffs = inp2.get_differences(inp4, ignore_vars=["ecut"]) + assert diffs == [ + "The variable 'ngkpt' is different in the two files:\n" + " - this file: '3 3 3'\n" + " - other file: '2 2 2'" + ] + diffs = inp2.get_differences(inp4, ignore_vars=["ngkpt"]) + assert diffs == ["The following variables are in other file but not in this one: ecut"] + diffs = inp2.get_differences(inp4, ignore_vars=["ngkpt", "ecut"]) + assert diffs == []