From 177a7a9085fb4cedde8f5946e7e31738875ece75 Mon Sep 17 00:00:00 2001 From: anaik Date: Mon, 5 Dec 2022 18:09:09 +0100 Subject: [PATCH 01/28] added dos_fingerprint and similarity index methods --- pymatgen/electronic_structure/dos.py | 134 +++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index aa0fc38fde7..aca0a949762 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -10,7 +10,9 @@ import functools import warnings from typing import Mapping +from collections import namedtuple +import re import numpy as np from monty.json import MSONable from scipy.constants import value as _cd @@ -1165,6 +1167,138 @@ def get_upper_band_edge( upper_band_edge = energies[np.argmax(densities)] return upper_band_edge + + def get_dos_fp(self, type='summed_pdos', binning=True, min_e=None, max_e=None, nbins=256, normalize=True): + """ + Generates the DOS fingerprint based on work of F. Knoop, T. A. r Purcell, M. Scheffler, C. Carbogno, J. Open Source Softw. 2020, 5, 2671. + + Args: + type (str): Fingerprint type needed can accept 's,p,d,f,summed_pdos,tdos' + min_e (float): The minimum mode energy to include in the fingerprint + max_e (float): The maximum mode energy to include in the fingerprint + nbins (int): Number of bins to be used in the fingerprint + + Returns: + Fingerprint(namedtuple) : The electronic density of states fingerprint of format (energies, densities, DOS, nbins) + """ + fp_tup = namedtuple("fingerprint", "energies states type nbins") + energies = self.energies + if max_e is None: + max_e = np.max(energies) + + if min_e is None: + min_e = np.min(energies) + + pdos_obj=self.get_spd_dos() + pdos= {} + for k, v in pdos_obj.items(): + #er = spd_dos_lobster[k].energies + dens = pdos_obj[k].get_densities() + + pdos.update({k.name: dens}) + + sum_pdos_array = [] + for dos in pdos.values(): + sum_pdos_array.append(np.array(dos)) + + pdos.update({"summed_pdos":np.sum(sum_pdos_array, axis=0)}) + pdos.update({"tdos": self.get_densities()}) + + energies=self.energies + + try: + densities=pdos[type] + if len(energies) < nbins: + inds = np.where((energies >= min_e) & (energies <= max_e)) + return fp_tup(energies[inds], densities[inds], [type], len(energies)) + + if binning: + enerBounds = np.linspace(min_e, max_e, nbins + 1) + ener = enerBounds[:-1] + (enerBounds[1] - enerBounds[0]) / 2.0 + else: + enerBounds = np.array(energies) + ener = np.append(energies, [energies[-1] + np.abs(energies[-1]) / 10]) + + dos_rebin = np.zeros(ener.shape) + + for ii, e1, e2 in zip(range(len(ener)), enerBounds[0:-1], enerBounds[1:]): + inds = np.where((energies >= e1) & (energies < e2))[0] + dos_rebin[ii] = np.sum( + densities[inds] + ) + if normalize: # scaling dos bins to make area under histogram equal 1 + bin_width = np.diff(ener)[0] + area = np.sum(dos_rebin * bin_width) + dos_rebin_sc = dos_rebin / area + else: + dos_rebin_sc = dos_rebin + return fp_tup(np.array([ener]), dos_rebin_sc, [type], nbins) # replaced here dos_rebin + except KeyError: + print('Please recheck type requested, either the orbital projections unavailable in input dos or' + 'some typo has been made.') + + + def fp_to_dict(self, fp): + """Converts a fingerprint into a dictionary + + Args: + fp: The DOS fingerprint to be converted into a dictionary + + Returns: + dict: A dict of the fingerprint Keys=labels, Values=np.ndarray(frequencies, #of states) + """ + fp_dict = {} + if len(fp[2]) > 1: + for aa in range(len(fp[2])): + fp_dict[re.sub("[.]", "_", str(fp[2][aa]))] = np.array( + [fp[0][aa], fp[1][aa]] + ).T + else: + fp_dict[re.sub("[.]", "_", str(fp[2][0]))] = np.array([fp[0], fp[1]]).T + + return fp_dict + + def get_dos_fp_similarity(self, fp1, fp2, col=0, pt="All", normalize=False, tanimoto=False): + """Calculates the similarity index (dot product) of two finger prints + + Args: + fp1 (get_dos_fp): The 1st dos fingerprint + fp2 get_dos_fp: The 2nd dos fingerprint + col (int): The item in the fingerprints to take the dot product of (either 0 or 1) + pt (int or 'All') : The index of the point that the dot product is to be taken + normalize (bool): If True normalize the scalar product to 1 + + Returns: + Similarity index (float): The value dot product + """ + if not isinstance(fp1, dict): + fp1_dict = self.fp_to_dict(fp1) + else: + fp1_dict = fp1 + + if not isinstance(fp2, dict): + fp2_dict = self.fp_to_dict(fp2) + else: + fp2_dict = fp2 + + if pt == "All": + vec1 = np.array([pt[col] for pt in fp1_dict.values()]).flatten() + vec2 = np.array([pt[col] for pt in fp2_dict.values()]).flatten() + else: + vec1 = fp1_dict[fp1[2][pt]][col] + vec2 = fp2_dict[fp2[2][pt]][col] + + rescale = 1.0 + + if tanimoto: + rescale = ( + np.linalg.norm(vec1) ** 2 + np.linalg.norm(vec2) ** 2 - np.dot(vec1, vec2) + ) + elif normalize: + rescale = np.linalg.norm(vec1) * np.linalg.norm(vec2) + + return np.dot(vec1, vec2) / rescale + @classmethod def from_dict(cls, d) -> CompleteDos: """ From e9669d1c347af41e31cf7dbde29d7b9c5bb25974 Mon Sep 17 00:00:00 2001 From: anaik Date: Mon, 5 Dec 2022 23:02:48 +0100 Subject: [PATCH 02/28] Added test cases and reformatted and cleaned code --- pymatgen/electronic_structure/dos.py | 83 ++++++++++--------- .../electronic_structure/tests/test_dos.py | 47 +++++++++++ 2 files changed, 90 insertions(+), 40 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index aca0a949762..c7bdb463f32 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -12,7 +12,6 @@ from typing import Mapping from collections import namedtuple -import re import numpy as np from monty.json import MSONable from scipy.constants import value as _cd @@ -1167,32 +1166,33 @@ def get_upper_band_edge( upper_band_edge = energies[np.argmax(densities)] return upper_band_edge - - def get_dos_fp(self, type='summed_pdos', binning=True, min_e=None, max_e=None, nbins=256, normalize=True): + def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, nbins=256, normalize=True): """ Generates the DOS fingerprint based on work of F. Knoop, T. A. r Purcell, M. Scheffler, C. Carbogno, J. Open Source Softw. 2020, 5, 2671. Args: - type (str): Fingerprint type needed can accept 's,p,d,f,summed_pdos,tdos' + type (str): Specify fingerprint type needed can accept 's/p/d/f/summed_pdos/tdos' min_e (float): The minimum mode energy to include in the fingerprint max_e (float): The maximum mode energy to include in the fingerprint nbins (int): Number of bins to be used in the fingerprint + normalize (bool): If true, normalizes the area under fp to equal to 1 Returns: - Fingerprint(namedtuple) : The electronic density of states fingerprint of format (energies, densities, DOS, nbins) + Fingerprint(namedtuple) : The electronic density of states fingerprint of format (energies, densities, type, nbins) """ fp_tup = namedtuple("fingerprint", "energies states type nbins") - energies = self.energies + energies = self.energies - self.efermi + if max_e is None: max_e = np.max(energies) if min_e is None: min_e = np.min(energies) - pdos_obj=self.get_spd_dos() - pdos= {} + pdos_obj = self.get_spd_dos() + + pdos = {} for k, v in pdos_obj.items(): - #er = spd_dos_lobster[k].energies dens = pdos_obj[k].get_densities() pdos.update({k.name: dens}) @@ -1201,16 +1201,15 @@ def get_dos_fp(self, type='summed_pdos', binning=True, min_e=None, max_e=None, n for dos in pdos.values(): sum_pdos_array.append(np.array(dos)) - pdos.update({"summed_pdos":np.sum(sum_pdos_array, axis=0)}) + pdos.update({"summed_pdos": np.sum(sum_pdos_array, axis=0)}) pdos.update({"tdos": self.get_densities()}) - energies=self.energies - try: - densities=pdos[type] + + densities = pdos[type] if len(energies) < nbins: inds = np.where((energies >= min_e) & (energies <= max_e)) - return fp_tup(energies[inds], densities[inds], [type], len(energies)) + return fp_tup(energies[inds], densities[inds], type, len(energies)) if binning: enerBounds = np.linspace(min_e, max_e, nbins + 1) @@ -1218,43 +1217,39 @@ def get_dos_fp(self, type='summed_pdos', binning=True, min_e=None, max_e=None, n else: enerBounds = np.array(energies) ener = np.append(energies, [energies[-1] + np.abs(energies[-1]) / 10]) + nbins = len(energies) dos_rebin = np.zeros(ener.shape) for ii, e1, e2 in zip(range(len(ener)), enerBounds[0:-1], enerBounds[1:]): inds = np.where((energies >= e1) & (energies < e2))[0] - dos_rebin[ii] = np.sum( - densities[inds] - ) - if normalize: # scaling dos bins to make area under histogram equal 1 + dos_rebin[ii] = np.sum(densities[inds]) + if normalize: # scale dos bins to make area under histogram equal 1 bin_width = np.diff(ener)[0] area = np.sum(dos_rebin * bin_width) dos_rebin_sc = dos_rebin / area else: dos_rebin_sc = dos_rebin - return fp_tup(np.array([ener]), dos_rebin_sc, [type], nbins) # replaced here dos_rebin - except KeyError: - print('Please recheck type requested, either the orbital projections unavailable in input dos or' - 'some typo has been made.') + return fp_tup(np.array([ener]), dos_rebin_sc, type, nbins) - def fp_to_dict(self, fp): + except KeyError: + raise ValueError( + "Please recheck type requested, either the orbital projections unavailable in input dos or " + "some typo has been made." + ) + + def _fp_to_dict(self, fp): """Converts a fingerprint into a dictionary Args: fp: The DOS fingerprint to be converted into a dictionary Returns: - dict: A dict of the fingerprint Keys=labels, Values=np.ndarray(frequencies, #of states) + dict: A dict of the fingerprint Keys=type, Values=np.ndarray(energies, states) """ fp_dict = {} - if len(fp[2]) > 1: - for aa in range(len(fp[2])): - fp_dict[re.sub("[.]", "_", str(fp[2][aa]))] = np.array( - [fp[0][aa], fp[1][aa]] - ).T - else: - fp_dict[re.sub("[.]", "_", str(fp[2][0]))] = np.array([fp[0], fp[1]]).T + fp_dict[fp[2]] = np.array([fp[0], fp[1]]).T return fp_dict @@ -1267,17 +1262,18 @@ def get_dos_fp_similarity(self, fp1, fp2, col=0, pt="All", normalize=False, tani col (int): The item in the fingerprints to take the dot product of (either 0 or 1) pt (int or 'All') : The index of the point that the dot product is to be taken normalize (bool): If True normalize the scalar product to 1 + tanimoto (bool): If True will compute tanimoto index Returns: Similarity index (float): The value dot product """ if not isinstance(fp1, dict): - fp1_dict = self.fp_to_dict(fp1) + fp1_dict = self._fp_to_dict(fp1) else: fp1_dict = fp1 if not isinstance(fp2, dict): - fp2_dict = self.fp_to_dict(fp2) + fp2_dict = self._fp_to_dict(fp2) else: fp2_dict = fp2 @@ -1288,16 +1284,23 @@ def get_dos_fp_similarity(self, fp1, fp2, col=0, pt="All", normalize=False, tani vec1 = fp1_dict[fp1[2][pt]][col] vec2 = fp2_dict[fp2[2][pt]][col] - rescale = 1.0 + if not normalize and tanimoto: + rescale = np.linalg.norm(vec1) ** 2 + np.linalg.norm(vec2) ** 2 - np.dot(vec1, vec2) + return np.dot(vec1, vec2) / rescale - if tanimoto: - rescale = ( - np.linalg.norm(vec1) ** 2 + np.linalg.norm(vec2) ** 2 - np.dot(vec1, vec2) - ) - elif normalize: + elif not tanimoto and normalize: rescale = np.linalg.norm(vec1) * np.linalg.norm(vec2) + return np.dot(vec1, vec2) / rescale + + elif not tanimoto and not normalize: + rescale = 1.0 + return np.dot(vec1, vec2) / rescale - return np.dot(vec1, vec2) / rescale + else: + raise ValueError( + "Cannot compute similarity index, Please set either one of normalize/tanimoto arg to true " + "or set both to false" + ) @classmethod def from_dict(cls, d) -> CompleteDos: diff --git a/pymatgen/electronic_structure/tests/test_dos.py b/pymatgen/electronic_structure/tests/test_dos.py index b39b077bfb9..b4044e6ad99 100644 --- a/pymatgen/electronic_structure/tests/test_dos.py +++ b/pymatgen/electronic_structure/tests/test_dos.py @@ -257,6 +257,53 @@ def test_kurtosis(self): kurtosis = dos.get_band_kurtosis() self.assertAlmostEqual(kurtosis, 7.764506941340621) + def test_get_dos_fp(self): + # normalize=True + dos_fp = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=True) + bin_width = np.diff(dos_fp.energies)[0][0] + self.assertLessEqual(max(dos_fp.energies[0]), 0) + self.assertGreaterEqual(min(dos_fp.energies[0]), -10) + self.assertEqual(len(dos_fp.energies[0]), 56) + self.assertEqual(dos_fp.type, "s") + self.assertAlmostEqual(sum(dos_fp.states * bin_width), 1, delta=0.001) + # normalize=False + dos_fp2 = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=False) + bin_width2 = np.diff(dos_fp2.energies)[0][0] + self.assertAlmostEqual(sum(dos_fp2.states * bin_width2), 7.279303571428509, delta=0.001) + # binning=False + dos_fp = self.dos.get_dos_fp(type="s", min_e=None, max_e=None, nbins=56, normalize=True, binning=False) + self.assertEqual(dos_fp.nbins, len(self.dos.energies)) + + def test_get_dos_fp_similarity(self): + dos_fp = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=True) + dos_fp2 = self.dos.get_dos_fp(type="tdos", min_e=-10, max_e=0, nbins=56, normalize=True) + similarity_index = self.dos.get_dos_fp_similarity(dos_fp, dos_fp2, col=1, tanimoto=True) + self.assertAlmostEqual(similarity_index, 0.3342481451042263, delta=0.0001) + + dos_fp = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=True) + dos_fp2 = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=True) + similarity_index = self.dos.get_dos_fp_similarity(dos_fp, dos_fp2, col=1, tanimoto=True) + self.assertEqual(similarity_index, 1) + + def test_dos_fp_exceptions(self): + dos_fp = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=True) + dos_fp2 = self.dos.get_dos_fp(type="tdos", min_e=-10, max_e=0, nbins=56, normalize=True) + # test exceptions + with self.assertRaises(ValueError) as err: + + self.dos.get_dos_fp_similarity(dos_fp, dos_fp2, col=1, tanimoto=True, normalize=True) + self.assertEqual( + err.exception.__str__(), + "Cannot compute similarity index, Please set either one of normalize/tanimoto arg to true or set both to false", + ) + with self.assertRaises(ValueError) as err: + + self.dos.get_dos_fp(type="k", min_e=-10, max_e=0, nbins=56, normalize=True) + self.assertEqual( + err.exception.__str__(), + "Please recheck type requested, either the orbital projections unavailable in input dos or some typo has been made.", + ) + class DOSTest(PymatgenTest): def setUp(self): From 6a52d42b9d6dc03410b132f3401664e7266655b9 Mon Sep 17 00:00:00 2001 From: anaik Date: Tue, 6 Dec 2022 09:27:31 +0100 Subject: [PATCH 03/28] added binwidth ,renamed states to densities in fp obj,updated tests --- pymatgen/electronic_structure/dos.py | 14 ++++++++------ pymatgen/electronic_structure/tests/test_dos.py | 5 +++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index c7bdb463f32..43c9c4d2e39 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1180,7 +1180,7 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n Returns: Fingerprint(namedtuple) : The electronic density of states fingerprint of format (energies, densities, type, nbins) """ - fp_tup = namedtuple("fingerprint", "energies states type nbins") + fp_tup = namedtuple("fingerprint", "energies densities type nbins binwidth") energies = self.energies - self.efermi if max_e is None: @@ -1209,15 +1209,17 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n densities = pdos[type] if len(energies) < nbins: inds = np.where((energies >= min_e) & (energies <= max_e)) - return fp_tup(energies[inds], densities[inds], type, len(energies)) + return fp_tup(energies[inds], densities[inds], type, len(energies),np.diff(energies)[0]) if binning: enerBounds = np.linspace(min_e, max_e, nbins + 1) ener = enerBounds[:-1] + (enerBounds[1] - enerBounds[0]) / 2.0 + bin_width = np.diff(ener)[0] else: enerBounds = np.array(energies) ener = np.append(energies, [energies[-1] + np.abs(energies[-1]) / 10]) nbins = len(energies) + bin_width = np.diff(energies)[0] dos_rebin = np.zeros(ener.shape) @@ -1225,13 +1227,13 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n inds = np.where((energies >= e1) & (energies < e2))[0] dos_rebin[ii] = np.sum(densities[inds]) if normalize: # scale dos bins to make area under histogram equal 1 - bin_width = np.diff(ener)[0] + #bin_width = np.diff(ener)[0] area = np.sum(dos_rebin * bin_width) dos_rebin_sc = dos_rebin / area else: dos_rebin_sc = dos_rebin - return fp_tup(np.array([ener]), dos_rebin_sc, type, nbins) + return fp_tup(np.array([ener]), dos_rebin_sc, type, nbins, bin_width) except KeyError: raise ValueError( @@ -1253,13 +1255,13 @@ def _fp_to_dict(self, fp): return fp_dict - def get_dos_fp_similarity(self, fp1, fp2, col=0, pt="All", normalize=False, tanimoto=False): + def get_dos_fp_similarity(self, fp1, fp2, col=1, pt="All", normalize=False, tanimoto=False): """Calculates the similarity index (dot product) of two finger prints Args: fp1 (get_dos_fp): The 1st dos fingerprint fp2 get_dos_fp: The 2nd dos fingerprint - col (int): The item in the fingerprints to take the dot product of (either 0 or 1) + col (int): The item in the fingerprints to take the dot product of (0=Energies 1=Densities) pt (int or 'All') : The index of the point that the dot product is to be taken normalize (bool): If True normalize the scalar product to 1 tanimoto (bool): If True will compute tanimoto index diff --git a/pymatgen/electronic_structure/tests/test_dos.py b/pymatgen/electronic_structure/tests/test_dos.py index b4044e6ad99..fa699fe17d2 100644 --- a/pymatgen/electronic_structure/tests/test_dos.py +++ b/pymatgen/electronic_structure/tests/test_dos.py @@ -265,11 +265,12 @@ def test_get_dos_fp(self): self.assertGreaterEqual(min(dos_fp.energies[0]), -10) self.assertEqual(len(dos_fp.energies[0]), 56) self.assertEqual(dos_fp.type, "s") - self.assertAlmostEqual(sum(dos_fp.states * bin_width), 1, delta=0.001) + self.assertAlmostEqual(sum(dos_fp.densities * bin_width), 1, delta=0.001) # normalize=False dos_fp2 = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=False) bin_width2 = np.diff(dos_fp2.energies)[0][0] - self.assertAlmostEqual(sum(dos_fp2.states * bin_width2), 7.279303571428509, delta=0.001) + self.assertAlmostEqual(sum(dos_fp2.densities * bin_width2), 7.279303571428509, delta=0.001) + self.assertAlmostEqual(dos_fp2.binwidth , bin_width2, delta=0.001) # binning=False dos_fp = self.dos.get_dos_fp(type="s", min_e=None, max_e=None, nbins=56, normalize=True, binning=False) self.assertEqual(dos_fp.nbins, len(self.dos.energies)) From 876eefe9f91ae7b612139b52173d979da156290a Mon Sep 17 00:00:00 2001 From: anaik Date: Tue, 6 Dec 2022 09:32:35 +0100 Subject: [PATCH 04/28] remove redundant comment --- pymatgen/electronic_structure/dos.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 43c9c4d2e39..f1b426474d5 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1227,7 +1227,6 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n inds = np.where((energies >= e1) & (energies < e2))[0] dos_rebin[ii] = np.sum(densities[inds]) if normalize: # scale dos bins to make area under histogram equal 1 - #bin_width = np.diff(ener)[0] area = np.sum(dos_rebin * bin_width) dos_rebin_sc = dos_rebin / area else: From dcd37ff1be72db8ac13df79ccc34b41144ebcaf1 Mon Sep 17 00:00:00 2001 From: anaik Date: Tue, 13 Dec 2022 12:09:08 +0100 Subject: [PATCH 05/28] added source link --- pymatgen/electronic_structure/dos.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index f1b426474d5..02aed78cf16 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1169,6 +1169,9 @@ def get_upper_band_edge( def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, nbins=256, normalize=True): """ Generates the DOS fingerprint based on work of F. Knoop, T. A. r Purcell, M. Scheffler, C. Carbogno, J. Open Source Softw. 2020, 5, 2671. + Source - https://gitlab.com/vibes-developers/vibes/-/tree/master/vibes/materials_fp + Copyright (c) 2020 Florian Knoop, Thomas A.R. Purcell, Matthias Scheffler, Christian Carbogno + Args: type (str): Specify fingerprint type needed can accept 's/p/d/f/summed_pdos/tdos' @@ -1209,7 +1212,7 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n densities = pdos[type] if len(energies) < nbins: inds = np.where((energies >= min_e) & (energies <= max_e)) - return fp_tup(energies[inds], densities[inds], type, len(energies),np.diff(energies)[0]) + return fp_tup(energies[inds], densities[inds], type, len(energies), np.diff(energies)[0]) if binning: enerBounds = np.linspace(min_e, max_e, nbins + 1) From 4f5752cc683ca60c1b640d09597740f7e044a1b7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 13 Dec 2022 11:23:03 +0000 Subject: [PATCH 06/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pymatgen/electronic_structure/dos.py | 2 +- pymatgen/electronic_structure/tests/test_dos.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 02aed78cf16..f67b5d2b563 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -9,8 +9,8 @@ import functools import warnings -from typing import Mapping from collections import namedtuple +from typing import Mapping import numpy as np from monty.json import MSONable diff --git a/pymatgen/electronic_structure/tests/test_dos.py b/pymatgen/electronic_structure/tests/test_dos.py index fa699fe17d2..c27790be66d 100644 --- a/pymatgen/electronic_structure/tests/test_dos.py +++ b/pymatgen/electronic_structure/tests/test_dos.py @@ -270,7 +270,7 @@ def test_get_dos_fp(self): dos_fp2 = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=False) bin_width2 = np.diff(dos_fp2.energies)[0][0] self.assertAlmostEqual(sum(dos_fp2.densities * bin_width2), 7.279303571428509, delta=0.001) - self.assertAlmostEqual(dos_fp2.binwidth , bin_width2, delta=0.001) + self.assertAlmostEqual(dos_fp2.binwidth, bin_width2, delta=0.001) # binning=False dos_fp = self.dos.get_dos_fp(type="s", min_e=None, max_e=None, nbins=56, normalize=True, binning=False) self.assertEqual(dos_fp.nbins, len(self.dos.energies)) From 1bc772f092dc6049c0bca2098efcc97b0a6e1686 Mon Sep 17 00:00:00 2001 From: anaik Date: Tue, 13 Dec 2022 12:29:42 +0100 Subject: [PATCH 07/28] fix liniting error --- pymatgen/electronic_structure/dos.py | 2 +- pymatgen/electronic_structure/tests/test_dos.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 02aed78cf16..5e52cb4662b 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1195,7 +1195,7 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n pdos_obj = self.get_spd_dos() pdos = {} - for k, v in pdos_obj.items(): + for k, _v in pdos_obj.items(): dens = pdos_obj[k].get_densities() pdos.update({k.name: dens}) diff --git a/pymatgen/electronic_structure/tests/test_dos.py b/pymatgen/electronic_structure/tests/test_dos.py index fa699fe17d2..c27790be66d 100644 --- a/pymatgen/electronic_structure/tests/test_dos.py +++ b/pymatgen/electronic_structure/tests/test_dos.py @@ -270,7 +270,7 @@ def test_get_dos_fp(self): dos_fp2 = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=False) bin_width2 = np.diff(dos_fp2.energies)[0][0] self.assertAlmostEqual(sum(dos_fp2.densities * bin_width2), 7.279303571428509, delta=0.001) - self.assertAlmostEqual(dos_fp2.binwidth , bin_width2, delta=0.001) + self.assertAlmostEqual(dos_fp2.binwidth, bin_width2, delta=0.001) # binning=False dos_fp = self.dos.get_dos_fp(type="s", min_e=None, max_e=None, nbins=56, normalize=True, binning=False) self.assertEqual(dos_fp.nbins, len(self.dos.energies)) From 0ee33dd2100ef609778c4d497b5b97f48f7c2d91 Mon Sep 17 00:00:00 2001 From: anaik Date: Tue, 13 Dec 2022 14:03:38 +0100 Subject: [PATCH 08/28] fix line length linting error --- pymatgen/electronic_structure/dos.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 2298b711743..3ccddd824e2 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1181,7 +1181,8 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n normalize (bool): If true, normalizes the area under fp to equal to 1 Returns: - Fingerprint(namedtuple) : The electronic density of states fingerprint of format (energies, densities, type, nbins) + Fingerprint(namedtuple) : The electronic density of states fingerprint + of format (energies, densities, type, nbins) """ fp_tup = namedtuple("fingerprint", "energies densities type nbins binwidth") energies = self.energies - self.efermi From d5468ef40b2520d9fd70ae26abcbcda5573bcbf3 Mon Sep 17 00:00:00 2001 From: anaik Date: Tue, 13 Dec 2022 14:27:57 +0100 Subject: [PATCH 09/28] fix line lenghts --- pymatgen/electronic_structure/dos.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 3ccddd824e2..5a1594e85af 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1168,9 +1168,10 @@ def get_upper_band_edge( def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, nbins=256, normalize=True): """ - Generates the DOS fingerprint based on work of F. Knoop, T. A. r Purcell, M. Scheffler, C. Carbogno, J. Open Source Softw. 2020, 5, 2671. + Generates the DOS fingerprint based on work of + F. Knoop, T. A. r Purcell, M. Scheffler, C. Carbogno, J. Open Source Softw. 2020, 5, 2671. Source - https://gitlab.com/vibes-developers/vibes/-/tree/master/vibes/materials_fp - Copyright (c) 2020 Florian Knoop, Thomas A.R. Purcell, Matthias Scheffler, Christian Carbogno + Copyright (c) 2020 Florian Knoop, Thomas A.R.Purcell, Matthias Scheffler, Christian Carbogno Args: @@ -1241,7 +1242,7 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n except KeyError: raise ValueError( "Please recheck type requested, either the orbital projections unavailable in input dos or " - "some typo has been made." + "some error in the spelling." ) def _fp_to_dict(self, fp): @@ -1263,7 +1264,7 @@ def get_dos_fp_similarity(self, fp1, fp2, col=1, pt="All", normalize=False, tani Args: fp1 (get_dos_fp): The 1st dos fingerprint - fp2 get_dos_fp: The 2nd dos fingerprint + fp2 (get_dos_fp): The 2nd dos fingerprint col (int): The item in the fingerprints to take the dot product of (0=Energies 1=Densities) pt (int or 'All') : The index of the point that the dot product is to be taken normalize (bool): If True normalize the scalar product to 1 From 6d68324b99543e54062a3abadac8f570928ec10b Mon Sep 17 00:00:00 2001 From: anaik Date: Tue, 13 Dec 2022 15:08:11 +0100 Subject: [PATCH 10/28] changed get_dos_fp_similarity and fp_to_dict methods to static --- pymatgen/electronic_structure/dos.py | 20 ++++++++++--------- .../electronic_structure/tests/test_dos.py | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 5a1594e85af..c172c0fc894 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1217,18 +1217,18 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n return fp_tup(energies[inds], densities[inds], type, len(energies), np.diff(energies)[0]) if binning: - enerBounds = np.linspace(min_e, max_e, nbins + 1) - ener = enerBounds[:-1] + (enerBounds[1] - enerBounds[0]) / 2.0 + ener_bounds = np.linspace(min_e, max_e, nbins + 1) + ener = ener_bounds[:-1] + (ener_bounds[1] - ener_bounds[0]) / 2.0 bin_width = np.diff(ener)[0] else: - enerBounds = np.array(energies) + ener_bounds = np.array(energies) ener = np.append(energies, [energies[-1] + np.abs(energies[-1]) / 10]) nbins = len(energies) bin_width = np.diff(energies)[0] dos_rebin = np.zeros(ener.shape) - for ii, e1, e2 in zip(range(len(ener)), enerBounds[0:-1], enerBounds[1:]): + for ii, e1, e2 in zip(range(len(ener)), ener_bounds[0:-1], ener_bounds[1:]): inds = np.where((energies >= e1) & (energies < e2))[0] dos_rebin[ii] = np.sum(densities[inds]) if normalize: # scale dos bins to make area under histogram equal 1 @@ -1242,10 +1242,11 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n except KeyError: raise ValueError( "Please recheck type requested, either the orbital projections unavailable in input dos or " - "some error in the spelling." + "some there exist some mistake in the spelling." ) - def _fp_to_dict(self, fp): + @staticmethod + def fp_to_dict(fp): """Converts a fingerprint into a dictionary Args: @@ -1259,7 +1260,8 @@ def _fp_to_dict(self, fp): return fp_dict - def get_dos_fp_similarity(self, fp1, fp2, col=1, pt="All", normalize=False, tanimoto=False): + @staticmethod + def get_dos_fp_similarity(fp1, fp2, col=1, pt="All", normalize=False, tanimoto=False): """Calculates the similarity index (dot product) of two finger prints Args: @@ -1274,12 +1276,12 @@ def get_dos_fp_similarity(self, fp1, fp2, col=1, pt="All", normalize=False, tani Similarity index (float): The value dot product """ if not isinstance(fp1, dict): - fp1_dict = self._fp_to_dict(fp1) + fp1_dict = CompleteDos.fp_to_dict(fp1) else: fp1_dict = fp1 if not isinstance(fp2, dict): - fp2_dict = self._fp_to_dict(fp2) + fp2_dict = CompleteDos.fp_to_dict(fp2) else: fp2_dict = fp2 diff --git a/pymatgen/electronic_structure/tests/test_dos.py b/pymatgen/electronic_structure/tests/test_dos.py index c27790be66d..a8dc15b2366 100644 --- a/pymatgen/electronic_structure/tests/test_dos.py +++ b/pymatgen/electronic_structure/tests/test_dos.py @@ -302,7 +302,7 @@ def test_dos_fp_exceptions(self): self.dos.get_dos_fp(type="k", min_e=-10, max_e=0, nbins=56, normalize=True) self.assertEqual( err.exception.__str__(), - "Please recheck type requested, either the orbital projections unavailable in input dos or some typo has been made.", + "Please recheck type requested, either the orbital projections unavailable in input dos or some there exist some mistake in the spelling.", ) From cf25f28e97d20e0ed7403dc29291786e3519ed07 Mon Sep 17 00:00:00 2001 From: anaik Date: Tue, 13 Dec 2022 15:53:33 +0100 Subject: [PATCH 11/28] fixed typo in doc string --- pymatgen/electronic_structure/dos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index c172c0fc894..41dbbefa0d9 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1273,7 +1273,7 @@ def get_dos_fp_similarity(fp1, fp2, col=1, pt="All", normalize=False, tanimoto=F tanimoto (bool): If True will compute tanimoto index Returns: - Similarity index (float): The value dot product + Similarity index (float): The value of dot product """ if not isinstance(fp1, dict): fp1_dict = CompleteDos.fp_to_dict(fp1) From eb8cfa4f8c245e1c85c09d170222d29cba8d41c5 Mon Sep 17 00:00:00 2001 From: Aakash Ashok Naik <91958822+naik-aakash@users.noreply.github.com> Date: Wed, 14 Dec 2022 16:41:04 +0100 Subject: [PATCH 12/28] fixed doc string suggestion --- pymatgen/electronic_structure/dos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 41dbbefa0d9..c2941757325 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1262,7 +1262,7 @@ def fp_to_dict(fp): @staticmethod def get_dos_fp_similarity(fp1, fp2, col=1, pt="All", normalize=False, tanimoto=False): - """Calculates the similarity index (dot product) of two finger prints + """Calculates the similarity index (dot product) of two fingerprints Args: fp1 (get_dos_fp): The 1st dos fingerprint From ff7c2714bbb5e456157e150815bb1d91e39c2b6b Mon Sep 17 00:00:00 2001 From: anaik Date: Thu, 15 Dec 2022 10:00:20 +0100 Subject: [PATCH 13/28] Updated doc strings based on suggestion, added type annotation to the methods --- pymatgen/electronic_structure/dos.py | 56 ++++++++++++------- .../electronic_structure/tests/test_dos.py | 24 ++++---- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index c2941757325..b3f16466e56 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1166,7 +1166,15 @@ def get_upper_band_edge( upper_band_edge = energies[np.argmax(densities)] return upper_band_edge - def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, nbins=256, normalize=True): + def get_dos_fp( + self, + type: str = "summed_pdos", + binning: bool = True, + min_e: float = None, + max_e: float = None, + n_bins: int = 256, + normalize: bool = True, + ): """ Generates the DOS fingerprint based on work of F. Knoop, T. A. r Purcell, M. Scheffler, C. Carbogno, J. Open Source Softw. 2020, 5, 2671. @@ -1176,16 +1184,17 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n Args: type (str): Specify fingerprint type needed can accept 's/p/d/f/summed_pdos/tdos' - min_e (float): The minimum mode energy to include in the fingerprint - max_e (float): The maximum mode energy to include in the fingerprint - nbins (int): Number of bins to be used in the fingerprint - normalize (bool): If true, normalizes the area under fp to equal to 1 + (default is summed_pdos) + min_e (float): The minimum mode energy to include in the fingerprint (default is None) + max_e (float): The maximum mode energy to include in the fingerprint (default is None) + n_bins (int): Number of bins to be used in the fingerprint (default is 256) + normalize (bool): If true, normalizes the area under fp to equal to 1 (default is True) Returns: Fingerprint(namedtuple) : The electronic density of states fingerprint - of format (energies, densities, type, nbins) + of format (energies, densities, type, n_bins) """ - fp_tup = namedtuple("fingerprint", "energies densities type nbins binwidth") + fp_tup = namedtuple("fingerprint", "energies densities type n_bins bin_width") energies = self.energies - self.efermi if max_e is None: @@ -1212,18 +1221,18 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n try: densities = pdos[type] - if len(energies) < nbins: + if len(energies) < n_bins: inds = np.where((energies >= min_e) & (energies <= max_e)) return fp_tup(energies[inds], densities[inds], type, len(energies), np.diff(energies)[0]) if binning: - ener_bounds = np.linspace(min_e, max_e, nbins + 1) + ener_bounds = np.linspace(min_e, max_e, n_bins + 1) ener = ener_bounds[:-1] + (ener_bounds[1] - ener_bounds[0]) / 2.0 bin_width = np.diff(ener)[0] else: ener_bounds = np.array(energies) ener = np.append(energies, [energies[-1] + np.abs(energies[-1]) / 10]) - nbins = len(energies) + n_bins = len(energies) bin_width = np.diff(energies)[0] dos_rebin = np.zeros(ener.shape) @@ -1237,7 +1246,7 @@ def get_dos_fp(self, type="summed_pdos", binning=True, min_e=None, max_e=None, n else: dos_rebin_sc = dos_rebin - return fp_tup(np.array([ener]), dos_rebin_sc, type, nbins, bin_width) + return fp_tup(np.array([ener]), dos_rebin_sc, type, n_bins, bin_width) except KeyError: raise ValueError( @@ -1253,24 +1262,31 @@ def fp_to_dict(fp): fp: The DOS fingerprint to be converted into a dictionary Returns: - dict: A dict of the fingerprint Keys=type, Values=np.ndarray(energies, states) + dict: A dict of the fingerprint Keys=type, Values=np.ndarray(energies, densities) """ fp_dict = {} - fp_dict[fp[2]] = np.array([fp[0], fp[1]]).T + fp_dict[fp[2]] = np.array([fp[0], fp[1]],dtype=object).T return fp_dict @staticmethod - def get_dos_fp_similarity(fp1, fp2, col=1, pt="All", normalize=False, tanimoto=False): + def get_dos_fp_similarity( + fp1, + fp2, + col: int = 1, + pt: int | str = "All", + normalize: bool = False, + tanimoto: bool = False, + ): """Calculates the similarity index (dot product) of two fingerprints Args: - fp1 (get_dos_fp): The 1st dos fingerprint - fp2 (get_dos_fp): The 2nd dos fingerprint - col (int): The item in the fingerprints to take the dot product of (0=Energies 1=Densities) - pt (int or 'All') : The index of the point that the dot product is to be taken - normalize (bool): If True normalize the scalar product to 1 - tanimoto (bool): If True will compute tanimoto index + fp1 (get_dos_fp): The 1st dos fingerprint object + fp2 (get_dos_fp): The 2nd dos fingerprint object + col (int): The item in the fingerprints (0:energies,1: densities) to take the dot product of (default is 1) + pt (int or str) : The index of the point that the dot product is to be taken (default is All) + normalize (bool): If True normalize the scalar product to 1 (default is False) + tanimoto (bool): If True will compute tanimoto index (default is False) Returns: Similarity index (float): The value of dot product diff --git a/pymatgen/electronic_structure/tests/test_dos.py b/pymatgen/electronic_structure/tests/test_dos.py index a8dc15b2366..12b4e2796b8 100644 --- a/pymatgen/electronic_structure/tests/test_dos.py +++ b/pymatgen/electronic_structure/tests/test_dos.py @@ -259,7 +259,7 @@ def test_kurtosis(self): def test_get_dos_fp(self): # normalize=True - dos_fp = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=True) + dos_fp = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, n_bins=56, normalize=True) bin_width = np.diff(dos_fp.energies)[0][0] self.assertLessEqual(max(dos_fp.energies[0]), 0) self.assertGreaterEqual(min(dos_fp.energies[0]), -10) @@ -267,28 +267,28 @@ def test_get_dos_fp(self): self.assertEqual(dos_fp.type, "s") self.assertAlmostEqual(sum(dos_fp.densities * bin_width), 1, delta=0.001) # normalize=False - dos_fp2 = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=False) + dos_fp2 = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, n_bins=56, normalize=False) bin_width2 = np.diff(dos_fp2.energies)[0][0] self.assertAlmostEqual(sum(dos_fp2.densities * bin_width2), 7.279303571428509, delta=0.001) - self.assertAlmostEqual(dos_fp2.binwidth, bin_width2, delta=0.001) + self.assertAlmostEqual(dos_fp2.bin_width, bin_width2, delta=0.001) # binning=False - dos_fp = self.dos.get_dos_fp(type="s", min_e=None, max_e=None, nbins=56, normalize=True, binning=False) - self.assertEqual(dos_fp.nbins, len(self.dos.energies)) + dos_fp = self.dos.get_dos_fp(type="s", min_e=None, max_e=None, n_bins=56, normalize=True, binning=False) + self.assertEqual(dos_fp.n_bins, len(self.dos.energies)) def test_get_dos_fp_similarity(self): - dos_fp = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=True) - dos_fp2 = self.dos.get_dos_fp(type="tdos", min_e=-10, max_e=0, nbins=56, normalize=True) + dos_fp = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, n_bins=56, normalize=True) + dos_fp2 = self.dos.get_dos_fp(type="tdos", min_e=-10, max_e=0, n_bins=56, normalize=True) similarity_index = self.dos.get_dos_fp_similarity(dos_fp, dos_fp2, col=1, tanimoto=True) self.assertAlmostEqual(similarity_index, 0.3342481451042263, delta=0.0001) - dos_fp = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=True) - dos_fp2 = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=True) + dos_fp = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, n_bins=56, normalize=True) + dos_fp2 = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, n_bins=56, normalize=True) similarity_index = self.dos.get_dos_fp_similarity(dos_fp, dos_fp2, col=1, tanimoto=True) self.assertEqual(similarity_index, 1) def test_dos_fp_exceptions(self): - dos_fp = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, nbins=56, normalize=True) - dos_fp2 = self.dos.get_dos_fp(type="tdos", min_e=-10, max_e=0, nbins=56, normalize=True) + dos_fp = self.dos.get_dos_fp(type="s", min_e=-10, max_e=0, n_bins=56, normalize=True) + dos_fp2 = self.dos.get_dos_fp(type="tdos", min_e=-10, max_e=0, n_bins=56, normalize=True) # test exceptions with self.assertRaises(ValueError) as err: @@ -299,7 +299,7 @@ def test_dos_fp_exceptions(self): ) with self.assertRaises(ValueError) as err: - self.dos.get_dos_fp(type="k", min_e=-10, max_e=0, nbins=56, normalize=True) + self.dos.get_dos_fp(type="k", min_e=-10, max_e=0, n_bins=56, normalize=True) self.assertEqual( err.exception.__str__(), "Please recheck type requested, either the orbital projections unavailable in input dos or some there exist some mistake in the spelling.", From 1882916885aa0a768b9d3545b7ba2cea28b10193 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 15 Dec 2022 09:02:42 +0000 Subject: [PATCH 14/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pymatgen/electronic_structure/dos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index b3f16466e56..45182b2c8bf 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1265,7 +1265,7 @@ def fp_to_dict(fp): dict: A dict of the fingerprint Keys=type, Values=np.ndarray(energies, densities) """ fp_dict = {} - fp_dict[fp[2]] = np.array([fp[0], fp[1]],dtype=object).T + fp_dict[fp[2]] = np.array([fp[0], fp[1]], dtype=object).T return fp_dict From 7b1fcee842f169851a4a2ddee9373a17fae3caf1 Mon Sep 17 00:00:00 2001 From: anaik Date: Thu, 15 Dec 2022 11:40:40 +0100 Subject: [PATCH 15/28] mypy fixes --- pymatgen/electronic_structure/dos.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 45182b2c8bf..d4413183581 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -10,7 +10,7 @@ import functools import warnings from collections import namedtuple -from typing import Mapping +from typing import Optional, Mapping import numpy as np from monty.json import MSONable @@ -1170,8 +1170,8 @@ def get_dos_fp( self, type: str = "summed_pdos", binning: bool = True, - min_e: float = None, - max_e: float = None, + min_e: Optional[float] = None, + max_e: Optional[float] = None, n_bins: int = 256, normalize: bool = True, ): @@ -1194,7 +1194,7 @@ def get_dos_fp( Fingerprint(namedtuple) : The electronic density of states fingerprint of format (energies, densities, type, n_bins) """ - fp_tup = namedtuple("fingerprint", "energies densities type n_bins bin_width") + fingerprint = namedtuple("fingerprint", "energies densities type n_bins bin_width") energies = self.energies - self.efermi if max_e is None: @@ -1223,7 +1223,7 @@ def get_dos_fp( densities = pdos[type] if len(energies) < n_bins: inds = np.where((energies >= min_e) & (energies <= max_e)) - return fp_tup(energies[inds], densities[inds], type, len(energies), np.diff(energies)[0]) + return fingerprint(energies[inds], densities[inds], type, len(energies), np.diff(energies)[0]) if binning: ener_bounds = np.linspace(min_e, max_e, n_bins + 1) @@ -1246,7 +1246,7 @@ def get_dos_fp( else: dos_rebin_sc = dos_rebin - return fp_tup(np.array([ener]), dos_rebin_sc, type, n_bins, bin_width) + return fingerprint(np.array([ener]), dos_rebin_sc, type, n_bins, bin_width) except KeyError: raise ValueError( @@ -1265,7 +1265,7 @@ def fp_to_dict(fp): dict: A dict of the fingerprint Keys=type, Values=np.ndarray(energies, densities) """ fp_dict = {} - fp_dict[fp[2]] = np.array([fp[0], fp[1]], dtype=object).T + fp_dict[fp[2]] = np.array([fp[0], fp[1]], dtype=tuple).T return fp_dict From b064ac93d840163e5674d4c5c201b83864c35b21 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 15 Dec 2022 10:42:55 +0000 Subject: [PATCH 16/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pymatgen/electronic_structure/dos.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index d4413183581..7826c5db7c3 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -10,7 +10,7 @@ import functools import warnings from collections import namedtuple -from typing import Optional, Mapping +from typing import Mapping, Optional import numpy as np from monty.json import MSONable @@ -1170,8 +1170,8 @@ def get_dos_fp( self, type: str = "summed_pdos", binning: bool = True, - min_e: Optional[float] = None, - max_e: Optional[float] = None, + min_e: float | None = None, + max_e: float | None = None, n_bins: int = 256, normalize: bool = True, ): From a1a44e8996d75a93f078c6228b83c1cf4a3b4f8e Mon Sep 17 00:00:00 2001 From: anaik Date: Thu, 15 Dec 2022 11:56:02 +0100 Subject: [PATCH 17/28] fix flake8 --- pymatgen/electronic_structure/dos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 7826c5db7c3..13a89c729ec 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -10,7 +10,7 @@ import functools import warnings from collections import namedtuple -from typing import Mapping, Optional +from typing import Mapping import numpy as np from monty.json import MSONable From 433e5c162417d329e59224433a4a23cec7b40ea2 Mon Sep 17 00:00:00 2001 From: anaik Date: Thu, 15 Dec 2022 12:10:08 +0100 Subject: [PATCH 18/28] mypy error fix --- pymatgen/electronic_structure/dos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 13a89c729ec..eb918e49b5f 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1265,7 +1265,7 @@ def fp_to_dict(fp): dict: A dict of the fingerprint Keys=type, Values=np.ndarray(energies, densities) """ fp_dict = {} - fp_dict[fp[2]] = np.array([fp[0], fp[1]], dtype=tuple).T + fp_dict[fp[2]] = np.array([fp[0], fp[1]]).T return fp_dict From cb9484fbb377182b633e548b2dbf1f88cd1a17d5 Mon Sep 17 00:00:00 2001 From: anaik Date: Thu, 15 Dec 2022 13:29:36 +0100 Subject: [PATCH 19/28] mypy error fix --- pymatgen/electronic_structure/Test.py | 82 +++++++++++++++++++++++++++ pymatgen/electronic_structure/dos.py | 4 +- 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 pymatgen/electronic_structure/Test.py diff --git a/pymatgen/electronic_structure/Test.py b/pymatgen/electronic_structure/Test.py new file mode 100644 index 00000000000..f94b8424fea --- /dev/null +++ b/pymatgen/electronic_structure/Test.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[1]: + + +from pymatgen.io.lobster import Doscar +from pymatgen.io.lobster import Lobsterout, Lobsterin +from pymatgen.io.vasp.outputs import Vasprun +from pymatgen.io.vasp.outputs import Outcar +from pymatgen.electronic_structure.core import Orbital, OrbitalType, Spin +from collections import namedtuple +from pymatgen.electronic_structure.plotter import DosPlotter +from pymatgen.electronic_structure.dos import Dos +from pymatgen.core.periodic_table import Element +import numpy as np +import pandas as pd +import os +import re +import plotly.graph_objects as go +import ast +import warnings +# from sklearn import preprocessing +from scipy.integrate import trapezoid +# from sklearn.linear_model import LinearRegression + + +# In[2]: + + +import seaborn as sns +from matplotlib import pyplot as plt +import matplotlib.patches as mpl_patches + +sns.set_style("white") +sns.set_context("talk") +sns.set_palette(["#0CB1F3", "#F34E0C"]) + +# In[3]: + + +os.chdir('/hpc-user/AG-JGeorge/anaik/') + +# In[4]: + + +parent = os.getcwd() +os.chdir('Phonon_Dataset/Results/') + +# In[5]: + + +mpids_lob = [f for f in os.listdir() if not f.startswith('t') and not f.startswith('.') and not f.startswith('__') + and os.path.isdir(f)] +mats = list(set([ids.split('_')[0] for ids in mpids_lob])) +mats.sort() + +# In[6]: + + +mpid = mats[100] +doscar_lobster = Doscar(doscar="{}/DOSCAR.lobster.gz".format(mpid), + structure_file="{}/POSCAR.gz".format(mpid), + dftprogram="Vasp") + +dos_lobster = doscar_lobster.completedos + +vasprun = Vasprun("{}/vasprun.xml.gz".format(mpid)) +# Sys_elec= round(Outcar('{}/OUTCAR.gz'.format(mpid)).nelect,2) +# Lobout = Lobsterout('{}/lobsterout.gz'.format(mpid)) + +dos_vasp = vasprun.complete_dos + + + +fp_lobster = dos_lobster.get_dos_fp(type='tdos', n_bins=100, normalize=True, binning=True) + + +fp_vasp = dos_vasp.get_dos_fp(type='s', max_e=0, min_e=-15, n_bins=100, normalize=True) + + +dos_vasp.get_dos_fp_similarity(fp_vasp, fp_lobster, tanimoto=False, normalize=True) \ No newline at end of file diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index eb918e49b5f..c0ce7050d8f 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1238,7 +1238,7 @@ def get_dos_fp( dos_rebin = np.zeros(ener.shape) for ii, e1, e2 in zip(range(len(ener)), ener_bounds[0:-1], ener_bounds[1:]): - inds = np.where((energies >= e1) & (energies < e2))[0] + inds = np.where((energies >= e1) & (energies < e2)) dos_rebin[ii] = np.sum(densities[inds]) if normalize: # scale dos bins to make area under histogram equal 1 area = np.sum(dos_rebin * bin_width) @@ -1265,7 +1265,7 @@ def fp_to_dict(fp): dict: A dict of the fingerprint Keys=type, Values=np.ndarray(energies, densities) """ fp_dict = {} - fp_dict[fp[2]] = np.array([fp[0], fp[1]]).T + fp_dict[fp[2]] = np.array([fp[0], fp[1]], dtype="object").T return fp_dict From f27e5fc7fbc7bfef35f362d539127de7391ea9fe Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 15 Dec 2022 12:31:50 +0000 Subject: [PATCH 20/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pymatgen/electronic_structure/Test.py | 51 ++++++++++----------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/pymatgen/electronic_structure/Test.py b/pymatgen/electronic_structure/Test.py index f94b8424fea..672d2e9642f 100644 --- a/pymatgen/electronic_structure/Test.py +++ b/pymatgen/electronic_structure/Test.py @@ -1,37 +1,22 @@ #!/usr/bin/env python -# coding: utf-8 # In[1]: +import os + +import seaborn as sns + from pymatgen.io.lobster import Doscar -from pymatgen.io.lobster import Lobsterout, Lobsterin from pymatgen.io.vasp.outputs import Vasprun -from pymatgen.io.vasp.outputs import Outcar -from pymatgen.electronic_structure.core import Orbital, OrbitalType, Spin -from collections import namedtuple -from pymatgen.electronic_structure.plotter import DosPlotter -from pymatgen.electronic_structure.dos import Dos -from pymatgen.core.periodic_table import Element -import numpy as np -import pandas as pd -import os -import re -import plotly.graph_objects as go -import ast -import warnings + # from sklearn import preprocessing -from scipy.integrate import trapezoid # from sklearn.linear_model import LinearRegression # In[2]: -import seaborn as sns -from matplotlib import pyplot as plt -import matplotlib.patches as mpl_patches - sns.set_style("white") sns.set_context("talk") sns.set_palette(["#0CB1F3", "#F34E0C"]) @@ -39,44 +24,44 @@ # In[3]: -os.chdir('/hpc-user/AG-JGeorge/anaik/') +os.chdir("/hpc-user/AG-JGeorge/anaik/") # In[4]: parent = os.getcwd() -os.chdir('Phonon_Dataset/Results/') +os.chdir("Phonon_Dataset/Results/") # In[5]: -mpids_lob = [f for f in os.listdir() if not f.startswith('t') and not f.startswith('.') and not f.startswith('__') - and os.path.isdir(f)] -mats = list(set([ids.split('_')[0] for ids in mpids_lob])) +mpids_lob = [ + f + for f in os.listdir() + if not f.startswith("t") and not f.startswith(".") and not f.startswith("__") and os.path.isdir(f) +] +mats = list({ids.split("_")[0] for ids in mpids_lob}) mats.sort() # In[6]: mpid = mats[100] -doscar_lobster = Doscar(doscar="{}/DOSCAR.lobster.gz".format(mpid), - structure_file="{}/POSCAR.gz".format(mpid), - dftprogram="Vasp") +doscar_lobster = Doscar(doscar=f"{mpid}/DOSCAR.lobster.gz", structure_file=f"{mpid}/POSCAR.gz", dftprogram="Vasp") dos_lobster = doscar_lobster.completedos -vasprun = Vasprun("{}/vasprun.xml.gz".format(mpid)) +vasprun = Vasprun(f"{mpid}/vasprun.xml.gz") # Sys_elec= round(Outcar('{}/OUTCAR.gz'.format(mpid)).nelect,2) # Lobout = Lobsterout('{}/lobsterout.gz'.format(mpid)) dos_vasp = vasprun.complete_dos - -fp_lobster = dos_lobster.get_dos_fp(type='tdos', n_bins=100, normalize=True, binning=True) +fp_lobster = dos_lobster.get_dos_fp(type="tdos", n_bins=100, normalize=True, binning=True) -fp_vasp = dos_vasp.get_dos_fp(type='s', max_e=0, min_e=-15, n_bins=100, normalize=True) +fp_vasp = dos_vasp.get_dos_fp(type="s", max_e=0, min_e=-15, n_bins=100, normalize=True) -dos_vasp.get_dos_fp_similarity(fp_vasp, fp_lobster, tanimoto=False, normalize=True) \ No newline at end of file +dos_vasp.get_dos_fp_similarity(fp_vasp, fp_lobster, tanimoto=False, normalize=True) From 746c12a1184fad8e2fd6d9279efead1d852086e4 Mon Sep 17 00:00:00 2001 From: Aakash Ashok Naik <91958822+naik-aakash@users.noreply.github.com> Date: Thu, 15 Dec 2022 13:34:41 +0100 Subject: [PATCH 21/28] Delete Test.py Remove unnecessary file --- pymatgen/electronic_structure/Test.py | 67 --------------------------- 1 file changed, 67 deletions(-) delete mode 100644 pymatgen/electronic_structure/Test.py diff --git a/pymatgen/electronic_structure/Test.py b/pymatgen/electronic_structure/Test.py deleted file mode 100644 index 672d2e9642f..00000000000 --- a/pymatgen/electronic_structure/Test.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python - -# In[1]: - - -import os - -import seaborn as sns - -from pymatgen.io.lobster import Doscar -from pymatgen.io.vasp.outputs import Vasprun - -# from sklearn import preprocessing -# from sklearn.linear_model import LinearRegression - - -# In[2]: - - -sns.set_style("white") -sns.set_context("talk") -sns.set_palette(["#0CB1F3", "#F34E0C"]) - -# In[3]: - - -os.chdir("/hpc-user/AG-JGeorge/anaik/") - -# In[4]: - - -parent = os.getcwd() -os.chdir("Phonon_Dataset/Results/") - -# In[5]: - - -mpids_lob = [ - f - for f in os.listdir() - if not f.startswith("t") and not f.startswith(".") and not f.startswith("__") and os.path.isdir(f) -] -mats = list({ids.split("_")[0] for ids in mpids_lob}) -mats.sort() - -# In[6]: - - -mpid = mats[100] -doscar_lobster = Doscar(doscar=f"{mpid}/DOSCAR.lobster.gz", structure_file=f"{mpid}/POSCAR.gz", dftprogram="Vasp") - -dos_lobster = doscar_lobster.completedos - -vasprun = Vasprun(f"{mpid}/vasprun.xml.gz") -# Sys_elec= round(Outcar('{}/OUTCAR.gz'.format(mpid)).nelect,2) -# Lobout = Lobsterout('{}/lobsterout.gz'.format(mpid)) - -dos_vasp = vasprun.complete_dos - - -fp_lobster = dos_lobster.get_dos_fp(type="tdos", n_bins=100, normalize=True, binning=True) - - -fp_vasp = dos_vasp.get_dos_fp(type="s", max_e=0, min_e=-15, n_bins=100, normalize=True) - - -dos_vasp.get_dos_fp_similarity(fp_vasp, fp_lobster, tanimoto=False, normalize=True) From a1f21c244141692f5420c41ce526d244b83f2d3a Mon Sep 17 00:00:00 2001 From: anaik Date: Mon, 19 Dec 2022 09:44:38 +0100 Subject: [PATCH 22/28] simplified dict updating, added missing type annotations --- pymatgen/electronic_structure/dos.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index c0ce7050d8f..7668bed37db 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1174,7 +1174,7 @@ def get_dos_fp( max_e: float | None = None, n_bins: int = 256, normalize: bool = True, - ): + ) -> namedtuple(): """ Generates the DOS fingerprint based on work of F. Knoop, T. A. r Purcell, M. Scheffler, C. Carbogno, J. Open Source Softw. 2020, 5, 2671. @@ -1206,17 +1206,17 @@ def get_dos_fp( pdos_obj = self.get_spd_dos() pdos = {} - for k, _v in pdos_obj.items(): - dens = pdos_obj[k].get_densities() + for key in pdos_obj: + dens = pdos_obj[key].get_densities() - pdos.update({k.name: dens}) + pdos[key.name] = dens sum_pdos_array = [] for dos in pdos.values(): sum_pdos_array.append(np.array(dos)) - pdos.update({"summed_pdos": np.sum(sum_pdos_array, axis=0)}) - pdos.update({"tdos": self.get_densities()}) + pdos["summed_pdos"] = np.sum(sum_pdos_array, axis=0) + pdos["tdos"] = self.get_densities() try: @@ -1255,7 +1255,7 @@ def get_dos_fp( ) @staticmethod - def fp_to_dict(fp): + def fp_to_dict(fp: namedtuple()) -> dict: """Converts a fingerprint into a dictionary Args: @@ -1277,7 +1277,7 @@ def get_dos_fp_similarity( pt: int | str = "All", normalize: bool = False, tanimoto: bool = False, - ): + ) -> float: """Calculates the similarity index (dot product) of two fingerprints Args: @@ -1286,7 +1286,7 @@ def get_dos_fp_similarity( col (int): The item in the fingerprints (0:energies,1: densities) to take the dot product of (default is 1) pt (int or str) : The index of the point that the dot product is to be taken (default is All) normalize (bool): If True normalize the scalar product to 1 (default is False) - tanimoto (bool): If True will compute tanimoto index (default is False) + tanimoto (bool): If True will compute Tanimoto index (default is False) Returns: Similarity index (float): The value of dot product From a681b706fea370bb6746522ad4015aab0447821e Mon Sep 17 00:00:00 2001 From: anaik Date: Mon, 19 Dec 2022 10:09:00 +0100 Subject: [PATCH 23/28] mypy error fixes --- pymatgen/electronic_structure/dos.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 7668bed37db..6ec9cdcdee8 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1174,7 +1174,7 @@ def get_dos_fp( max_e: float | None = None, n_bins: int = 256, normalize: bool = True, - ) -> namedtuple(): + ) -> namedtuple[...]: """ Generates the DOS fingerprint based on work of F. Knoop, T. A. r Purcell, M. Scheffler, C. Carbogno, J. Open Source Softw. 2020, 5, 2671. @@ -1255,7 +1255,7 @@ def get_dos_fp( ) @staticmethod - def fp_to_dict(fp: namedtuple()) -> dict: + def fp_to_dict(fp: namedtuple[...]) -> dict: """Converts a fingerprint into a dictionary Args: From 6445f42adbae3f74c3ee1308463cea5aec39840a Mon Sep 17 00:00:00 2001 From: anaik Date: Mon, 19 Dec 2022 10:28:50 +0100 Subject: [PATCH 24/28] NamedTuple return type fixed --- pymatgen/electronic_structure/dos.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 6ec9cdcdee8..3ea0cebb94a 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -10,7 +10,7 @@ import functools import warnings from collections import namedtuple -from typing import Mapping +from typing import Mapping, NamedTuple import numpy as np from monty.json import MSONable @@ -1174,7 +1174,7 @@ def get_dos_fp( max_e: float | None = None, n_bins: int = 256, normalize: bool = True, - ) -> namedtuple[...]: + ) -> NamedTuple: """ Generates the DOS fingerprint based on work of F. Knoop, T. A. r Purcell, M. Scheffler, C. Carbogno, J. Open Source Softw. 2020, 5, 2671. @@ -1255,7 +1255,7 @@ def get_dos_fp( ) @staticmethod - def fp_to_dict(fp: namedtuple[...]) -> dict: + def fp_to_dict(fp: NamedTuple) -> dict: """Converts a fingerprint into a dictionary Args: From c589945a87cd203fe5c0db82e4554e0719905a09 Mon Sep 17 00:00:00 2001 From: Janosh Riebesell Date: Fri, 23 Dec 2022 16:51:44 -0800 Subject: [PATCH 25/28] small clean up --- pymatgen/electronic_structure/dos.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 3ea0cebb94a..4ef0d25779f 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1211,15 +1211,10 @@ def get_dos_fp( pdos[key.name] = dens - sum_pdos_array = [] - for dos in pdos.values(): - sum_pdos_array.append(np.array(dos)) - - pdos["summed_pdos"] = np.sum(sum_pdos_array, axis=0) + pdos["summed_pdos"] = np.sum(list(pdos.values()), axis=0) pdos["tdos"] = self.get_densities() try: - densities = pdos[type] if len(energies) < n_bins: inds = np.where((energies >= min_e) & (energies <= max_e)) From 1c2dbc47abf603e67cf04e23782c15833c1ecf11 Mon Sep 17 00:00:00 2001 From: Janosh Riebesell Date: Fri, 23 Dec 2022 16:53:06 -0800 Subject: [PATCH 26/28] document get_dos_fp() and get_dos_fp_similarity() raise conditions in doc str --- pymatgen/electronic_structure/dos.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index 4ef0d25779f..fb2d6f50610 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1183,13 +1183,16 @@ def get_dos_fp( Args: - type (str): Specify fingerprint type needed can accept 's/p/d/f/summed_pdos/tdos' + type (str): Specify fingerprint type needed can accept '{s/p/d/f/}summed_{pdos/tdos}' (default is summed_pdos) min_e (float): The minimum mode energy to include in the fingerprint (default is None) max_e (float): The maximum mode energy to include in the fingerprint (default is None) n_bins (int): Number of bins to be used in the fingerprint (default is 256) normalize (bool): If true, normalizes the area under fp to equal to 1 (default is True) + Raises: + ValueError: If type is not one of the accepted values {s/p/d/f/}summed_{pdos/tdos}. + Returns: Fingerprint(namedtuple) : The electronic density of states fingerprint of format (energies, densities, type, n_bins) @@ -1235,7 +1238,7 @@ def get_dos_fp( for ii, e1, e2 in zip(range(len(ener)), ener_bounds[0:-1], ener_bounds[1:]): inds = np.where((energies >= e1) & (energies < e2)) dos_rebin[ii] = np.sum(densities[inds]) - if normalize: # scale dos bins to make area under histogram equal 1 + if normalize: # scale DOS bins to make area under histogram equal 1 area = np.sum(dos_rebin * bin_width) dos_rebin_sc = dos_rebin / area else: @@ -1245,8 +1248,8 @@ def get_dos_fp( except KeyError: raise ValueError( - "Please recheck type requested, either the orbital projections unavailable in input dos or " - "some there exist some mistake in the spelling." + "Please recheck type requested, either the orbital projections unavailable in input DOS or " + "there's a typo in type." ) @staticmethod @@ -1283,6 +1286,9 @@ def get_dos_fp_similarity( normalize (bool): If True normalize the scalar product to 1 (default is False) tanimoto (bool): If True will compute Tanimoto index (default is False) + Raises: + ValueError: If both tanimoto and normalize are set to True. + Returns: Similarity index (float): The value of dot product """ @@ -1317,8 +1323,7 @@ def get_dos_fp_similarity( else: raise ValueError( - "Cannot compute similarity index, Please set either one of normalize/tanimoto arg to true " - "or set both to false" + "Cannot compute similarity index. Please set either normalize=True or tanimoto=True or both to False." ) @classmethod From a8216c767a78176717a0d675b07294600ee71fce Mon Sep 17 00:00:00 2001 From: Janosh Riebesell Date: Fri, 23 Dec 2022 16:53:51 -0800 Subject: [PATCH 27/28] add types for fp1,fp2 and update doc str --- pymatgen/electronic_structure/dos.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pymatgen/electronic_structure/dos.py b/pymatgen/electronic_structure/dos.py index fb2d6f50610..6992a6e94c6 100644 --- a/pymatgen/electronic_structure/dos.py +++ b/pymatgen/electronic_structure/dos.py @@ -1269,8 +1269,8 @@ def fp_to_dict(fp: NamedTuple) -> dict: @staticmethod def get_dos_fp_similarity( - fp1, - fp2, + fp1: NamedTuple, + fp2: NamedTuple, col: int = 1, pt: int | str = "All", normalize: bool = False, @@ -1279,8 +1279,8 @@ def get_dos_fp_similarity( """Calculates the similarity index (dot product) of two fingerprints Args: - fp1 (get_dos_fp): The 1st dos fingerprint object - fp2 (get_dos_fp): The 2nd dos fingerprint object + fp1 (NamedTuple): The 1st dos fingerprint object + fp2 (NamedTuple): The 2nd dos fingerprint object col (int): The item in the fingerprints (0:energies,1: densities) to take the dot product of (default is 1) pt (int or str) : The index of the point that the dot product is to be taken (default is All) normalize (bool): If True normalize the scalar product to 1 (default is False) From 8309b1b21dc91b2a969c5da7f4b105c1bb139e23 Mon Sep 17 00:00:00 2001 From: Janosh Riebesell Date: Fri, 23 Dec 2022 16:54:09 -0800 Subject: [PATCH 28/28] update exception tests --- pymatgen/electronic_structure/tests/test_dos.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pymatgen/electronic_structure/tests/test_dos.py b/pymatgen/electronic_structure/tests/test_dos.py index 12b4e2796b8..32bbcd13bc9 100644 --- a/pymatgen/electronic_structure/tests/test_dos.py +++ b/pymatgen/electronic_structure/tests/test_dos.py @@ -295,14 +295,14 @@ def test_dos_fp_exceptions(self): self.dos.get_dos_fp_similarity(dos_fp, dos_fp2, col=1, tanimoto=True, normalize=True) self.assertEqual( err.exception.__str__(), - "Cannot compute similarity index, Please set either one of normalize/tanimoto arg to true or set both to false", + "Cannot compute similarity index. Please set either normalize=True or tanimoto=True or both to False.", ) with self.assertRaises(ValueError) as err: self.dos.get_dos_fp(type="k", min_e=-10, max_e=0, n_bins=56, normalize=True) self.assertEqual( err.exception.__str__(), - "Please recheck type requested, either the orbital projections unavailable in input dos or some there exist some mistake in the spelling.", + "Please recheck type requested, either the orbital projections unavailable in input DOS or there's a typo in type.", )