Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ResourceResolvers in lammps/vasp/sphinx #1527

Merged
merged 11 commits into from
Aug 16, 2024
Prev Previous commit
Next Next commit
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
pmrv committed Aug 16, 2024
commit d7e3f1af56c441a17c02c2114150e889a20e4aaa
51 changes: 21 additions & 30 deletions pyiron_atomistics/atomistics/job/potentials.py
Original file line number Diff line number Diff line change
@@ -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
23 changes: 13 additions & 10 deletions pyiron_atomistics/lammps/potential.py
Original file line number Diff line number Diff line change
@@ -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__(
14 changes: 3 additions & 11 deletions pyiron_atomistics/sphinx/base.py
Original file line number Diff line number Diff line change
@@ -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]
)
)
26 changes: 12 additions & 14 deletions pyiron_atomistics/sphinx/potential.py
Original file line number Diff line number Diff line change
@@ -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)
4 changes: 2 additions & 2 deletions pyiron_atomistics/vasp/potential.py
Original file line number Diff line number Diff line change
@@ -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":