|
25 | 25 | martynov_batsanov,
|
26 | 26 | mulliken,
|
27 | 27 | sanderson,
|
| 28 | + interpolate_property, |
28 | 29 | )
|
29 | 30 | from .db import get_session
|
30 | 31 | from .econf import ElectronicConfiguration, get_l, ORBITALS
|
@@ -774,15 +775,21 @@ def electronegativity_pauling(self) -> float:
|
774 | 775 | "Pauling's electronegativity"
|
775 | 776 | return self.en_pauling
|
776 | 777 |
|
777 |
| - def electronegativity_sanderson(self, radius="covalent_radius_pyykko") -> float: |
| 778 | + def electronegativity_sanderson( |
| 779 | + self, radius: str = "covalent_radius_pyykko" |
| 780 | + ) -> float: |
778 | 781 | """
|
779 |
| - Sanderson electronegativity |
| 782 | + Sanderson's electronegativity |
780 | 783 |
|
781 | 784 | Args:
|
782 | 785 | radius : radius to use in the calculation
|
783 | 786 | """
|
784 |
| - # estimate the radius of a corresponding noble gas |
785 |
| - noble_gas_radius = estimate_from_group(self.atomic_number, radius) |
| 787 | + results = fetch_by_group(["atomic_number", radius], group=18) |
| 788 | + # transpose rows to list of properties |
| 789 | + atomic_numbers, radii = list(zip(*results)) |
| 790 | + noble_gas_radius = interpolate_property( |
| 791 | + self.atomic_number, atomic_numbers, radii |
| 792 | + ) |
786 | 793 | return sanderson(getattr(self, radius), noble_gas_radius)
|
787 | 794 |
|
788 | 795 | def nvalence(self, method: str = None) -> int:
|
@@ -841,6 +848,36 @@ def __repr__(self) -> str:
|
841 | 848 | )
|
842 | 849 |
|
843 | 850 |
|
| 851 | +def fetch_by_group(properties: List[str], group: int = 18) -> tuple[list[Any]]: |
| 852 | + """ |
| 853 | + Get a specified properties for all the elements of a given group. |
| 854 | +
|
| 855 | + Args: |
| 856 | + properties: Attributes of `Element` to retrieve for all group members |
| 857 | + group: Group number to retrieve data for |
| 858 | +
|
| 859 | + Returns: |
| 860 | + result: list of tuples with the requested properties for all group members |
| 861 | + """ |
| 862 | + if isinstance(properties, str): |
| 863 | + props = [properties] |
| 864 | + else: |
| 865 | + props = properties[:] |
| 866 | + |
| 867 | + if "atomic_number" not in props: |
| 868 | + props = ["atomic_number"] + props |
| 869 | + |
| 870 | + session = get_session() |
| 871 | + results = ( |
| 872 | + session.query(*[getattr(Element, prop) for prop in props]) |
| 873 | + .filter(Element.group_id == group) |
| 874 | + .order_by("atomic_number") |
| 875 | + .all() |
| 876 | + ) |
| 877 | + session.close() |
| 878 | + return results |
| 879 | + |
| 880 | + |
844 | 881 | class ValueOrigin(enum.Enum):
|
845 | 882 | "Options for the origin of the property value."
|
846 | 883 |
|
@@ -889,65 +926,6 @@ def __repr__(self) -> str:
|
889 | 926 | )
|
890 | 927 |
|
891 | 928 |
|
892 |
| -def fetch_attrs_for_group(attrs: List[str], group: int = 18) -> Tuple[List[Any]]: |
893 |
| - """ |
894 |
| - A convenience function for getting a specified attribute for all |
895 |
| - the memebers of a given group. |
896 |
| -
|
897 |
| - Args: |
898 |
| - attr : Attribute of `Element` to retrieve for all group members |
899 |
| -
|
900 |
| - Returns: |
901 |
| - data (dict): Dictionary with noble gas atomic numbers as keys and values of the |
902 |
| - `attr` as values |
903 |
| - """ |
904 |
| - session = get_session() |
905 |
| - members = ( |
906 |
| - session.query(Element) |
907 |
| - .filter(Element.group_id == group) |
908 |
| - .order_by(Element.atomic_number) |
909 |
| - .all() |
910 |
| - ) |
911 |
| - |
912 |
| - results = tuple([getattr(member, attr) for member in members] for attr in attrs) |
913 |
| - session.close() |
914 |
| - return results |
915 |
| - |
916 |
| - |
917 |
| -def estimate_from_group( |
918 |
| - atomic_number, attr_name, group: int = 18, deg: int = 1 |
919 |
| -) -> float: |
920 |
| - """ |
921 |
| - Evaluate a value `attribute` for element by interpolation or |
922 |
| - extrapolation of the data points from elements from `group`. |
923 |
| -
|
924 |
| - Args: |
925 |
| - atomic_number: value for which the property will be evaluated |
926 |
| - attr_name: attribute to be estimated |
927 |
| - group: periodic table group number |
928 |
| - deg: degree of the polynomial used in the extrapolation beyond |
929 |
| - the provided data points |
930 |
| - """ |
931 |
| - xref, yref = fetch_attrs_for_group(["atomic_number", attr_name], group=group) |
932 |
| - |
933 |
| - x = atomic_number |
934 |
| - xref = np.array(xref) |
935 |
| - yref = np.array(yref) |
936 |
| - if xref.min() <= x <= xref.max(): |
937 |
| - return np.interp([x], xref, yref) |
938 |
| - |
939 |
| - if x < xref.min(): |
940 |
| - xslice = xref[:3] |
941 |
| - yslice = yref[:3] |
942 |
| - elif x > xref.max(): |
943 |
| - xslice = xref[-3:] |
944 |
| - yslice = yref[-3:] |
945 |
| - |
946 |
| - fit = np.polyfit(xslice, yslice, deg) |
947 |
| - fn = np.poly1d(fit) |
948 |
| - return fn(x) |
949 |
| - |
950 |
| - |
951 | 929 | class IonicRadius(Base):
|
952 | 930 | """
|
953 | 931 | Effective ionic radii and crystal radii in pm retrieved from [1]_.
|
@@ -1130,6 +1108,7 @@ def __repr__(self) -> str:
|
1130 | 1108 | return "<Series(name={n:s}, color={c:s})>".format(n=self.name, c=self.color)
|
1131 | 1109 |
|
1132 | 1110 |
|
| 1111 | +# TODO: move to utils |
1133 | 1112 | def with_uncertainty(value: float, uncertainty: float, digits: int = 5) -> str:
|
1134 | 1113 | """Format a value with uncertainty using scientific notation.
|
1135 | 1114 |
|
@@ -1346,6 +1325,7 @@ def __repr__(self) -> str:
|
1346 | 1325 | return str(self)
|
1347 | 1326 |
|
1348 | 1327 |
|
| 1328 | +# TODO: some thing is wrong with the docstring |
1349 | 1329 | class ScatteringFactor(Base):
|
1350 | 1330 | """Atomic scattering factors
|
1351 | 1331 |
|
|
0 commit comments