Skip to content

Commit

Permalink
Merge pull request #1308 from pyiron/delay_mendeleev
Browse files Browse the repository at this point in the history
Import mendeleev only when needed
  • Loading branch information
jan-janssen authored Feb 5, 2024
2 parents d007097 + 9d7b6b8 commit 938238d
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 23 deletions.
143 changes: 127 additions & 16 deletions pyiron_atomistics/atomistics/structure/periodic_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import pkgutil
import io
import numpy as np
import mendeleev
import pandas
from functools import lru_cache

Expand All @@ -24,8 +23,127 @@
pandas.options.mode.chained_assignment = None


MENDELEEV_PROPERTY_LIST = [
"abundance_crust",
"abundance_sea",
"annotation",
"atomic_number",
"atomic_radius",
"atomic_radius_rahm",
"atomic_volume",
"atomic_weight",
"atomic_weight_uncertainty",
"block",
"boiling_point",
"c6",
"c6_gb",
"cas",
"covalent_radius",
"covalent_radius_bragg",
"covalent_radius_cordero",
"covalent_radius_pyykko",
"covalent_radius_pyykko_double",
"covalent_radius_pyykko_triple",
"cpk_color",
"density",
"description",
"dipole_polarizability",
"dipole_polarizability_unc",
"discoverers",
"discovery_location",
"discovery_year",
"ec",
"econf",
"electron_affinity",
"electronegativity",
"electronegativity_allen",
"electronegativity_allred_rochow",
"electronegativity_cottrell_sutton",
"electronegativity_ghosh",
"electronegativity_gordy",
"electronegativity_li_xue",
"electronegativity_martynov_batsanov",
"electronegativity_mulliken",
"electronegativity_nagle",
"electronegativity_pauling",
"electronegativity_sanderson",
"electronegativity_scales",
"electrons",
"electrophilicity",
"en_allen",
"en_ghosh",
"en_pauling",
"evaporation_heat",
"fusion_heat",
"gas_basicity",
"geochemical_class",
"glawe_number",
"goldschmidt_class",
"group",
"group_id",
"hardness",
"heat_of_formation",
"inchi",
"init_on_load",
"ionenergies",
"ionic_radii",
"is_monoisotopic",
"is_radioactive",
"isotopes",
"jmol_color",
"lattice_constant",
"lattice_structure",
"mass",
"mass_number",
"mass_str",
"melting_point",
"mendeleev_number",
"metadata",
"metallic_radius",
"metallic_radius_c12",
"molar_heat_capacity",
"molcas_gv_color",
"name",
"name_origin",
"neutrons",
"nist_webbook_url",
"nvalence",
"oxidation_states",
"oxides",
"oxistates",
"period",
"pettifor_number",
"phase_transitions",
"proton_affinity",
"protons",
"registry",
"sconst",
"screening_constants",
"series",
"softness",
"sources",
"specific_heat",
"specific_heat_capacity",
"symbol",
"thermal_conductivity",
"uses",
"vdw_radius",
"vdw_radius_alvarez",
"vdw_radius_batsanov",
"vdw_radius_bondi",
"vdw_radius_dreiding",
"vdw_radius_mm3",
"vdw_radius_rt",
"vdw_radius_truhlar",
"vdw_radius_uff",
"zeff",
]


@lru_cache(maxsize=118)
def element(*args):
import mendeleev

return mendeleev.element(*args)


