From 576cc2fe36c1c32f32b33fe8d1bae397e22ad53f Mon Sep 17 00:00:00 2001 From: Marvin Poul Date: Thu, 4 Jul 2024 23:48:09 +0200 Subject: [PATCH 01/11] AbstractPotential: Use Resolver to find potentials --- .../atomistics/job/potentials.py | 127 ++++++++---------- pyiron_atomistics/lammps/potential.py | 37 +++-- pyiron_atomistics/vasp/potential.py | 10 +- 3 files changed, 74 insertions(+), 100 deletions(-) diff --git a/pyiron_atomistics/atomistics/job/potentials.py b/pyiron_atomistics/atomistics/job/potentials.py index 1d63c0ffd..e947a65f1 100644 --- a/pyiron_atomistics/atomistics/job/potentials.py +++ b/pyiron_atomistics/atomistics/job/potentials.py @@ -11,6 +11,7 @@ import pandas from pyiron_base import state +from pyiron_snippets.resources import ResourceResolver, ResourceNotFound __author__ = "Martin Boeckmann, Jan Janssen" __copyright__ = ( @@ -115,44 +116,38 @@ def _get_potential_df(plugin_name, file_name_lst): """ env = os.environ resource_path_lst = state.settings.resource_paths - for conda_var in ["CONDA_PREFIX", "CONDA_DIR"]: - if conda_var in env.keys(): # support iprpy-data package - path_to_add = os.path.join(env[conda_var], "share", "iprpy") - if path_to_add not in resource_path_lst: - resource_path_lst += [path_to_add] - df_lst = [] - for resource_path in resource_path_lst: - if os.path.exists(os.path.join(resource_path, plugin_name, "potentials")): - resource_path = os.path.join(resource_path, plugin_name, "potentials") - if "potentials" in resource_path or "iprpy" in resource_path: - for path, folder_lst, file_lst in os.walk(resource_path): - for periodic_table_file_name in file_name_lst: - if ( - periodic_table_file_name in file_lst - and periodic_table_file_name.endswith(".csv") - ): - df_lst.append( - pandas.read_csv( - os.path.join(path, periodic_table_file_name), - index_col=0, - converters={ - "Species": lambda x: x.replace("'", "") - .strip("[]") - .split(", "), - "Config": lambda x: x.replace("'", "") - .replace("\\n", "\n") - .strip("[]") - .split(", "), - "Filename": lambda x: x.replace("'", "") - .strip("[]") - .split(", "), - }, - ) - ) - if len(df_lst) > 0: - return pandas.concat(df_lst) - else: - raise ValueError("Was not able to locate the potential files.") + def read_csv(path): + return pandas.read_csv( + path, + index_col=0, + converters={ + "Species": lambda x: x.replace("'", "") + .strip("[]") + .split(", "), + "Config": lambda x: x.replace("'", "") + .replace("\\n", "\n") + .strip("[]") + .split(", "), + "Filename": lambda x: x.replace("'", "") + .strip("[]") + .split(", "), + }, + ) + files = ResourceResolver( + resource_path_lst, + plugin_name, "potentials", + ).chain( + # support iprpy-data package; data paths in the iprpy are of a different form than in + # pyiron resources, so we cannot add it as an additional path to the resolver above. + # Instead make a new resolver and chain it after the first one. + # TODO: this is a fix specific for lammps potentials; it could be moved to the lammps + # subclass + ResourceResolver( + [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], + "share", "iprpy", + ), + ).search(file_name_lst) + return pandas.concat(map(read_csv, files), ignore_index=True) @staticmethod def _get_potential_default_df( @@ -168,42 +163,26 @@ def _get_potential_default_df( Returns: pandas.DataFrame: """ - for resource_path in state.settings.resource_paths: - pot_path = os.path.join(resource_path, plugin_name, "potentials") - if os.path.exists(pot_path): - resource_path = pot_path - if "potentials" in resource_path: - for path, folder_lst, file_lst in os.walk(resource_path): - for periodic_table_file_name in file_name_lst: - if ( - periodic_table_file_name in file_lst - and periodic_table_file_name.endswith(".csv") - ): - return pandas.read_csv( - os.path.join(path, periodic_table_file_name), - index_col=0, - ) - elif ( - periodic_table_file_name in file_lst - and periodic_table_file_name.endswith(".h5") - ): - return pandas.read_hdf( - os.path.join(path, periodic_table_file_name), mode="r" - ) - raise ValueError("Was not able to locate the potential files.") + try: + file = ResourceResolver( + state.settings.resource_paths, + plugin_name, "potentials", + ).first(file_name_lst) + return pandas.read_csv(file, index_col=0) + except ResourceNotFound: + raise ValueError("Was not able to locate the potential files.") from None def find_potential_file_base(path, resource_path_lst, rel_path): - if path is not None: - for resource_path in resource_path_lst: - path_direct = os.path.join(resource_path, path) - path_indirect = os.path.join(resource_path, rel_path, path) - if os.path.exists(path_direct): - return path_direct - elif os.path.exists(path_indirect): - return path_indirect - raise ValueError( - "Either the filename or the functional has to be defined.", - path, - resource_path_lst, - ) + try: + return ResourceResolver( + resource_path_lst, + rel_path, + name=path + ).first() + except ResourceNotFound: + raise ValueError( + "Either the filename or the functional has to be defined.", + path, + resource_path_lst, + ) from None diff --git a/pyiron_atomistics/lammps/potential.py b/pyiron_atomistics/lammps/potential.py index 04a80c4dc..7022c539f 100644 --- a/pyiron_atomistics/lammps/potential.py +++ b/pyiron_atomistics/lammps/potential.py @@ -11,9 +11,9 @@ from pyiron_atomistics.atomistics.job.potentials import ( PotentialAbstract, - find_potential_file_base, ) from pyiron_atomistics.atomistics.structure.atoms import Atoms +from pyiron_snippets.resources import ResourceResolver, ResourceNotFound __author__ = "Joerg Neugebauer, Sudarsan Surendralal, Jan Janssen" __copyright__ = ( @@ -77,27 +77,24 @@ def files(self): for files in list(self._df["Filename"])[0] if not os.path.isabs(files) ] - env = os.environ - resource_path_lst = state.settings.resource_paths - for conda_var in ["CONDA_PREFIX", "CONDA_DIR"]: - if conda_var in env.keys(): # support iprpy-data package - path_to_add = state.settings.convert_path_to_abs_posix( - os.path.join(env[conda_var], "share", "iprpy") - ) - if path_to_add not in resource_path_lst: - resource_path_lst.append(path_to_add) for path in relative_file_paths: - absolute_file_paths.append( - find_potential_file_base( - path=path, - resource_path_lst=resource_path_lst, - rel_path=os.path.join("lammps", "potentials"), - ) + resolver = ResourceResolver( + state.settings.resource_paths, + "lammps", "potentials", + ).chain( + # support iprpy-data package; data paths in the iprpy are of a different form than in + # pyiron resources, so we cannot add it as an additional path to the resolver above. + # Instead make a new resolver and chain it after the first one. + ResourceResolver( + [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], + "share", "iprpy", + ), ) - if len(absolute_file_paths) != len(list(self._df["Filename"])[0]): - raise ValueError("Was not able to locate the potentials.") - else: - return absolute_file_paths + try: + absolute_file_paths.append(resolver.first(path)) + except ResourceNotFound: + raise ValueError("Was not able to locate the potentials.") from None + return absolute_file_paths def copy_pot_files(self, working_directory): if self.files is not None: diff --git a/pyiron_atomistics/vasp/potential.py b/pyiron_atomistics/vasp/potential.py index 3629f384e..fcef76809 100644 --- a/pyiron_atomistics/vasp/potential.py +++ b/pyiron_atomistics/vasp/potential.py @@ -12,7 +12,6 @@ from pyiron_atomistics.atomistics.job.potentials import ( PotentialAbstract, - find_potential_file_base, ) __author__ = "Jan Janssen" @@ -268,11 +267,10 @@ def __repr__(self): def find_potential_file(path): - return find_potential_file_base( - path=path, - resource_path_lst=state.settings.resource_paths, - rel_path=os.path.join("vasp", "potentials"), - ) + return ResourceResolver( + state.settings.resource_paths, + "vasp", "potentials", + ).first(path) @deprecate( From 7965f3d4c81158760d76aa6dfedc7ce21e2b1a54 Mon Sep 17 00:00:00 2001 From: Marvin Poul Date: Fri, 19 Jul 2024 12:58:06 +0200 Subject: [PATCH 02/11] Use resolvers in lammps/vasp/sphinx --- .../atomistics/job/potentials.py | 4 +-- pyiron_atomistics/lammps/potential.py | 29 +++++++++---------- pyiron_atomistics/sphinx/potential.py | 27 +++++++---------- pyiron_atomistics/vasp/potential.py | 24 ++++++--------- 4 files changed, 35 insertions(+), 49 deletions(-) diff --git a/pyiron_atomistics/atomistics/job/potentials.py b/pyiron_atomistics/atomistics/job/potentials.py index e947a65f1..8892ce419 100644 --- a/pyiron_atomistics/atomistics/job/potentials.py +++ b/pyiron_atomistics/atomistics/job/potentials.py @@ -172,14 +172,12 @@ def _get_potential_default_df( except ResourceNotFound: raise ValueError("Was not able to locate the potential files.") from None - def find_potential_file_base(path, resource_path_lst, rel_path): try: return ResourceResolver( resource_path_lst, rel_path, - name=path - ).first() + ).first(path) except ResourceNotFound: raise ValueError( "Either the filename or the functional has to be defined.", diff --git a/pyiron_atomistics/lammps/potential.py b/pyiron_atomistics/lammps/potential.py index 7022c539f..c0ac36e44 100644 --- a/pyiron_atomistics/lammps/potential.py +++ b/pyiron_atomistics/lammps/potential.py @@ -10,7 +10,7 @@ from pyiron_base import GenericParameters, state from pyiron_atomistics.atomistics.job.potentials import ( - PotentialAbstract, + PotentialAbstract ) from pyiron_atomistics.atomistics.structure.atoms import Atoms from pyiron_snippets.resources import ResourceResolver, ResourceNotFound @@ -26,7 +26,6 @@ __status__ = "production" __date__ = "Sep 1, 2017" - class LammpsPotential(GenericParameters): """ This module helps write commands which help in the control of parameters related to the potential used in LAMMPS @@ -66,6 +65,16 @@ def remove_structure_block(self): @property def files(self): + env = os.environ + resolver = ResourceResolver( + state.settings.resource_paths, + "lammps", "potentials", + ).chain( + ResourceResolver( + [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], + "share", "iprpy", + ) + ) if len(self._df["Filename"].values[0]) > 0 and self._df["Filename"].values[ 0 ] != [""]: @@ -78,20 +87,10 @@ def files(self): if not os.path.isabs(files) ] for path in relative_file_paths: - resolver = ResourceResolver( - state.settings.resource_paths, - "lammps", "potentials", - ).chain( - # support iprpy-data package; data paths in the iprpy are of a different form than in - # pyiron resources, so we cannot add it as an additional path to the resolver above. - # Instead make a new resolver and chain it after the first one. - ResourceResolver( - [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], - "share", "iprpy", - ), - ) try: - absolute_file_paths.append(resolver.first(path)) + absolute_file_paths.append( + resolver.first(path) + ) except ResourceNotFound: raise ValueError("Was not able to locate the potentials.") from None return absolute_file_paths diff --git a/pyiron_atomistics/sphinx/potential.py b/pyiron_atomistics/sphinx/potential.py index 8e58ff123..ab1c93d2f 100644 --- a/pyiron_atomistics/sphinx/potential.py +++ b/pyiron_atomistics/sphinx/potential.py @@ -6,11 +6,8 @@ import pandas from pyiron_base import state - -from pyiron_atomistics.vasp.potential import ( - VaspPotentialAbstract, - find_potential_file_base, -) +from pyiron_atomistics.vasp.potential import VaspPotentialAbstract +from pyiron_snippets.resources import ResourceResolver, ResourceNotFound __author__ = "Osamu Waseda" __copyright__ = ( @@ -80,14 +77,12 @@ def add_new_element(self, parent_element, new_element): def find_potential_file(path): env = os.environ - resource_path_lst = state.settings.resource_paths - for conda_var in ["CONDA_PREFIX", "CONDA_DIR"]: - if conda_var in env.keys(): # support sphinx-data package - path_to_add = os.path.join(env[conda_var], "share", "sphinxdft") - if path_to_add not in resource_path_lst: - resource_path_lst += [path_to_add] - return find_potential_file_base( - path=path, - resource_path_lst=resource_path_lst, - rel_path=os.path.join("sphinx", "potentials"), - ) + return ResourceResolver( + state.settings.resource_paths, + "sphinx", "potentials" + ).chain( + ResourceResolver( + [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], + "share", "sphinxdft", + ) + ).first(path) diff --git a/pyiron_atomistics/vasp/potential.py b/pyiron_atomistics/vasp/potential.py index fcef76809..12b56abdf 100644 --- a/pyiron_atomistics/vasp/potential.py +++ b/pyiron_atomistics/vasp/potential.py @@ -9,6 +9,7 @@ import pandas from pyiron_base import GenericParameters, state from pyiron_snippets.deprecate import deprecate +from pyiron_snippets.resources import ResourceResolver, ResourceNotFound from pyiron_atomistics.atomistics.job.potentials import ( PotentialAbstract, @@ -120,16 +121,6 @@ def list_potential_names(self): else: return [] - @staticmethod - def _return_potential_file(file_name): - for resource_path in state.settings.resource_paths: - resource_path_potcar = os.path.join( - resource_path, "vasp", "potentials", file_name - ) - if os.path.exists(resource_path_potcar): - return resource_path_potcar - return None - def __dir__(self): return [val.replace("-", "_") for val in self.list_potential_names()] @@ -137,7 +128,7 @@ def __getitem__(self, item): item_replace = item.replace("_gga_pbe", "-gga-pbe").replace("_lda", "-lda") if item_replace in self.list_potential_names(): df = self.list() - return self._return_potential_file( + return return_potential_file( file_name=list(df[df["Name"] == item_replace]["Filename"])[0][0] ) selected_atoms = self._selected_atoms + [item] @@ -267,10 +258,13 @@ def __repr__(self): def find_potential_file(path): - return ResourceResolver( - state.settings.resource_paths, - "vasp", "potentials", - ).first(path) + try: + return ResourceResolver( + state.settings.resource_paths, + "vasp", "potentials", + ).first(path) + except ResourceNotFound: + return None @deprecate( From ee43fdfc5730002f41df32d4b161a8b1a929c331 Mon Sep 17 00:00:00 2001 From: Marvin Poul Date: Fri, 16 Aug 2024 09:07:21 +0200 Subject: [PATCH 03/11] Bump lower version supported of pyiron_snippets Otherwise we do not get to import the resolvers. --- .ci_support/environment-old.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci_support/environment-old.yml b/.ci_support/environment-old.yml index 731d8fae1..fd0d49f4a 100644 --- a/.ci_support/environment-old.yml +++ b/.ci_support/environment-old.yml @@ -14,7 +14,7 @@ dependencies: - phonopy =2.20.0 - pint =0.18 - pyiron_base =0.9.4 -- pyiron_snippets =0.1.1 +- pyiron_snippets =0.1.3 - pylammpsmpi =0.2.18 - pyscal3 =3.2.5 - monty =2024.3.31 From 4dbd838a279abde4a62f5f6910385db03fcccfb2 Mon Sep 17 00:00:00 2001 From: Marvin Poul Date: Fri, 16 Aug 2024 09:13:05 +0200 Subject: [PATCH 04/11] Pull pyiron_base lower bound up as well base 0.9.12 needs the resolvers as well, so it makes no sense to have this bound lower. --- .ci_support/environment-old.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci_support/environment-old.yml b/.ci_support/environment-old.yml index fd0d49f4a..46da1cf3d 100644 --- a/.ci_support/environment-old.yml +++ b/.ci_support/environment-old.yml @@ -13,7 +13,7 @@ dependencies: - pandas =2.0.3 - phonopy =2.20.0 - pint =0.18 -- pyiron_base =0.9.4 +- pyiron_base =0.9.12 - pyiron_snippets =0.1.3 - pylammpsmpi =0.2.18 - pyscal3 =3.2.5 From b00fb4b29ef6ab4b7fc90e96c47a7c1b8a144bfb Mon Sep 17 00:00:00 2001 From: Marvin Poul Date: Thu, 15 Aug 2024 20:48:02 +0200 Subject: [PATCH 05/11] Extract ResourceResolver into class method --- .../atomistics/job/potentials.py | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/pyiron_atomistics/atomistics/job/potentials.py b/pyiron_atomistics/atomistics/job/potentials.py index 8892ce419..03639411b 100644 --- a/pyiron_atomistics/atomistics/job/potentials.py +++ b/pyiron_atomistics/atomistics/job/potentials.py @@ -103,8 +103,25 @@ def __getitem__(self, item): def __str__(self): return str(self.list()) - @staticmethod - def _get_potential_df(plugin_name, file_name_lst): + @classmethod + def _get_resolver(cls, plugin_name): + """Return a ResourceResolver that can be searched for potential files or potential dataframes. + + This exists primarily so that the lammps and sphinx sub classes can overload it to add their conda package + specific resource paths. + + Args: + plugin_name (str): one of "lammps", "vasp", "sphinx"; i.e. the name of the resource folder to search + Returns: + :class:`.ResourceResolver` + """ + return ResourceResolver( + state.settings.resource_paths, + plugin_name, "potentials", + ) + + @classmethod + def _get_potential_df(cls, plugin_name, file_name_lst): """ Args: @@ -115,7 +132,6 @@ def _get_potential_df(plugin_name, file_name_lst): pandas.DataFrame: """ env = os.environ - resource_path_lst = state.settings.resource_paths def read_csv(path): return pandas.read_csv( path, @@ -133,10 +149,7 @@ def read_csv(path): .split(", "), }, ) - files = ResourceResolver( - resource_path_lst, - plugin_name, "potentials", - ).chain( + files = cls._get_resolver(plugin_name).chain( # support iprpy-data package; data paths in the iprpy are of a different form than in # pyiron resources, so we cannot add it as an additional path to the resolver above. # Instead make a new resolver and chain it after the first one. From d7e3f1af56c441a17c02c2114150e889a20e4aaa Mon Sep 17 00:00:00 2001 From: Marvin Poul Date: Thu, 15 Aug 2024 21:30:46 +0200 Subject: [PATCH 06/11] Pull find_potential_file into PotentialAbstract This requires a new class attribute resource_plugin_name, so that it does not have to passed to _get_resolver anymore --- .../atomistics/job/potentials.py | 51 ++++++++----------- pyiron_atomistics/lammps/potential.py | 23 +++++---- pyiron_atomistics/sphinx/base.py | 14 ++--- pyiron_atomistics/sphinx/potential.py | 26 +++++----- pyiron_atomistics/vasp/potential.py | 4 +- 5 files changed, 51 insertions(+), 67 deletions(-) diff --git a/pyiron_atomistics/atomistics/job/potentials.py b/pyiron_atomistics/atomistics/job/potentials.py index 03639411b..cc4d0f144 100644 --- a/pyiron_atomistics/atomistics/job/potentials.py +++ b/pyiron_atomistics/atomistics/job/potentials.py @@ -7,6 +7,7 @@ OpenKim https://openkim.org database. """ +from abc import ABC, abstractmethod import os import pandas @@ -25,7 +26,7 @@ __date__ = "Sep 1, 2017" -class PotentialAbstract(object): +class PotentialAbstract(ABC): """ The PotentialAbstract class loads a list of available potentials and sorts them. Afterwards the potentials can be accessed through: @@ -37,6 +38,14 @@ class PotentialAbstract(object): selected_atoms: """ + @property + @abstractmethod + def resource_plugin_name(self) -> str: + """Return the name of the folder of this plugin/code in the pyiron resources. + + One of lammps/vasp/sphinx, to be overriden in the specific sub classes.""" + pass + def __init__(self, potential_df, default_df=None, selected_atoms=None): self._potential_df = potential_df self._default_df = default_df @@ -104,28 +113,25 @@ def __str__(self): return str(self.list()) @classmethod - def _get_resolver(cls, plugin_name): + def _get_resolver(cls): """Return a ResourceResolver that can be searched for potential files or potential dataframes. This exists primarily so that the lammps and sphinx sub classes can overload it to add their conda package specific resource paths. - Args: - plugin_name (str): one of "lammps", "vasp", "sphinx"; i.e. the name of the resource folder to search Returns: :class:`.ResourceResolver` """ return ResourceResolver( state.settings.resource_paths, - plugin_name, "potentials", + cls.resource_plugin_name, "potentials", ) @classmethod - def _get_potential_df(cls, plugin_name, file_name_lst): + def _get_potential_df(cls, file_name_lst): """ Args: - plugin_name (str): file_name_lst (set): Returns: @@ -149,17 +155,7 @@ def read_csv(path): .split(", "), }, ) - files = cls._get_resolver(plugin_name).chain( - # support iprpy-data package; data paths in the iprpy are of a different form than in - # pyiron resources, so we cannot add it as an additional path to the resolver above. - # Instead make a new resolver and chain it after the first one. - # TODO: this is a fix specific for lammps potentials; it could be moved to the lammps - # subclass - ResourceResolver( - [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], - "share", "iprpy", - ), - ).search(file_name_lst) + files = cls._get_resolver().search(file_name_lst) return pandas.concat(map(read_csv, files), ignore_index=True) @staticmethod @@ -185,15 +181,10 @@ def _get_potential_default_df( except ResourceNotFound: raise ValueError("Was not able to locate the potential files.") from None -def find_potential_file_base(path, resource_path_lst, rel_path): - try: - return ResourceResolver( - resource_path_lst, - rel_path, - ).first(path) - except ResourceNotFound: - raise ValueError( - "Either the filename or the functional has to be defined.", - path, - resource_path_lst, - ) from None + @classmethod + def find_potential_file(cls, path): + res = cls._get_resolver() + try: + return res.first(path) + except ResourceNotFound: + raise ValueError(f"Could not find file '{path}' in {res}!") from None diff --git a/pyiron_atomistics/lammps/potential.py b/pyiron_atomistics/lammps/potential.py index c0ac36e44..96475e292 100644 --- a/pyiron_atomistics/lammps/potential.py +++ b/pyiron_atomistics/lammps/potential.py @@ -66,15 +66,7 @@ def remove_structure_block(self): @property def files(self): env = os.environ - resolver = ResourceResolver( - state.settings.resource_paths, - "lammps", "potentials", - ).chain( - ResourceResolver( - [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], - "share", "iprpy", - ) - ) + resolver = LammpsPotentialFile._get_resolver() if len(self._df["Filename"].values[0]) > 0 and self._df["Filename"].values[ 0 ] != [""]: @@ -247,10 +239,21 @@ class LammpsPotentialFile(PotentialAbstract): selected_atoms: """ + resource_plugin_name = "lammps" + + @classmethod + def _get_resolver(cls): + env = os.environ + return super()._get_resolver().chain( + ResourceResolver( + [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], + "share", "iprpy", + ) + ) + def __init__(self, potential_df=None, default_df=None, selected_atoms=None): if potential_df is None: potential_df = self._get_potential_df( - plugin_name="lammps", file_name_lst={"potentials_lammps.csv"}, ) super(LammpsPotentialFile, self).__init__( diff --git a/pyiron_atomistics/sphinx/base.py b/pyiron_atomistics/sphinx/base.py index abc4e3b09..48ed204a1 100644 --- a/pyiron_atomistics/sphinx/base.py +++ b/pyiron_atomistics/sphinx/base.py @@ -38,9 +38,6 @@ collect_spins_dat, ) from pyiron_atomistics.sphinx.potential import SphinxJTHPotentialFile -from pyiron_atomistics.sphinx.potential import ( - find_potential_file as find_potential_file_jth, -) from pyiron_atomistics.sphinx.structure import read_atoms from pyiron_atomistics.sphinx.util import sxversions from pyiron_atomistics.sphinx.volumetric_data import SphinxVolumetricData @@ -49,9 +46,6 @@ VaspPotentialSetter, strip_xc_from_potential_name, ) -from pyiron_atomistics.vasp.potential import ( - find_potential_file as find_potential_file_vasp, -) __author__ = "Osamu Waseda, Jan Janssen" __copyright__ = ( @@ -1293,11 +1287,9 @@ def _get_potential_path( if potformat == "JTH": potentials = SphinxJTHPotentialFile(xc=xc) - find_potential_file = find_potential_file_jth pot_path_dict.setdefault("PBE", "jth-gga-pbe") elif potformat == "VASP": potentials = VaspPotentialFile(xc=xc) - find_potential_file = find_potential_file_vasp pot_path_dict.setdefault("PBE", "paw-gga-pbe") pot_path_dict.setdefault("LDA", "paw-lda") else: @@ -1313,7 +1305,7 @@ def _get_potential_path( if "pseudo_potcar_file" in species_obj.tags.keys(): new_element = species_obj.tags["pseudo_potcar_file"] potentials.add_new_element(parent_element=elem, new_element=new_element) - potential_path = find_potential_file( + potential_path = potentials.find_potential_file( path=potentials.find_default(new_element)["Filename"].values[0][0] ) assert os.path.isfile( @@ -1327,14 +1319,14 @@ def _get_potential_path( potentials.add_new_element( parent_element=elem, new_element=new_element ) - potential_path = find_potential_file( + potential_path = potentials.find_potential_file( path=potentials.find_default(new_element)["Filename"].values[0][ 0 ] ) else: ori_paths.append( - find_potential_file( + potentials.find_potential_file( path=potentials.find_default(elem)["Filename"].values[0][0] ) ) diff --git a/pyiron_atomistics/sphinx/potential.py b/pyiron_atomistics/sphinx/potential.py index ab1c93d2f..31ec82939 100644 --- a/pyiron_atomistics/sphinx/potential.py +++ b/pyiron_atomistics/sphinx/potential.py @@ -30,9 +30,20 @@ class SphinxJTHPotentialFile(VaspPotentialAbstract): xc (str): Exchange correlation functional ['PBE', 'LDA'] """ + resource_plugin_name = "sphinx" + + @classmethod + def _get_resolver(cls): + env = os.environ + return super()._get_resolver().chain( + ResourceResolver( + [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], + "share", "sphinxdft", + ) + ) + def __init__(self, xc=None, selected_atoms=None): potential_df = self._get_potential_df( - plugin_name="sphinx", file_name_lst={"potentials_sphinx.csv"}, ) if xc == "PBE": @@ -73,16 +84,3 @@ def add_new_element(self, parent_element, new_element): ds.name = new_element ds["Name"] = "-".join(name_list) self._default_df = self._default_df.append(ds) - - -def find_potential_file(path): - env = os.environ - return ResourceResolver( - state.settings.resource_paths, - "sphinx", "potentials" - ).chain( - ResourceResolver( - [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], - "share", "sphinxdft", - ) - ).first(path) diff --git a/pyiron_atomistics/vasp/potential.py b/pyiron_atomistics/vasp/potential.py index 12b56abdf..b5961a176 100644 --- a/pyiron_atomistics/vasp/potential.py +++ b/pyiron_atomistics/vasp/potential.py @@ -36,10 +36,11 @@ class VaspPotentialAbstract(PotentialAbstract): selected_atoms: """ + resource_plugin_name = "vasp" + def __init__(self, potential_df=None, default_df=None, selected_atoms=None): if potential_df is None: potential_df = self._get_potential_df( - plugin_name="vasp", file_name_lst={"potentials_vasp.csv"}, ) super(VaspPotentialAbstract, self).__init__( @@ -150,7 +151,6 @@ class VaspPotentialFile(VaspPotentialAbstract): def __init__(self, xc=None, selected_atoms=None): potential_df = self._get_potential_df( - plugin_name="vasp", file_name_lst={"potentials_vasp.csv"}, ) if xc == "PBE": From 37b816980e9a3d3d44cc3268c166119809bac279 Mon Sep 17 00:00:00 2001 From: Marvin Poul Date: Thu, 15 Aug 2024 21:41:26 +0200 Subject: [PATCH 07/11] Use PotentialAbstract.find_potential_file in Vasp --- pyiron_atomistics/vasp/potential.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/pyiron_atomistics/vasp/potential.py b/pyiron_atomistics/vasp/potential.py index b5961a176..c15df37ae 100644 --- a/pyiron_atomistics/vasp/potential.py +++ b/pyiron_atomistics/vasp/potential.py @@ -257,16 +257,6 @@ def __repr__(self): return self._potential_dict.__repr__() -def find_potential_file(path): - try: - return ResourceResolver( - state.settings.resource_paths, - "vasp", "potentials", - ).first(path) - except ResourceNotFound: - return None - - @deprecate( "use get_enmax_among_potentials and note the adjustment to the signature (*args instead of list)" ) @@ -333,7 +323,7 @@ def _get_potcar_filename(name, exch_corr): enmax_lst = [] for n in names: - with open(find_potential_file(path=_get_potcar_filename(n, xc))) as pf: + with open(self.vasp_potentials.find_potential_file(path=_get_potcar_filename(n, xc))) as pf: for i, line in enumerate(pf): if i == 14: encut_str = line.split()[2][:-1] @@ -431,7 +421,7 @@ def _set_potential_paths(self): self.vasp_potentials.add_new_element( parent_element=el, new_element=new_element ) - el_path = find_potential_file( + el_path = self.vasp_potentials.find_potential_file( path=self.vasp_potentials.find_default(new_element)[ "Filename" ].values[0][0] @@ -446,13 +436,13 @@ def _set_potential_paths(self): self.vasp_potentials.add_new_element( parent_element=el, new_element=new_element ) - el_path = find_potential_file( + el_path = self.vasp_potentials.find_potential_file( path=self.vasp_potentials.find_default(new_element)[ "Filename" ].values[0][0] ) else: - el_path = find_potential_file( + el_path = self.vasp_potentials.find_potential_file( path=self.vasp_potentials.find_default(el)["Filename"].values[0][0] ) From 12fca3dd25efd7593c250a346b13c9d0a2b7ca66 Mon Sep 17 00:00:00 2001 From: Marvin Poul Date: Thu, 15 Aug 2024 21:47:45 +0200 Subject: [PATCH 08/11] Use _get_resolver in _get_potential_default_df --- pyiron_atomistics/atomistics/job/potentials.py | 12 +++--------- pyiron_atomistics/sphinx/potential.py | 1 - pyiron_atomistics/vasp/potential.py | 3 --- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/pyiron_atomistics/atomistics/job/potentials.py b/pyiron_atomistics/atomistics/job/potentials.py index cc4d0f144..b43e64a84 100644 --- a/pyiron_atomistics/atomistics/job/potentials.py +++ b/pyiron_atomistics/atomistics/job/potentials.py @@ -158,26 +158,20 @@ def read_csv(path): files = cls._get_resolver().search(file_name_lst) return pandas.concat(map(read_csv, files), ignore_index=True) - @staticmethod + @classmethod def _get_potential_default_df( - plugin_name, - file_name_lst={"potentials_vasp_pbe_default.csv"}, + cls, file_name_lst={"potentials_vasp_pbe_default.csv"}, ): """ Args: - plugin_name (str): file_name_lst (set): Returns: pandas.DataFrame: """ try: - file = ResourceResolver( - state.settings.resource_paths, - plugin_name, "potentials", - ).first(file_name_lst) - return pandas.read_csv(file, index_col=0) + return pandas.read_csv(cls._get_resolver().first(file_name_lst), index_col=0) except ResourceNotFound: raise ValueError("Was not able to locate the potential files.") from None diff --git a/pyiron_atomistics/sphinx/potential.py b/pyiron_atomistics/sphinx/potential.py index 31ec82939..50ac41f41 100644 --- a/pyiron_atomistics/sphinx/potential.py +++ b/pyiron_atomistics/sphinx/potential.py @@ -48,7 +48,6 @@ def __init__(self, xc=None, selected_atoms=None): ) if xc == "PBE": default_df = self._get_potential_default_df( - plugin_name="sphinx", file_name_lst={"potentials_sphinx_jth_default.csv"}, ) potential_df = potential_df[(potential_df["Model"] == "jth-gga-pbe")] diff --git a/pyiron_atomistics/vasp/potential.py b/pyiron_atomistics/vasp/potential.py index c15df37ae..bcadb6a21 100644 --- a/pyiron_atomistics/vasp/potential.py +++ b/pyiron_atomistics/vasp/potential.py @@ -155,19 +155,16 @@ def __init__(self, xc=None, selected_atoms=None): ) if xc == "PBE": default_df = self._get_potential_default_df( - plugin_name="vasp", file_name_lst={"potentials_vasp_pbe_default.csv"}, ) potential_df = potential_df[(potential_df["Model"] == "gga-pbe")] elif xc == "GGA": default_df = self._get_potential_default_df( - plugin_name="vasp", file_name_lst={"potentials_vasp_pbe_default.csv"}, ) potential_df = potential_df[(potential_df["Model"] == "gga-pbe")] elif xc == "LDA": default_df = self._get_potential_default_df( - plugin_name="vasp", file_name_lst={"potentials_vasp_lda_default.csv"}, ) potential_df = potential_df[(potential_df["Model"] == "lda")] From 964639f3d6461e96da0ff79f590dab77cb7a0356 Mon Sep 17 00:00:00 2001 From: Marvin Poul Date: Thu, 15 Aug 2024 21:56:12 +0200 Subject: [PATCH 09/11] Clean up imports and use find_potential_file in lammps --- pyiron_atomistics/lammps/potential.py | 10 ++-------- pyiron_atomistics/sphinx/potential.py | 2 +- pyiron_atomistics/vasp/potential.py | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/pyiron_atomistics/lammps/potential.py b/pyiron_atomistics/lammps/potential.py index 96475e292..680d54a23 100644 --- a/pyiron_atomistics/lammps/potential.py +++ b/pyiron_atomistics/lammps/potential.py @@ -13,7 +13,7 @@ PotentialAbstract ) from pyiron_atomistics.atomistics.structure.atoms import Atoms -from pyiron_snippets.resources import ResourceResolver, ResourceNotFound +from pyiron_snippets.resources import ResourceResolver __author__ = "Joerg Neugebauer, Sudarsan Surendralal, Jan Janssen" __copyright__ = ( @@ -66,7 +66,6 @@ def remove_structure_block(self): @property def files(self): env = os.environ - resolver = LammpsPotentialFile._get_resolver() if len(self._df["Filename"].values[0]) > 0 and self._df["Filename"].values[ 0 ] != [""]: @@ -79,12 +78,7 @@ def files(self): if not os.path.isabs(files) ] for path in relative_file_paths: - try: - absolute_file_paths.append( - resolver.first(path) - ) - except ResourceNotFound: - raise ValueError("Was not able to locate the potentials.") from None + absolute_file_paths.append(LammpsPotentialFile.find_potential_file(path)) return absolute_file_paths def copy_pot_files(self, working_directory): diff --git a/pyiron_atomistics/sphinx/potential.py b/pyiron_atomistics/sphinx/potential.py index 50ac41f41..ff7d65419 100644 --- a/pyiron_atomistics/sphinx/potential.py +++ b/pyiron_atomistics/sphinx/potential.py @@ -7,7 +7,7 @@ import pandas from pyiron_base import state from pyiron_atomistics.vasp.potential import VaspPotentialAbstract -from pyiron_snippets.resources import ResourceResolver, ResourceNotFound +from pyiron_snippets.resources import ResourceResolver __author__ = "Osamu Waseda" __copyright__ = ( diff --git a/pyiron_atomistics/vasp/potential.py b/pyiron_atomistics/vasp/potential.py index bcadb6a21..79282b1d4 100644 --- a/pyiron_atomistics/vasp/potential.py +++ b/pyiron_atomistics/vasp/potential.py @@ -9,7 +9,7 @@ import pandas from pyiron_base import GenericParameters, state from pyiron_snippets.deprecate import deprecate -from pyiron_snippets.resources import ResourceResolver, ResourceNotFound +from pyiron_snippets.resources import ResourceResolver from pyiron_atomistics.atomistics.job.potentials import ( PotentialAbstract, From eb2e359d23fdc52f229a894c7d447681f541b1d1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 09:19:19 +0000 Subject: [PATCH 10/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../atomistics/job/potentials.py | 42 ++++++++++--------- pyiron_atomistics/lammps/potential.py | 24 +++++++---- pyiron_atomistics/sphinx/potential.py | 16 ++++--- pyiron_atomistics/vasp/potential.py | 4 +- 4 files changed, 51 insertions(+), 35 deletions(-) diff --git a/pyiron_atomistics/atomistics/job/potentials.py b/pyiron_atomistics/atomistics/job/potentials.py index b43e64a84..ab499d4f4 100644 --- a/pyiron_atomistics/atomistics/job/potentials.py +++ b/pyiron_atomistics/atomistics/job/potentials.py @@ -7,12 +7,12 @@ OpenKim https://openkim.org database. """ -from abc import ABC, abstractmethod import os +from abc import ABC, abstractmethod import pandas from pyiron_base import state -from pyiron_snippets.resources import ResourceResolver, ResourceNotFound +from pyiron_snippets.resources import ResourceNotFound, ResourceResolver __author__ = "Martin Boeckmann, Jan Janssen" __copyright__ = ( @@ -123,8 +123,9 @@ def _get_resolver(cls): :class:`.ResourceResolver` """ return ResourceResolver( - state.settings.resource_paths, - cls.resource_plugin_name, "potentials", + state.settings.resource_paths, + cls.resource_plugin_name, + "potentials", ) @classmethod @@ -138,29 +139,28 @@ def _get_potential_df(cls, file_name_lst): pandas.DataFrame: """ env = os.environ + def read_csv(path): return pandas.read_csv( - path, - index_col=0, - converters={ - "Species": lambda x: x.replace("'", "") - .strip("[]") - .split(", "), - "Config": lambda x: x.replace("'", "") - .replace("\\n", "\n") - .strip("[]") - .split(", "), - "Filename": lambda x: x.replace("'", "") - .strip("[]") - .split(", "), - }, + path, + index_col=0, + converters={ + "Species": lambda x: x.replace("'", "").strip("[]").split(", "), + "Config": lambda x: x.replace("'", "") + .replace("\\n", "\n") + .strip("[]") + .split(", "), + "Filename": lambda x: x.replace("'", "").strip("[]").split(", "), + }, ) + files = cls._get_resolver().search(file_name_lst) return pandas.concat(map(read_csv, files), ignore_index=True) @classmethod def _get_potential_default_df( - cls, file_name_lst={"potentials_vasp_pbe_default.csv"}, + cls, + file_name_lst={"potentials_vasp_pbe_default.csv"}, ): """ @@ -171,7 +171,9 @@ def _get_potential_default_df( pandas.DataFrame: """ try: - return pandas.read_csv(cls._get_resolver().first(file_name_lst), index_col=0) + return pandas.read_csv( + cls._get_resolver().first(file_name_lst), index_col=0 + ) except ResourceNotFound: raise ValueError("Was not able to locate the potential files.") from None diff --git a/pyiron_atomistics/lammps/potential.py b/pyiron_atomistics/lammps/potential.py index 680d54a23..fbe6d4030 100644 --- a/pyiron_atomistics/lammps/potential.py +++ b/pyiron_atomistics/lammps/potential.py @@ -8,12 +8,10 @@ import pandas as pd from pyiron_base import GenericParameters, state +from pyiron_snippets.resources import ResourceResolver -from pyiron_atomistics.atomistics.job.potentials import ( - PotentialAbstract -) +from pyiron_atomistics.atomistics.job.potentials import PotentialAbstract from pyiron_atomistics.atomistics.structure.atoms import Atoms -from pyiron_snippets.resources import ResourceResolver __author__ = "Joerg Neugebauer, Sudarsan Surendralal, Jan Janssen" __copyright__ = ( @@ -26,6 +24,7 @@ __status__ = "production" __date__ = "Sep 1, 2017" + class LammpsPotential(GenericParameters): """ This module helps write commands which help in the control of parameters related to the potential used in LAMMPS @@ -78,7 +77,9 @@ def files(self): if not os.path.isabs(files) ] for path in relative_file_paths: - absolute_file_paths.append(LammpsPotentialFile.find_potential_file(path)) + absolute_file_paths.append( + LammpsPotentialFile.find_potential_file(path) + ) return absolute_file_paths def copy_pot_files(self, working_directory): @@ -238,10 +239,15 @@ class LammpsPotentialFile(PotentialAbstract): @classmethod def _get_resolver(cls): env = os.environ - return super()._get_resolver().chain( - ResourceResolver( - [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], - "share", "iprpy", + return ( + super() + ._get_resolver() + .chain( + ResourceResolver( + [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], + "share", + "iprpy", + ) ) ) diff --git a/pyiron_atomistics/sphinx/potential.py b/pyiron_atomistics/sphinx/potential.py index ff7d65419..8688e063f 100644 --- a/pyiron_atomistics/sphinx/potential.py +++ b/pyiron_atomistics/sphinx/potential.py @@ -6,9 +6,10 @@ import pandas from pyiron_base import state -from pyiron_atomistics.vasp.potential import VaspPotentialAbstract from pyiron_snippets.resources import ResourceResolver +from pyiron_atomistics.vasp.potential import VaspPotentialAbstract + __author__ = "Osamu Waseda" __copyright__ = ( "Copyright 2019, Max-Planck-Institut für Eisenforschung GmbH - " @@ -35,10 +36,15 @@ class SphinxJTHPotentialFile(VaspPotentialAbstract): @classmethod def _get_resolver(cls): env = os.environ - return super()._get_resolver().chain( - ResourceResolver( - [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], - "share", "sphinxdft", + return ( + super() + ._get_resolver() + .chain( + ResourceResolver( + [env[var] for var in ("CONDA_PREFIX", "CONDA_DIR") if var in env], + "share", + "sphinxdft", + ) ) ) diff --git a/pyiron_atomistics/vasp/potential.py b/pyiron_atomistics/vasp/potential.py index 79282b1d4..04bdeb1dd 100644 --- a/pyiron_atomistics/vasp/potential.py +++ b/pyiron_atomistics/vasp/potential.py @@ -320,7 +320,9 @@ def _get_potcar_filename(name, exch_corr): enmax_lst = [] for n in names: - with open(self.vasp_potentials.find_potential_file(path=_get_potcar_filename(n, xc))) as pf: + with open( + self.vasp_potentials.find_potential_file(path=_get_potcar_filename(n, xc)) + ) as pf: for i, line in enumerate(pf): if i == 14: encut_str = line.split()[2][:-1] From de0b61b22b4885a1f458a0a684cd878818af3fc5 Mon Sep 17 00:00:00 2001 From: Marvin Poul Date: Fri, 16 Aug 2024 11:26:55 +0200 Subject: [PATCH 11/11] Do not use self --- pyiron_atomistics/vasp/potential.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyiron_atomistics/vasp/potential.py b/pyiron_atomistics/vasp/potential.py index 04bdeb1dd..9281a484e 100644 --- a/pyiron_atomistics/vasp/potential.py +++ b/pyiron_atomistics/vasp/potential.py @@ -321,7 +321,7 @@ def _get_potcar_filename(name, exch_corr): enmax_lst = [] for n in names: with open( - self.vasp_potentials.find_potential_file(path=_get_potcar_filename(n, xc)) + VaspPotentialFile.find_potential_file(path=_get_potcar_filename(n, xc)) ) as pf: for i, line in enumerate(pf): if i == 14: