Source code for pyiron_base.jobs.job.template

# 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.
"""
Template class to define jobs
"""

from typing import Optional

from pyiron_base.interfaces.object import HasStorage
from pyiron_base.jobs.job.generic import GenericJob
from pyiron_base.storage.datacontainer import DataContainer

__author__ = "Jan Janssen"
__copyright__ = (
    "Copyright 2020, Max-Planck-Institut für Eisenforschung GmbH - "
    "Computational Materials Design (CM) Department"
)
__version__ = "1.0"
__maintainer__ = "Jan Janssen"
__email__ = "janssen@mpie.de"
__status__ = "development"
__date__ = "May 15, 2020"


[docs] class TemplateJob(GenericJob, HasStorage): """ pyiron template job class for codes with an external executable. Example: >>> from pyiron_base import TemplateJob, Project >>> class MyJob(TemplateJob): >>> def __init__(self, project, job_name): >>> super().__init__(project, job_name) >>> job.input.message = "hello!" >>> self.executable = "cat input.dat > output.dat" >>> def write_input(self): >>> with open(self.working_directory + "/input.dat", "w") as f: >>> f.write(job.input.message) >>> def collect_output(self): >>> with open(self.working_directory + "/output.dat", "w") as f: >>> job.output.message = f.read() >>> job.to_hdf() >>> pr = Project("my_project") >>> job = pr.create_job(MyJob, "my_job") >>> job.run() You can store information you need in `job.input` (or `self.input`) and `job.output` (or `self.output`). The information assigned there will be automatically stored in the database after a successful run. You can write everything inside `run_static`, but optionally you can use the functions `def write_input(self)` and `def collect_output(self)`, which are called before and after `run_static`, respectively. Important: The job runs in the working directory of the pyiron job. In the example above, it is placed under `my_project/my_job_hdf5/my_job/`. It is therefore important to use the absolute path, or `self.working_directory` to make sure that the files are found correctly If you have a code which requires an executable, take a look at :class:`~.TemplateJob` instead. """
[docs] def __init__( self, project: "pyiron_base.storage.hdfio.ProjectHDFio", job_name: str ): GenericJob.__init__(self, project, job_name) HasStorage.__init__(self, group_name="") self.storage.create_group("input") self.storage.create_group("output")
@property def input(self) -> DataContainer: return self.storage.input @property def output(self) -> DataContainer: return self.storage.output def _to_dict(self) -> dict: """ Convert the job object to a dictionary. Returns: dict: A dictionary representation of the job object. """ job_dict = super()._to_dict() job_dict["input/data"] = self.storage.input.to_dict() return job_dict def _from_dict(self, obj_dict: dict, version: str = None): """ Update the object attributes from a dictionary representation. Args: obj_dict (dict): The dictionary containing the object attributes. version (str, optional): The version of the dictionary format. Defaults to None. """ super()._from_dict(obj_dict=obj_dict, version=version) input_dict = obj_dict["input"] if "data" in input_dict.keys(): self.storage.input.update(input_dict["data"])
[docs] def to_hdf( self, hdf: Optional["pyiron_base.storage.hdfio.ProjectHDFio"] = None, group_name: Optional[str] = None, ) -> None: GenericJob.to_hdf(self=self, hdf=hdf, group_name=group_name) HasStorage.to_hdf(self=self, hdf=self.project_hdf5)
[docs] def from_hdf( self, hdf: Optional["pyiron_base.storage.hdfio.ProjectHDFio"] = None, group_name: Optional[str] = None, ) -> None: GenericJob.from_hdf(self=self, hdf=hdf, group_name=group_name) HasStorage.from_hdf(self=self, hdf=self.project_hdf5)
[docs] class PythonTemplateJob(TemplateJob): """ pyiron template job class for python codes. Example: >>> from pyiron_base import PythonTemplateJob, Project >>> class ToyJob(PythonTemplateJob): # Create a custom job class >>> def __init__(self, project, job_name): >>> super().__init__(project, job_name) >>> self.input.energy = 100 # Define default input >>> def run_static(self): # Call a python function and store stuff in the output >>> self.output.double = self.input.energy * 2 >>> self.status.finished = True >>> self.to_hdf() >>> job = pr.create_job(job_type=ToyJob, job_name="toy") # Create job instance >>> job.run() # Execute Custom job class You can store information you need in `job.input` (or `self.input`) and `job.output` (or `self.output`). The information assigned there will be automatically stored in the database after a successful run. You can write everything inside `run_static`, but optionally you can use the functions `def write_input(self)` and `def collect_output(self)`, whichare called before and after `run_static`, respectively. If you have a code which requires an executable, take a look at `TemplateJob` instead. """
[docs] def __init__( self, project: "pyiron_base.storeage.hdfio.ProjectHDFio", job_name: str ): super().__init__(project, job_name) self._job_with_calculate_function = True self._write_work_dir_warnings = False