Expand All @@ -40,15 +158,14 @@ def __init__(self, sub):
"""
self._dataset = None
self.sub = sub
self._mendeleev_element = None
self._mendeleev_property_lst = None
self._element_str = None
stringtypes = str
if isinstance(self.sub, stringtypes):
self._init_mendeleev(self.sub)
self._element_str = self.sub
elif "Parent" in self.sub.index and isinstance(self.sub.Parent, stringtypes):
self._init_mendeleev(self.sub.Parent)
self._element_str = self.sub.Parent
elif len(self.sub) > 0:
self._init_mendeleev(self.sub.Abbreviation)
self._element_str = self.sub.Abbreviation

self._mendeleev_translation_dict = {
"AtomicNumber": "atomic_number",
Expand All @@ -70,12 +187,6 @@ def __init__(self, sub):
}
self.el = None

def _init_mendeleev(self, element_str):
self._mendeleev_element = element(str(element_str))
self._mendeleev_property_lst = [
s for s in dir(self._mendeleev_element) if not s.startswith("_")
]

def __getattr__(self, item):
if item in ["__array_struct__", "__array_interface__", "__array__"]:
raise AttributeError
Expand All @@ -84,8 +195,8 @@ def __getattr__(self, item):
def __getitem__(self, item):
if item in self._mendeleev_translation_dict.keys():
item = self._mendeleev_translation_dict[item]
if item in self._mendeleev_property_lst:
return getattr(self._mendeleev_element, item)
if item in MENDELEEV_PROPERTY_LIST:
return getattr(element(self._element_str), item)
if item in self.sub.index:
return self.sub[item]

Expand Down Expand Up @@ -189,10 +300,10 @@ def from_hdf(self, hdf):
if key in "Parent":
self.sub = pse.dataframe.loc[val]
self.sub["Parent"] = val
self._init_mendeleev(val)
self._element_str = val
else:
self.sub["Parent"] = None
self._init_mendeleev(elname)
self._element_str = elname
self.sub.name = elname
if "tagData" in hdf_el.list_groups():
with hdf_el.open(
Expand Down
12 changes: 6 additions & 6 deletions test_benchmarks/atomistics/structure/test_atoms.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ def test_cached_speed(self):
element.cache_clear()
PeriodicTable._get_periodic_table_df.cache_clear()
t1[i] = time.perf_counter()
Atoms(symbols="Al", positions=pos, cell=cell)
Atoms(symbols="Al", positions=pos, cell=cell).species[0].melting_point
t2[i] = time.perf_counter()
Atoms(symbols="Al", positions=pos, cell=cell)
Atoms(symbols="Al", positions=pos, cell=cell).species[0].melting_point
t3[i] = time.perf_counter()
Atoms(symbols="Cu", positions=pos, cell=cell)
Atoms(symbols="Cu", positions=pos, cell=cell).species[0].melting_point
t4[i] = time.perf_counter()
Atoms(symbols="CuAl", positions=[[0., 0., 0.], [0.5, 0.5, 0.5]], cell=cell)
Atoms(symbols="CuAl", positions=[[0., 0., 0.], [0.5, 0.5, 0.5]], cell=cell).species[0].melting_point
t5[i] = time.perf_counter()
Atoms(symbols="MgO", positions=[[0., 0., 0.], [0.5, 0.5, 0.5]], cell=cell)
Atoms(symbols="MgO", positions=[[0., 0., 0.], [0.5, 0.5, 0.5]], cell=cell).species[0].melting_point
t6[i] = time.perf_counter()
Atoms(symbols="AlMgO", positions=[[0., 0., 0.], [0.5, 0.5, 0.5], [0.5, 0.5, 0.]], cell=cell)
Atoms(symbols="AlMgO", positions=[[0., 0., 0.], [0.5, 0.5, 0.5], [0.5, 0.5, 0.]], cell=cell).species[0].melting_point
t7[i] = time.perf_counter()
dt21 = np.mean(t2 - t1)
dt32 = np.mean(t3 - t2)
Expand Down
7 changes: 6 additions & 1 deletion tests/atomic/structure/test_periodic_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import unittest
import os
from pyiron_atomistics.atomistics.structure.atoms import CrystalStructure
from pyiron_atomistics.atomistics.structure.periodic_table import PeriodicTable
from pyiron_atomistics.atomistics.structure.periodic_table import PeriodicTable, MENDELEEV_PROPERTY_LIST, element
from pyiron_base import Project


Expand Down Expand Up @@ -161,5 +161,10 @@ def test_ge__(self):
self.assertTrue(o_1 >= o_2)


class TestMendeleevInterface(unittest.TestCase):
def test_mendeleev_property_list(self):
self.assertEqual(MENDELEEV_PROPERTY_LIST, [s for s in dir(element("Al")) if not s.startswith("_")])


if __name__ == "__main__":
unittest.main()

0 comments on commit 938238d

Please sign in to comment.