Source code for pyiron_base.project.jobloader
# coding: utf-8
# Copyright (c) Max-Planck-Institut für Eisenforschung GmbH - Computational Materials Design (CM) Department
# Distributed under the terms of "New BSD License", see the LICENSE file.
"""
A helper class to be assigned to the project, which facilitates tab-completion when
loading jobs.
"""
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING
import numpy as np
from pyiron_base.database.jobtable import get_job_id
from pyiron_base.jobs.job.util import _get_safe_job_name
from pyiron_base.state import state
if TYPE_CHECKING:
from pyiron_base.jobs.job.generic import GenericJob
from pyiron_base.jobs.job.path import JobPath
from pyiron_base.project.generic import Project
class _JobByAttribute(ABC):
"""
A parent class for accessing project jobs by a call and a job specifier, or by tab
completion.
"""
def __init__(self, project: Project):
self._project = project
@property
def _job_table(self):
return self._project.job_table(columns=["job"])
@property
def _job_names(self):
return self._job_table["job"].values
def __dir__(self):
return self._job_names
def _id_from_name(self, name):
return self._job_table.loc[self._job_names == name, "id"].values[0]
def __getattr__(self, item):
return self._project.load_from_jobpath(
job_id=self._id_from_name(item), convert_to_object=self.convert_to_object
)
def __getitem__(self, item):
return self.__getattr__(item)
def __call__(self, job_specifier, convert_to_object=None):
if self._project.sql_query is not None:
state.logger.warning(
f"SQL filter '{self._project.sql_query}' is active (may exclude job)"
)
if not isinstance(job_specifier, (int, np.integer)):
job_specifier = _get_safe_job_name(name=job_specifier)
job_id = get_job_id(
database=self._project.db,
sql_query=self._project.sql_query,
user=self._project.user,
project_path=self._project.project_path,
job_specifier=job_specifier,
)
if job_id is None:
state.logger.warning(
f"Job '{job_specifier}' does not exist and cannot be loaded"
)
return None
return self._project.load_from_jobpath(
job_id=job_id,
convert_to_object=(
convert_to_object
if convert_to_object is not None
else self.convert_to_object
),
)
@property
@abstractmethod
def convert_to_object(self):
pass
[docs]
class JobLoader(_JobByAttribute):
"""
Load an existing pyiron object - most commonly a job - from the database
Args:
job_specifier (str, int): name of the job or job ID
Returns:
GenericJob, JobCore: Either the full GenericJob object or just a reduced JobCore object
"""
convert_to_object = True
def __call__(self, job_specifier, convert_to_object=None) -> GenericJob:
return super().__call__(job_specifier, convert_to_object=convert_to_object)
[docs]
class JobInspector(_JobByAttribute):
"""
Inspect an existing pyiron object - most commonly a job - from the database
Args:
job_specifier (str, int): name of the job or job ID
Returns:
JobCore: Access to the HDF5 object - not a GenericJob object - use :meth:`~.Project.load()`
instead.
"""
convert_to_object = False
def __call__(self, job_specifier) -> JobPath:
return super().__call__(job_specifier)