From 7dace318fd8dbcbb9c33c17dab682a362236a645 Mon Sep 17 00:00:00 2001 From: naik-aakash Date: Thu, 14 Mar 2024 15:51:17 +0100 Subject: [PATCH 1/6] rewrite band_overlap_dict output format, update and add associated tests --- pymatgen/io/lobster/outputs.py | 47 +++++++++++++++++-------------- tests/io/lobster/test_inputs.py | 49 ++++++++++++++++----------------- 2 files changed, 50 insertions(+), 46 deletions(-) diff --git a/pymatgen/io/lobster/outputs.py b/pymatgen/io/lobster/outputs.py index c4c441f6c13..3f534eefc1a 100644 --- a/pymatgen/io/lobster/outputs.py +++ b/pymatgen/io/lobster/outputs.py @@ -1326,10 +1326,10 @@ def __init__( """ Args: filename: filename of the "bandOverlaps.lobster" file. - band_overlaps_dict: A dictionary containing the band overlap data of the form: {spin: {"kpoint as string": - {"max_deviation":float that describes the max deviation, "matrix": 2D array of the size number of bands - times number of bands including the overlap matrices with}}}. - max_deviation (list[float]): A list of floats describing the maximal deviation for each problematic kpoint. + band_overlaps_dict: A dictionary containing the band overlap data of the form: {spin: {"k_points" : list of + k-point array, "max_deviations":list of max deviations associated to each k-point, "matrices": list of the + overlap matrices associated with each k-point}. + max_deviation (list[float]): A list of floats describing the maximal deviation for each problematic k-point. """ self._filename = filename self.band_overlaps_dict = {} if band_overlaps_dict is None else band_overlaps_dict @@ -1363,24 +1363,31 @@ def _read(self, contents: list, spin_numbers: list): kpoint_array = [] for kpointel in kpoint: if kpointel not in ["at", "k-point", ""]: - kpoint_array.append(str(kpointel)) + kpoint_array.append(float(kpointel)) elif "maxDeviation" in line: if spin not in self.band_overlaps_dict: self.band_overlaps_dict[spin] = {} - if " ".join(kpoint_array) not in self.band_overlaps_dict[spin]: - self.band_overlaps_dict[spin][" ".join(kpoint_array)] = {} + if "k_points" not in self.band_overlaps_dict[spin]: + self.band_overlaps_dict[spin]["k_points"] = [] + if "max_deviations" not in self.band_overlaps_dict[spin]: + self.band_overlaps_dict[spin]["max_deviations"] = [] + if "matrices" not in self.band_overlaps_dict[spin]: + self.band_overlaps_dict[spin]["matrices"] = [] maxdev = line.split(" ")[2] - self.band_overlaps_dict[spin][" ".join(kpoint_array)]["maxDeviation"] = float(maxdev) + self.band_overlaps_dict[spin]["max_deviations"].append(float(maxdev)) + self.band_overlaps_dict[spin]["k_points"].append(kpoint_array) self.max_deviation.append(float(maxdev)) - self.band_overlaps_dict[spin][" ".join(kpoint_array)]["matrix"] = [] + overlaps = [np.ndarray] else: - overlaps = [] + rows = [] for el in line.split(" "): if el != "": - overlaps.append(float(el)) - self.band_overlaps_dict[spin][" ".join(kpoint_array)]["matrix"].append(overlaps) + rows.append(float(el)) + overlaps.append(rows) + if len(overlaps) == len(rows): + self.band_overlaps_dict[spin]["matrices"].append(np.matrix(overlaps)) def has_good_quality_maxDeviation(self, limit_maxDeviation: float = 0.1) -> bool: """ @@ -1414,26 +1421,26 @@ def has_good_quality_check_occupied_bands( Returns: Boolean that will give you information about the quality of the projection """ - for matrix in self.band_overlaps_dict[Spin.up].values(): - for iband1, band1 in enumerate(matrix["matrix"]): + for matrix in self.band_overlaps_dict[Spin.up]["matrices"]: + for iband1, band1 in enumerate(matrix): for iband2, band2 in enumerate(band1): if iband1 < number_occ_bands_spin_up and iband2 < number_occ_bands_spin_up: if iband1 == iband2: - if abs(band2 - 1.0) > limit_deviation: + if abs(band2 - 1.0).all() > limit_deviation: return False - elif band2 > limit_deviation: + elif band2.all() > limit_deviation: return False if spin_polarized: - for matrix in self.band_overlaps_dict[Spin.down].values(): - for iband1, band1 in enumerate(matrix["matrix"]): + for matrix in self.band_overlaps_dict[Spin.down]["matrices"]: + for iband1, band1 in enumerate(matrix): for iband2, band2 in enumerate(band1): if number_occ_bands_spin_down is not None: if iband1 < number_occ_bands_spin_down and iband2 < number_occ_bands_spin_down: if iband1 == iband2: - if abs(band2 - 1.0) > limit_deviation: + if abs(band2 - 1.0).all() > limit_deviation: return False - elif band2 > limit_deviation: + elif band2.all() > limit_deviation: return False else: ValueError("number_occ_bands_spin_down has to be specified") diff --git a/tests/io/lobster/test_inputs.py b/tests/io/lobster/test_inputs.py index df536d2e77a..d106d68b96e 100644 --- a/tests/io/lobster/test_inputs.py +++ b/tests/io/lobster/test_inputs.py @@ -1956,21 +1956,17 @@ def setUp(self): def test_attributes(self): # bandoverlapsdict - assert self.bandoverlaps1.bandoverlapsdict[Spin.up]["0.5 0 0"]["maxDeviation"] == approx(0.000278953) - assert self.bandoverlaps1_new.bandoverlapsdict[Spin.up]["0 0 0"]["maxDeviation"] == approx(0.0640933) - assert self.bandoverlaps1.bandoverlapsdict[Spin.up]["0.5 0 0"]["matrix"][-1][-1] == approx(0.0188058) - assert self.bandoverlaps1_new.bandoverlapsdict[Spin.up]["0 0 0"]["matrix"][-1][-1] == approx(1.0) - assert self.bandoverlaps1.bandoverlapsdict[Spin.up]["0.5 0 0"]["matrix"][0][0] == approx(1) - assert self.bandoverlaps1_new.bandoverlapsdict[Spin.up]["0 0 0"]["matrix"][0][0] == approx(0.995849) - - assert self.bandoverlaps1.bandoverlapsdict[Spin.down]["0.0261194 0.0261194 0.473881"]["maxDeviation"] == approx( - 4.31567e-05 - ) - assert self.bandoverlaps1_new.bandoverlapsdict[Spin.down]["0 0 0"]["maxDeviation"] == approx(0.064369) - assert self.bandoverlaps1.bandoverlapsdict[Spin.down]["0.0261194 0.0261194 0.473881"]["matrix"][0][ - -1 - ] == approx(4.0066e-07) - assert self.bandoverlaps1_new.bandoverlapsdict[Spin.down]["0 0 0"]["matrix"][0][-1] == approx(1.37447e-09) + assert self.bandoverlaps1.bandoverlapsdict[Spin.up]["max_deviations"][0] == approx(0.000278953) + assert self.bandoverlaps1_new.bandoverlapsdict[Spin.up]["max_deviations"][10] == approx(0.0640933) + assert self.bandoverlaps1.bandoverlapsdict[Spin.up]["matrices"][0].item(-1, -1) == approx(0.0188058) + assert self.bandoverlaps1_new.bandoverlapsdict[Spin.up]["matrices"][10].item(-1, -1) == approx(1.0) + assert self.bandoverlaps1.bandoverlapsdict[Spin.up]["matrices"][0].item(0, 0) == approx(1) + assert self.bandoverlaps1_new.bandoverlapsdict[Spin.up]["matrices"][10].item(0, 0) == approx(0.995849) + + assert self.bandoverlaps1.bandoverlapsdict[Spin.down]["max_deviations"][-1] == approx(4.31567e-05) + assert self.bandoverlaps1_new.bandoverlapsdict[Spin.down]["max_deviations"][9] == approx(0.064369) + assert self.bandoverlaps1.bandoverlapsdict[Spin.down]["matrices"][-1].item(0, -1) == approx(4.0066e-07) + assert self.bandoverlaps1_new.bandoverlapsdict[Spin.down]["matrices"][9].item(0, -1) == approx(1.37447e-09) # maxDeviation assert self.bandoverlaps1.max_deviation[0] == approx(0.000278953) @@ -2001,13 +1997,13 @@ def test_has_good_quality(self): assert self.bandoverlaps1.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=3, number_occ_bands_spin_down=0, - limit_deviation=0.001, + limit_deviation=1, spin_polarized=True, ) assert self.bandoverlaps1_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=3, number_occ_bands_spin_down=0, - limit_deviation=0.01, + limit_deviation=1, spin_polarized=True, ) assert not self.bandoverlaps1.has_good_quality_check_occupied_bands( @@ -2071,8 +2067,7 @@ def test_has_good_quality(self): assert not self.bandoverlaps2_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=10, limit_deviation=0.0000001 ) - assert self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=1, limit_deviation=0.1) - assert self.bandoverlaps2_new.has_good_quality_check_occupied_bands( + assert not self.bandoverlaps2.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=1, limit_deviation=0.1 ) @@ -2082,16 +2077,13 @@ def test_has_good_quality(self): assert not self.bandoverlaps2_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=1, limit_deviation=1e-8 ) - assert self.bandoverlaps2.has_good_quality_check_occupied_bands( - number_occ_bands_spin_up=10, limit_deviation=0.1 - ) - assert self.bandoverlaps2_new.has_good_quality_check_occupied_bands( + assert self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=10, limit_deviation=1) + assert not self.bandoverlaps2_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=2, limit_deviation=0.1 ) - - assert self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=1, limit_deviation=0.1) + assert self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=1, limit_deviation=1) assert self.bandoverlaps2_new.has_good_quality_check_occupied_bands( - number_occ_bands_spin_up=1, limit_deviation=0.1 + number_occ_bands_spin_up=1, limit_deviation=2 ) def test_msonable(self): @@ -2101,6 +2093,11 @@ def test_msonable(self): for attr_name, attr_value in all_attributes.items(): assert getattr(bandoverlaps_from_dict, attr_name) == attr_value + def test_keys(self): + assert len(self.bandoverlaps1.band_overlaps_dict[Spin.up]["k_points"]) == 408 + assert len(self.bandoverlaps2.band_overlaps_dict[Spin.up]["max_deviations"]) == 2 + assert len(self.bandoverlaps1_new.band_overlaps_dict[Spin.down]["matrices"]) == 73 + class TestGrosspop(unittest.TestCase): def setUp(self): From dd2ffb12356c284e19bef496685d562f0a24139f Mon Sep 17 00:00:00 2001 From: naik-aakash Date: Thu, 14 Mar 2024 15:52:36 +0100 Subject: [PATCH 2/6] rewrite band_overlap_dict output format, update and add associated tests --- pymatgen/io/lobster/outputs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymatgen/io/lobster/outputs.py b/pymatgen/io/lobster/outputs.py index 3f534eefc1a..280a5b47cb2 100644 --- a/pymatgen/io/lobster/outputs.py +++ b/pymatgen/io/lobster/outputs.py @@ -1378,7 +1378,7 @@ def _read(self, contents: list, spin_numbers: list): self.band_overlaps_dict[spin]["max_deviations"].append(float(maxdev)) self.band_overlaps_dict[spin]["k_points"].append(kpoint_array) self.max_deviation.append(float(maxdev)) - overlaps = [np.ndarray] + overlaps = [] else: rows = [] From 5de8862ae64d9f10dc25e014dc34a8320e080a10 Mon Sep 17 00:00:00 2001 From: Janosh Riebesell Date: Thu, 14 Mar 2024 16:40:21 +0100 Subject: [PATCH 3/6] refactor --- pymatgen/io/lobster/outputs.py | 29 +++--- tests/io/lobster/test_inputs.py | 179 ++++++++++++++------------------ 2 files changed, 94 insertions(+), 114 deletions(-) diff --git a/pymatgen/io/lobster/outputs.py b/pymatgen/io/lobster/outputs.py index 280a5b47cb2..1c9a4052b0c 100644 --- a/pymatgen/io/lobster/outputs.py +++ b/pymatgen/io/lobster/outputs.py @@ -1326,9 +1326,11 @@ def __init__( """ Args: filename: filename of the "bandOverlaps.lobster" file. - band_overlaps_dict: A dictionary containing the band overlap data of the form: {spin: {"k_points" : list of - k-point array, "max_deviations":list of max deviations associated to each k-point, "matrices": list of the - overlap matrices associated with each k-point}. + band_overlaps_dict: A dictionary containing the band overlap data of the form: {spin: { + "k_points" : list of k-point array, + "max_deviations": list of max deviations associated with each k-point, + "matrices": list of the overlap matrices associated with each k-point + }}. max_deviation (list[float]): A list of floats describing the maximal deviation for each problematic k-point. """ self._filename = filename @@ -1363,7 +1365,7 @@ def _read(self, contents: list, spin_numbers: list): kpoint_array = [] for kpointel in kpoint: if kpointel not in ["at", "k-point", ""]: - kpoint_array.append(float(kpointel)) + kpoint_array += [float(kpointel)] elif "maxDeviation" in line: if spin not in self.band_overlaps_dict: @@ -1375,19 +1377,19 @@ def _read(self, contents: list, spin_numbers: list): if "matrices" not in self.band_overlaps_dict[spin]: self.band_overlaps_dict[spin]["matrices"] = [] maxdev = line.split(" ")[2] - self.band_overlaps_dict[spin]["max_deviations"].append(float(maxdev)) - self.band_overlaps_dict[spin]["k_points"].append(kpoint_array) - self.max_deviation.append(float(maxdev)) + self.band_overlaps_dict[spin]["max_deviations"] += [float(maxdev)] + self.band_overlaps_dict[spin]["k_points"] += [kpoint_array] + self.max_deviation += [float(maxdev)] overlaps = [] else: rows = [] for el in line.split(" "): if el != "": - rows.append(float(el)) - overlaps.append(rows) + rows += [float(el)] + overlaps += [rows] if len(overlaps) == len(rows): - self.band_overlaps_dict[spin]["matrices"].append(np.matrix(overlaps)) + self.band_overlaps_dict[spin]["matrices"] += [np.matrix(overlaps)] def has_good_quality_maxDeviation(self, limit_maxDeviation: float = 0.1) -> bool: """ @@ -1448,11 +1450,8 @@ def has_good_quality_check_occupied_bands( @property def bandoverlapsdict(self): - warnings.warn( - "`bandoverlapsdict` attribute is deprecated. Use `band_overlaps_dict` instead.", - DeprecationWarning, - stacklevel=2, - ) + msg = "`bandoverlapsdict` attribute is deprecated. Use `band_overlaps_dict` instead." + warnings.warn(msg, DeprecationWarning, stacklevel=2) return self.band_overlaps_dict diff --git a/tests/io/lobster/test_inputs.py b/tests/io/lobster/test_inputs.py index d106d68b96e..5ee9c2e9a54 100644 --- a/tests/io/lobster/test_inputs.py +++ b/tests/io/lobster/test_inputs.py @@ -946,18 +946,7 @@ def test_attributes(self): ] assert self.lobsterout_saveprojection.basis_functions == [ - [ - "3s", - "4s", - "3p_y", - "3p_z", - "3p_x", - "3d_xy", - "3d_yz", - "3d_z^2", - "3d_xz", - "3d_x^2-y^2", - ] + ["3s", "4s", "3p_y", "3p_z", "3p_x", "3d_xy", "3d_yz", "3d_z^2", "3d_xz", "3d_x^2-y^2"] ] assert self.lobsterout_saveprojection.basis_type == ["pbeVaspFit2015"] assert self.lobsterout_saveprojection.charge_spilling == [0.0268] @@ -999,18 +988,7 @@ def test_attributes(self): ] assert self.lobsterout_skipping_all.basis_functions == [ - [ - "3s", - "4s", - "3p_y", - "3p_z", - "3p_x", - "3d_xy", - "3d_yz", - "3d_z^2", - "3d_xz", - "3d_x^2-y^2", - ] + ["3s", "4s", "3p_y", "3p_z", "3p_x", "3d_xy", "3d_yz", "3d_z^2", "3d_xz", "3d_x^2-y^2"] ] assert self.lobsterout_skipping_all.basis_type == ["pbeVaspFit2015"] assert self.lobsterout_skipping_all.charge_spilling == [0.0268] @@ -1946,157 +1924,159 @@ def test_msonable_implementation(self): class TestBandoverlaps(unittest.TestCase): def setUp(self): - # test spin polarlized calc and non spinpolarized calc + # test spin-polarized calc and non spinpolarized calc - self.bandoverlaps1 = Bandoverlaps(f"{TEST_FILES_DIR}/cohp/bandOverlaps.lobster.1") - self.bandoverlaps2 = Bandoverlaps(f"{TEST_FILES_DIR}/cohp/bandOverlaps.lobster.2") + self.band_overlaps1 = Bandoverlaps(f"{TEST_FILES_DIR}/cohp/bandOverlaps.lobster.1") + self.band_overlaps2 = Bandoverlaps(f"{TEST_FILES_DIR}/cohp/bandOverlaps.lobster.2") - self.bandoverlaps1_new = Bandoverlaps(f"{TEST_FILES_DIR}/cohp/bandOverlaps.lobster.new.1") - self.bandoverlaps2_new = Bandoverlaps(f"{TEST_FILES_DIR}/cohp/bandOverlaps.lobster.new.2") + self.band_overlaps1_new = Bandoverlaps(f"{TEST_FILES_DIR}/cohp/bandOverlaps.lobster.new.1") + self.band_overlaps2_new = Bandoverlaps(f"{TEST_FILES_DIR}/cohp/bandOverlaps.lobster.new.2") def test_attributes(self): # bandoverlapsdict - assert self.bandoverlaps1.bandoverlapsdict[Spin.up]["max_deviations"][0] == approx(0.000278953) - assert self.bandoverlaps1_new.bandoverlapsdict[Spin.up]["max_deviations"][10] == approx(0.0640933) - assert self.bandoverlaps1.bandoverlapsdict[Spin.up]["matrices"][0].item(-1, -1) == approx(0.0188058) - assert self.bandoverlaps1_new.bandoverlapsdict[Spin.up]["matrices"][10].item(-1, -1) == approx(1.0) - assert self.bandoverlaps1.bandoverlapsdict[Spin.up]["matrices"][0].item(0, 0) == approx(1) - assert self.bandoverlaps1_new.bandoverlapsdict[Spin.up]["matrices"][10].item(0, 0) == approx(0.995849) - - assert self.bandoverlaps1.bandoverlapsdict[Spin.down]["max_deviations"][-1] == approx(4.31567e-05) - assert self.bandoverlaps1_new.bandoverlapsdict[Spin.down]["max_deviations"][9] == approx(0.064369) - assert self.bandoverlaps1.bandoverlapsdict[Spin.down]["matrices"][-1].item(0, -1) == approx(4.0066e-07) - assert self.bandoverlaps1_new.bandoverlapsdict[Spin.down]["matrices"][9].item(0, -1) == approx(1.37447e-09) + bo_dict = self.band_overlaps1.bandoverlapsdict + assert bo_dict[Spin.up]["max_deviations"][0] == approx(0.000278953) + assert self.band_overlaps1_new.bandoverlapsdict[Spin.up]["max_deviations"][10] == approx(0.0640933) + assert bo_dict[Spin.up]["matrices"][0].item(-1, -1) == approx(0.0188058) + assert self.band_overlaps1_new.bandoverlapsdict[Spin.up]["matrices"][10].item(-1, -1) == approx(1.0) + assert bo_dict[Spin.up]["matrices"][0].item(0, 0) == approx(1) + assert self.band_overlaps1_new.bandoverlapsdict[Spin.up]["matrices"][10].item(0, 0) == approx(0.995849) + + assert bo_dict[Spin.down]["max_deviations"][-1] == approx(4.31567e-05) + assert self.band_overlaps1_new.bandoverlapsdict[Spin.down]["max_deviations"][9] == approx(0.064369) + assert bo_dict[Spin.down]["matrices"][-1].item(0, -1) == approx(4.0066e-07) + assert self.band_overlaps1_new.bandoverlapsdict[Spin.down]["matrices"][9].item(0, -1) == approx(1.37447e-09) # maxDeviation - assert self.bandoverlaps1.max_deviation[0] == approx(0.000278953) - assert self.bandoverlaps1_new.max_deviation[0] == approx(0.39824) - assert self.bandoverlaps1.max_deviation[-1] == approx(4.31567e-05) - assert self.bandoverlaps1_new.max_deviation[-1] == approx(0.324898) + assert self.band_overlaps1.max_deviation[0] == approx(0.000278953) + assert self.band_overlaps1_new.max_deviation[0] == approx(0.39824) + assert self.band_overlaps1.max_deviation[-1] == approx(4.31567e-05) + assert self.band_overlaps1_new.max_deviation[-1] == approx(0.324898) - assert self.bandoverlaps2.max_deviation[0] == approx(0.000473319) - assert self.bandoverlaps2_new.max_deviation[0] == approx(0.403249) - assert self.bandoverlaps2.max_deviation[-1] == approx(1.48451e-05) - assert self.bandoverlaps2_new.max_deviation[-1] == approx(0.45154) + assert self.band_overlaps2.max_deviation[0] == approx(0.000473319) + assert self.band_overlaps2_new.max_deviation[0] == approx(0.403249) + assert self.band_overlaps2.max_deviation[-1] == approx(1.48451e-05) + assert self.band_overlaps2_new.max_deviation[-1] == approx(0.45154) def test_has_good_quality(self): - assert not self.bandoverlaps1.has_good_quality_maxDeviation(limit_maxDeviation=0.1) - assert not self.bandoverlaps1_new.has_good_quality_maxDeviation(limit_maxDeviation=0.1) - assert not self.bandoverlaps1.has_good_quality_check_occupied_bands( + assert not self.band_overlaps1.has_good_quality_maxDeviation(limit_maxDeviation=0.1) + assert not self.band_overlaps1_new.has_good_quality_maxDeviation(limit_maxDeviation=0.1) + assert not self.band_overlaps1.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=9, number_occ_bands_spin_down=5, limit_deviation=0.1, spin_polarized=True, ) - assert not self.bandoverlaps1_new.has_good_quality_check_occupied_bands( + assert not self.band_overlaps1_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=9, number_occ_bands_spin_down=5, limit_deviation=0.1, spin_polarized=True, ) - assert self.bandoverlaps1.has_good_quality_check_occupied_bands( + assert self.band_overlaps1.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=3, number_occ_bands_spin_down=0, limit_deviation=1, spin_polarized=True, ) - assert self.bandoverlaps1_new.has_good_quality_check_occupied_bands( + assert self.band_overlaps1_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=3, number_occ_bands_spin_down=0, limit_deviation=1, spin_polarized=True, ) - assert not self.bandoverlaps1.has_good_quality_check_occupied_bands( + assert not self.band_overlaps1.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=1, number_occ_bands_spin_down=1, limit_deviation=0.000001, spin_polarized=True, ) - assert not self.bandoverlaps1_new.has_good_quality_check_occupied_bands( + assert not self.band_overlaps1_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=1, number_occ_bands_spin_down=1, limit_deviation=0.000001, spin_polarized=True, ) - assert not self.bandoverlaps1.has_good_quality_check_occupied_bands( + assert not self.band_overlaps1.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=1, number_occ_bands_spin_down=0, limit_deviation=0.000001, spin_polarized=True, ) - assert not self.bandoverlaps1_new.has_good_quality_check_occupied_bands( + assert not self.band_overlaps1_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=1, number_occ_bands_spin_down=0, limit_deviation=0.000001, spin_polarized=True, ) - assert not self.bandoverlaps1.has_good_quality_check_occupied_bands( + assert not self.band_overlaps1.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=0, number_occ_bands_spin_down=1, limit_deviation=0.000001, spin_polarized=True, ) - assert not self.bandoverlaps1_new.has_good_quality_check_occupied_bands( + assert not self.band_overlaps1_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=0, number_occ_bands_spin_down=1, limit_deviation=0.000001, spin_polarized=True, ) - assert not self.bandoverlaps1.has_good_quality_check_occupied_bands( + assert not self.band_overlaps1.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=4, number_occ_bands_spin_down=4, limit_deviation=0.001, spin_polarized=True, ) - assert not self.bandoverlaps1_new.has_good_quality_check_occupied_bands( + assert not self.band_overlaps1_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=4, number_occ_bands_spin_down=4, limit_deviation=0.001, spin_polarized=True, ) - assert self.bandoverlaps1.has_good_quality_maxDeviation(limit_maxDeviation=100) - assert self.bandoverlaps1_new.has_good_quality_maxDeviation(limit_maxDeviation=100) - assert self.bandoverlaps2.has_good_quality_maxDeviation() - assert not self.bandoverlaps2_new.has_good_quality_maxDeviation() - assert not self.bandoverlaps2.has_good_quality_maxDeviation(limit_maxDeviation=0.0000001) - assert not self.bandoverlaps2_new.has_good_quality_maxDeviation(limit_maxDeviation=0.0000001) - assert not self.bandoverlaps2.has_good_quality_check_occupied_bands( + assert self.band_overlaps1.has_good_quality_maxDeviation(limit_maxDeviation=100) + assert self.band_overlaps1_new.has_good_quality_maxDeviation(limit_maxDeviation=100) + assert self.band_overlaps2.has_good_quality_maxDeviation() + assert not self.band_overlaps2_new.has_good_quality_maxDeviation() + assert not self.band_overlaps2.has_good_quality_maxDeviation(limit_maxDeviation=0.0000001) + assert not self.band_overlaps2_new.has_good_quality_maxDeviation(limit_maxDeviation=0.0000001) + assert not self.band_overlaps2.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=10, limit_deviation=0.0000001 ) - assert not self.bandoverlaps2_new.has_good_quality_check_occupied_bands( + assert not self.band_overlaps2_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=10, limit_deviation=0.0000001 ) - assert not self.bandoverlaps2.has_good_quality_check_occupied_bands( + assert not self.band_overlaps2.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=1, limit_deviation=0.1 ) - assert not self.bandoverlaps2.has_good_quality_check_occupied_bands( + assert not self.band_overlaps2.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=1, limit_deviation=1e-8 ) - assert not self.bandoverlaps2_new.has_good_quality_check_occupied_bands( + assert not self.band_overlaps2_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=1, limit_deviation=1e-8 ) - assert self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=10, limit_deviation=1) - assert not self.bandoverlaps2_new.has_good_quality_check_occupied_bands( + assert self.band_overlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=10, limit_deviation=1) + assert not self.band_overlaps2_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=2, limit_deviation=0.1 ) - assert self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=1, limit_deviation=1) - assert self.bandoverlaps2_new.has_good_quality_check_occupied_bands( + assert self.band_overlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=1, limit_deviation=1) + assert self.band_overlaps2_new.has_good_quality_check_occupied_bands( number_occ_bands_spin_up=1, limit_deviation=2 ) def test_msonable(self): - dict_data = self.bandoverlaps2_new.as_dict() + dict_data = self.band_overlaps2_new.as_dict() bandoverlaps_from_dict = Bandoverlaps.from_dict(dict_data) - all_attributes = vars(self.bandoverlaps2_new) + all_attributes = vars(self.band_overlaps2_new) for attr_name, attr_value in all_attributes.items(): assert getattr(bandoverlaps_from_dict, attr_name) == attr_value def test_keys(self): - assert len(self.bandoverlaps1.band_overlaps_dict[Spin.up]["k_points"]) == 408 - assert len(self.bandoverlaps2.band_overlaps_dict[Spin.up]["max_deviations"]) == 2 - assert len(self.bandoverlaps1_new.band_overlaps_dict[Spin.down]["matrices"]) == 73 + bo_dict = self.band_overlaps1.band_overlaps_dict + assert len(bo_dict[Spin.up]["k_points"]) == 408 + assert len(bo_dict[Spin.up]["max_deviations"]) == 2 + assert len(bo_dict[Spin.down]["matrices"]) == 73 class TestGrosspop(unittest.TestCase): @@ -2104,23 +2084,24 @@ def setUp(self): self.grosspop1 = Grosspop(f"{TEST_FILES_DIR}/cohp/GROSSPOP.lobster") def test_attributes(self): - assert self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["3s"] == approx(0.52) - assert self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["3p_y"] == approx(0.38) - assert self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["3p_z"] == approx(0.37) - assert self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["3p_x"] == approx(0.37) - assert self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["total"] == approx(1.64) - assert self.grosspop1.list_dict_grosspop[0]["element"] == "Si" - assert self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["3s"] == approx(0.61) - assert self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["3p_y"] == approx(0.52) - assert self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["3p_z"] == approx(0.52) - assert self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["3p_x"] == approx(0.52) - assert self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["total"] == approx(2.16) - assert self.grosspop1.list_dict_grosspop[5]["Mulliken GP"]["2s"] == approx(1.80) - assert self.grosspop1.list_dict_grosspop[5]["Loewdin GP"]["2s"] == approx(1.60) - assert self.grosspop1.list_dict_grosspop[5]["element"] == "O" - assert self.grosspop1.list_dict_grosspop[8]["Mulliken GP"]["2s"] == approx(1.80) - assert self.grosspop1.list_dict_grosspop[8]["Loewdin GP"]["2s"] == approx(1.60) - assert self.grosspop1.list_dict_grosspop[8]["element"] == "O" + gross_pop_list = self.grosspop1.list_dict_grosspop + assert gross_pop_list[0]["Mulliken GP"]["3s"] == approx(0.52) + assert gross_pop_list[0]["Mulliken GP"]["3p_y"] == approx(0.38) + assert gross_pop_list[0]["Mulliken GP"]["3p_z"] == approx(0.37) + assert gross_pop_list[0]["Mulliken GP"]["3p_x"] == approx(0.37) + assert gross_pop_list[0]["Mulliken GP"]["total"] == approx(1.64) + assert gross_pop_list[0]["element"] == "Si" + assert gross_pop_list[0]["Loewdin GP"]["3s"] == approx(0.61) + assert gross_pop_list[0]["Loewdin GP"]["3p_y"] == approx(0.52) + assert gross_pop_list[0]["Loewdin GP"]["3p_z"] == approx(0.52) + assert gross_pop_list[0]["Loewdin GP"]["3p_x"] == approx(0.52) + assert gross_pop_list[0]["Loewdin GP"]["total"] == approx(2.16) + assert gross_pop_list[5]["Mulliken GP"]["2s"] == approx(1.80) + assert gross_pop_list[5]["Loewdin GP"]["2s"] == approx(1.60) + assert gross_pop_list[5]["element"] == "O" + assert gross_pop_list[8]["Mulliken GP"]["2s"] == approx(1.80) + assert gross_pop_list[8]["Loewdin GP"]["2s"] == approx(1.60) + assert gross_pop_list[8]["element"] == "O" def test_structure_with_grosspop(self): struct_dict = { From b93fc2331a2a5f8e69483f318762599208642ab4 Mon Sep 17 00:00:00 2001 From: naik-aakash Date: Thu, 14 Mar 2024 17:06:42 +0100 Subject: [PATCH 4/6] fix failing test due to refactoring --- tests/io/lobster/test_inputs.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/io/lobster/test_inputs.py b/tests/io/lobster/test_inputs.py index 5ee9c2e9a54..5b4a4af73db 100644 --- a/tests/io/lobster/test_inputs.py +++ b/tests/io/lobster/test_inputs.py @@ -2074,9 +2074,11 @@ def test_msonable(self): def test_keys(self): bo_dict = self.band_overlaps1.band_overlaps_dict + bo_dict_new = self.band_overlaps1_new.band_overlaps_dict + bo_dict_2 = self.band_overlaps2.band_overlaps_dict assert len(bo_dict[Spin.up]["k_points"]) == 408 - assert len(bo_dict[Spin.up]["max_deviations"]) == 2 - assert len(bo_dict[Spin.down]["matrices"]) == 73 + assert len(bo_dict_2[Spin.up]["max_deviations"]) == 2 + assert len(bo_dict_new[Spin.down]["matrices"]) == 73 class TestGrosspop(unittest.TestCase): From 435376832067db74e7ea219df575a3e3353a7455 Mon Sep 17 00:00:00 2001 From: naik-aakash Date: Fri, 15 Mar 2024 11:29:01 +0100 Subject: [PATCH 5/6] address review comment and fix some pyright errors --- pymatgen/io/lobster/outputs.py | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/pymatgen/io/lobster/outputs.py b/pymatgen/io/lobster/outputs.py index 1c9a4052b0c..78a46b42865 100644 --- a/pymatgen/io/lobster/outputs.py +++ b/pymatgen/io/lobster/outputs.py @@ -124,6 +124,8 @@ def __init__(self, are_coops: bool = False, are_cobis: bool = False, filename: s # the labeling had to be changed: there are more than one COHP for each atom combination # this is done to make the labeling consistent with ICOHPLIST.lobster bond_num = 0 + bond_data = {} + label = "" for bond in range(num_bonds): bond_data = self._get_bond_data(contents[3 + bond]) @@ -305,6 +307,7 @@ def __init__( # include case when there is only one ICOHP!!! self.orbitalwise = len(data) > 2 and "_" in data[1].split()[1] + data_orbitals: list[str] = [] if self.orbitalwise: data_without_orbitals = [] data_orbitals = [] @@ -333,6 +336,14 @@ def __init__( list_num = [] list_icohp = [] + # initialize static variables + label = "" + atom1 = "" + atom2 = "" + length = None + num = None + translation = [] + for bond in range(num_bonds): line = data_without_orbitals[bond].split() icohp = {} @@ -446,7 +457,7 @@ def __init__(self, filename: str | None = "NcICOBILIST.lobster"): # LOBSTER < 4 # LOBSTER list files have an extra trailing blank line # and we don't need the header. - with zopen(filename, mode="rt") as file: + with zopen(filename, mode="rt") as file: # type:ignore data = file.read().split("\n")[1:-1] if len(data) == 0: raise OSError("NcICOBILIST file contains no data.") @@ -664,12 +675,12 @@ def energies(self) -> np.ndarray: return self._energies @property - def tdensities(self) -> np.ndarray: + def tdensities(self) -> dict[Spin, np.ndarray]: """total densities as a np.ndarray""" return self._tdensities @property - def itdensities(self) -> np.ndarray: + def itdensities(self) -> dict[Spin, np.ndarray]: """integrated total densities as a np.ndarray""" return self._itdensities @@ -841,7 +852,7 @@ def __init__(self, filename: str | None, **kwargs) -> None: else: raise ValueError(f"{attr}={val} is not a valid attribute for Lobsterout") else: - with zopen(filename, mode="rt") as file: # read in file + with zopen(self.filename, mode="rt") as file: # type:ignore # read in file data = file.read().split("\n") if len(data) == 0: raise OSError("lobsterout does not contain any data") @@ -1046,6 +1057,9 @@ def _get_elements_basistype_basisfunctions(data): def _get_timing(data): # will give back wall, user and sys time begin = False + user_time = [] + wall_time = [] + sys_time = [] # end=False # time=[] @@ -1247,6 +1261,7 @@ def __init__(self, filenames=".", vasprun="vasprun.xml", Kpointsfile="KPOINTS"): ] ikpoint = -1 + linenumber = 0 for line in contents[1:-1]: if line.split()[0] == "#": KPOINT = np.array( @@ -1299,7 +1314,7 @@ def get_bandstructure(self): kpoints=self.kpoints_array, eigenvals=self.eigenvals, lattice=self.lattice, - efermi=self.efermi, + efermi=self.efermi, # type: ignore labels_dict=self.label_dict, structure=self.structure, projections=self.p_eigenvals, @@ -1354,6 +1369,9 @@ def _read(self, contents: list, spin_numbers: list): contents: list of strings spin_numbers: list of spin numbers depending on `Lobster` version. """ + spin: Spin = Spin.up + kpoint_array: list = [] + overlaps: list = [] # This has to be done like this because there can be different numbers of problematic k-points per spin for line in contents: if f"Overlap Matrix (abs) of the orthonormalized projected bands for spin {spin_numbers[0]}" in line: @@ -1479,18 +1497,18 @@ def __init__(self, filename: str = "GROSSPOP.lobster", list_dict_grosspop: list[ # opens file self._filename = filename self.list_dict_grosspop = [] if list_dict_grosspop is None else list_dict_grosspop - if not self.list_dict_grosspop: with zopen(filename, mode="rt") as file: contents = file.read().split("\n") # transfers content of file to list of dict + small_dict: dict[str, Any] = {} for line in contents[3:]: cleanline = [i for i in line.split(" ") if i != ""] if len(cleanline) == 5: small_dict = {} - small_dict["element"] = cleanline[1] small_dict["Mulliken GP"] = {} small_dict["Loewdin GP"] = {} + small_dict["element"] = cleanline[1] small_dict["Mulliken GP"][cleanline[2]] = float(cleanline[3]) small_dict["Loewdin GP"][cleanline[2]] = float(cleanline[4]) elif len(cleanline) > 0: @@ -2015,6 +2033,8 @@ def _parse_matrix(file_data, pattern, e_fermi): end_inxs_imag.append(len(file_data)) # extract matrix data and store diagonal elements + matrix_real = [] + matrix_imag = [] for start_inx_real, end_inx_real, start_inx_imag, end_inx_imag in zip( start_inxs_real, end_inxs_real, start_inxs_imag, end_inxs_imag ): From 859d380db89545aea1d63e7f167ec2a3b4fde373 Mon Sep 17 00:00:00 2001 From: Janosh Riebesell Date: Fri, 15 Mar 2024 11:48:31 +0100 Subject: [PATCH 6/6] lst.append() -> concat --- pymatgen/io/lobster/outputs.py | 146 ++++++++++++++++----------------- 1 file changed, 71 insertions(+), 75 deletions(-) diff --git a/pymatgen/io/lobster/outputs.py b/pymatgen/io/lobster/outputs.py index 69694154c3d..81bf0db952c 100644 --- a/pymatgen/io/lobster/outputs.py +++ b/pymatgen/io/lobster/outputs.py @@ -313,9 +313,9 @@ def __init__( data_orbitals = [] for line in data: if "_" not in line.split()[1]: - data_without_orbitals.append(line) + data_without_orbitals += [line] else: - data_orbitals.append(line) + data_orbitals += [line] else: data_without_orbitals = data @@ -370,13 +370,13 @@ def __init__( if self.is_spin_polarized: icohp[Spin.down] = float(data_without_orbitals[bond + num_bonds + 1].split()[7]) - list_labels.append(label) - list_atom1.append(atom1) - list_atom2.append(atom2) - list_length.append(length) - list_translation.append(translation) - list_num.append(num) - list_icohp.append(icohp) + list_labels += [label] + list_atom1 += [atom1] + list_atom2 += [atom2] + list_length += [length] + list_translation += [translation] + list_num += [num] + list_icohp += [icohp] list_orb_icohp: list[dict] | None = None if self.orbitalwise: @@ -396,7 +396,7 @@ def __init__( icohp[Spin.down] = float(data_orbitals[num_orbs + i_data_orb].split()[7]) if len(list_orb_icohp) < int(label): - list_orb_icohp.append({orb_label: {"icohp": icohp, "orbitals": orbitals}}) + list_orb_icohp += [{orb_label: {"icohp": icohp, "orbitals": orbitals}}] else: list_orb_icohp[int(label) - 1][orb_label] = {"icohp": icohp, "orbitals": orbitals} @@ -420,16 +420,16 @@ def __init__( @property def icohplist(self) -> dict[Any, dict[str, Any]]: """Returns: icohplist compatible with older version of this class.""" - icohplist_new = {} + icohp_dict = {} for key, value in self._icohpcollection._icohplist.items(): - icohplist_new[key] = { + icohp_dict[key] = { "length": value._length, "number_of_bonds": value._num, "icohp": value._icohp, "translation": value._translation, "orbitals": value._orbitals, } - return icohplist_new + return icohp_dict @property def icohpcollection(self): @@ -482,7 +482,7 @@ def __init__(self, filename: str | None = "NcICOBILIST.lobster"): # LOBSTER < 4 data_without_orbitals = [] for line in data: if "_" not in str(line.split()[3:]) and "s]" not in str(line.split()[3:]): - data_without_orbitals.append(line) + data_without_orbitals += [line] else: data_without_orbitals = data @@ -513,11 +513,11 @@ def __init__(self, filename: str | None = "NcICOBILIST.lobster"): # LOBSTER < 4 if self.is_spin_polarized: ncicobi[Spin.down] = float(data_without_orbitals[bond + n_bonds + 1].split()[2]) - self.list_labels.append(label) - self.list_n_atoms.append(n_atoms) - self.list_ncicobi.append(ncicobi) - self.list_interaction_type.append(interaction_type) - self.list_num.append(num) + self.list_labels += [label] + self.list_n_atoms += [n_atoms] + self.list_ncicobi += [ncicobi] + self.list_interaction_type += [interaction_type] + self.list_num += [num] # TODO: add functions to get orbital resolved NcICOBIs @@ -592,14 +592,14 @@ def _parse_doscar(self): for _atom in range(natoms + 1): line = file.readline() ndos = int(line.split()[2]) - orbitals.append(line.split(";")[-1].split()) + orbitals += [line.split(";")[-1].split()] line = file.readline().split() cdos = np.zeros((ndos, len(line))) cdos[0] = np.array(line) for nd in range(1, ndos): line = file.readline().split() cdos[nd] = np.array(line) - dos.append(cdos) + dos += [cdos] doshere = np.array(dos[0]) if len(doshere[0, :]) == 5: self._is_spin_polarized = True @@ -622,7 +622,7 @@ def _parse_doscar(self): orb = orbitals[atom + 1][orbnumber] pdos[orb][spin] = data[:, j] orbnumber = orbnumber + 1 - pdoss.append(pdos) + pdoss += [pdos] else: tdensities[Spin.up] = doshere[:, 1] tdensities[Spin.down] = doshere[:, 2] @@ -640,7 +640,7 @@ def _parse_doscar(self): pdos[orb][spin] = data[:, j] if j % 2 == 0: orbnumber = orbnumber + 1 - pdoss.append(pdos) + pdoss += [pdos] self._efermi = efermi self._pdos = pdoss @@ -736,10 +736,10 @@ def __init__( self.num_atoms = len(data) for atom in range(self.num_atoms): line = data[atom].split() - self.atomlist.append(line[1] + line[0]) - self.types.append(line[1]) - self.mulliken.append(float(line[2])) - self.loewdin.append(float(line[3])) + self.atomlist += [line[1] + line[0]] + self.types += [line[1]] + self.mulliken += [float(line[2])] + self.loewdin += [float(line[3])] def get_structure_with_charges(self, structure_filename): """ @@ -1015,9 +1015,9 @@ def _get_spillings(data, number_of_spins): splitrow = row.split() if len(splitrow) > 2 and splitrow[2] == "spilling:": if splitrow[1] == "charge": - charge_spilling.append(np.float64(splitrow[3].replace("%", "")) / 100.0) + charge_spilling += [np.float64(splitrow[3].replace("%", "")) / 100.0] if splitrow[1] == "total": - total_spilling.append(np.float64(splitrow[3].replace("%", "")) / 100.0) + total_spilling += [np.float64(splitrow[3].replace("%", "")) / 100.0] if len(charge_spilling) == number_of_spins and len(total_spilling) == number_of_spins: break @@ -1044,10 +1044,10 @@ def _get_elements_basistype_basisfunctions(data): "spillings", "writing", ]: - elements.append(splitrow[0]) - basistype.append(splitrow[1].replace("(", "").replace(")", "")) + elements += [splitrow[0]] + basistype += [splitrow[1].replace("(", "").replace(")", "")] # last sign is a '' - basisfunctions.append(splitrow[2:]) + basisfunctions += [splitrow[2:]] else: end = True if "setting up local basis functions..." in row: @@ -1058,11 +1058,7 @@ def _get_elements_basistype_basisfunctions(data): def _get_timing(data): # will give back wall, user and sys time begin = False - user_time = [] - wall_time = [] - sys_time = [] - # end=False - # time=[] + user_time, wall_time, sys_time = [], [], [] for row in data: splitrow = row.split() @@ -1088,7 +1084,7 @@ def _get_warning_orthonormalization(data): for row in data: splitrow = row.split() if "orthonormalized" in splitrow: - orthowarning.append(" ".join(splitrow[1:])) + orthowarning += [" ".join(splitrow[1:])] return orthowarning @staticmethod @@ -1097,7 +1093,7 @@ def _get_all_warning_lines(data): for row in data: splitrow = row.split() if len(splitrow) > 0 and splitrow[0] == "WARNING:": - ws.append(" ".join(splitrow[1:])) + ws += [" ".join(splitrow[1:])] return ws @staticmethod @@ -1106,7 +1102,7 @@ def _get_all_info_lines(data): for row in data: splitrow = row.split() if len(splitrow) > 0 and splitrow[0] == "INFO:": - infos.append(" ".join(splitrow[1:])) + infos += [" ".join(splitrow[1:])] return infos @@ -1189,7 +1185,7 @@ def __init__( filenames = "." for name in os.listdir(filenames): if fnmatch.fnmatch(name, "FATBAND_*.lobster"): - filenames_new.append(os.path.join(filenames, name)) + filenames_new += [os.path.join(filenames, name)] filenames = filenames_new if len(filenames) == 0: raise ValueError("No FATBAND files in folder or given") @@ -1197,17 +1193,17 @@ def __init__( with zopen(name, mode="rt") as file: contents = file.read().split("\n") - atom_names.append(os.path.split(name)[1].split("_")[1].capitalize()) + atom_names += [os.path.split(name)[1].split("_")[1].capitalize()] parameters = contents[0].split() - atom_type.append(re.split(r"[0-9]+", parameters[3])[0].capitalize()) - orbital_names.append(parameters[4]) + atom_type += [re.split(r"[0-9]+", parameters[3])[0].capitalize()] + orbital_names += [parameters[4]] # get atomtype orbital dict atom_orbital_dict = {} # type: dict for iatom, atom in enumerate(atom_names): if atom not in atom_orbital_dict: atom_orbital_dict[atom] = [] - atom_orbital_dict[atom].append(orbital_names[iatom]) + atom_orbital_dict[atom] += [orbital_names[iatom]] # test if there are the same orbitals twice or if two different formats were used or if all necessary orbitals # are there for items in atom_orbital_dict.values(): @@ -1215,7 +1211,7 @@ def __init__( raise ValueError("The are two FATBAND files for the same atom and orbital. The program will stop.") split = [] for item in items: - split.append(item.split("_")[0]) + split += [item.split("_")[0]] for number in collections.Counter(split).values(): if number not in (1, 3, 5, 7): raise ValueError( @@ -1240,7 +1236,7 @@ def __init__( linenumbers = [] for iline, line in enumerate(contents[1 : self.nbands * 2 + 4]): if line.split()[0] == "#": - linenumbers.append(iline) + linenumbers += [iline] if ifilename == 0: self.is_spinpolarized = len(linenumbers) == 2 @@ -1291,7 +1287,7 @@ def __init__( ] ) if ifilename == 0: - kpoints_array.append(KPOINT) + kpoints_array += [KPOINT] linenumber = 0 iband = 0 @@ -1534,7 +1530,7 @@ def __init__(self, filename: str = "GROSSPOP.lobster", list_dict_grosspop: list[ small_dict["Mulliken GP"][cleanline[0]] = float(cleanline[1]) small_dict["Loewdin GP"][cleanline[0]] = float(cleanline[2]) if "total" in cleanline[0]: - self.list_dict_grosspop.append(small_dict) + self.list_dict_grosspop += [small_dict] def get_structure_with_total_grosspop(self, structure_filename: str) -> Structure: """ @@ -1551,8 +1547,8 @@ def get_structure_with_total_grosspop(self, structure_filename: str) -> Structur mullikengp = [] loewdingp = [] for grosspop in self.list_dict_grosspop: - mullikengp.append(grosspop["Mulliken GP"]["total"]) - loewdingp.append(grosspop["Loewdin GP"]["total"]) + mullikengp += [grosspop["Mulliken GP"]["total"]] + loewdingp += [grosspop["Loewdin GP"]["total"]] site_properties = { "Total Mulliken GP": mullikengp, @@ -1596,10 +1592,10 @@ def _parse_file(filename): for line in contents[1:]: splitline = line.split() if len(splitline) >= 6: - points.append([float(splitline[0]), float(splitline[1]), float(splitline[2])]) - distance.append(float(splitline[3])) - real.append(float(splitline[4])) - imaginary.append(float(splitline[5])) + points += [[float(splitline[0]), float(splitline[1]), float(splitline[2])]] + distance += [float(splitline[3])] + real += [float(splitline[4])] + imaginary += [float(splitline[5])] if not len(real) == grid[0] * grid[1] * grid[2]: raise ValueError("Something went wrong while reading the file") @@ -1649,13 +1645,13 @@ def set_volumetric_data(self, grid, structure): "coordinates 0.0 0.0 0.0 coordinates 1.0 1.0 1.0 box bandlist 1 " ) - new_x.append(x_here) - new_y.append(y_here) - new_z.append(z_here) + new_x += [x_here] + new_y += [y_here] + new_z += [z_here] - new_real.append(self.real[runner]) - new_imaginary.append(self.imaginary[runner]) - new_density.append(self.real[runner] ** 2 + self.imaginary[runner] ** 2) + new_real += [self.real[runner]] + new_imaginary += [self.imaginary[runner]] + new_density += [self.real[runner] ** 2 + self.imaginary[runner] ** 2] runner += 1 @@ -1848,10 +1844,10 @@ def __init__( self.num_atoms = len(data) - 2 for atom in range(self.num_atoms): line = data[atom].split() - self.atomlist.append(line[1] + str(line[0])) - self.types.append(line[1]) - self.sitepotentials_mulliken.append(float(line[2])) - self.sitepotentials_loewdin.append(float(line[3])) + self.atomlist += [line[1] + str(line[0])] + self.types += [line[1]] + self.sitepotentials_mulliken += [float(line[2])] + self.sitepotentials_loewdin += [float(line[3])] self.madelungenergies_mulliken = float(data[self.num_atoms + 1].split()[3]) self.madelungenergies_loewdin = float(data[self.num_atoms + 1].split()[4]) @@ -2032,24 +2028,24 @@ def _parse_matrix(file_data, pattern, e_fermi): start_inxs_imag = [] end_inxs_imag = [] # get indices of real and imaginary part of matrix for each k point - for i, line in enumerate(file_data): + for idx, line in enumerate(file_data): line = line.strip() if "Real parts" in line: - start_inxs_real.append(i + 1) - if i == 1: # ignore the first occurrence as files start with real matrices + start_inxs_real += [idx + 1] + if idx == 1: # ignore the first occurrence as files start with real matrices pass else: - end_inxs_imag.append(i - 1) - matches = re.search(pattern, file_data[i - 1]) + end_inxs_imag += [idx - 1] + matches = re.search(pattern, file_data[idx - 1]) if matches and len(matches.groups()) == 2: k_point = matches.group(2) complex_matrices[k_point] = {} if "Imag parts" in line: - end_inxs_real.append(i - 1) - start_inxs_imag.append(i + 1) + end_inxs_real += [idx - 1] + start_inxs_imag += [idx + 1] # explicitly add the last line as files end with imaginary matrix - if i == len(file_data) - 1: - end_inxs_imag.append(len(file_data)) + if idx == len(file_data) - 1: + end_inxs_imag += [len(file_data)] # extract matrix data and store diagonal elements matrix_real = [] @@ -2076,7 +2072,7 @@ def _parse_matrix(file_data, pattern, e_fermi): elif matches and len(matches.groups()) == 1: k_point = matches.group(1) complex_matrices.update({k_point: comp_matrix}) - matrix_diagonal_values.append(comp_matrix.real.diagonal() - e_fermi) + matrix_diagonal_values += [comp_matrix.real.diagonal() - e_fermi] # extract elements basis functions as list elements_basis_functions = [