Custom extensions
Experienced users have the possibility to add custom components which are used
throughout the proFit workflow. The code should be placed in a Python file which
is referenced inside the include section of the profit.yaml configuration file.
Following components are customizable:
- Runner
- Base class:
profit.run.RunnerSet inrunconfig:runner: label_of_custom_runner
- RunnerInterface & WorkerInterface
- Base class:
profit.run.RunnerInterface&profit.run.WorkerInterfaceSet inrunconfig:interface: label_of_custom_interface
- Worker
- Base class:
profit.run.WorkerSet inrunconfig:worker: label_of_custom_worker
- Preprocessor
- Base class:
profit.run.PreprocessorSet inrun.runner(command)config:pre: label_of_custom_preprocessor
- Postprocessor
- Base class:
profit.run.PostprocessorSet inrun.runner(command)config:post: label_of_custom_postprocessor
- Surrogate model
- Base class:
profit.sur.SurrogateSet infitconfig:surrogate: label_of_custom_surrogate
- Active learning algorithm
- Base class:
profit.al.ActiveLearningSet inactive_learningconfig:algorithm: label_of_custom_al_algorithm
- Acquisition function
- Base class:
profit.al.acquisition_functions.AcquisitionFunctionSet inactive_learning/algorithmconfig:acquisition_function: label_of_custom_acquisition_function
- FileHandler in-/output file format
- Base class:
profit.util.file_handler.FileHandlerSet infilesconfig: File ending of customFileHandler
To create custom classes, the method register of the corresponding base class is used.
All run components support registering using subclass arguments.
For the Worker, Preprocessor and Postprocessor classes there exists a wrap method which simplifies the registering process.
Examples
Here, examples of registering a custom worker, custom postprocessor and a custom file format are shown.
# Worker
from profit.run import Worker
import numpy as np
class CustomWorker(Worker, label="custom_worker"):
"""Directly calling the wanted python function."""
def work(self):
self.interface.retrieve()
u = self.interface.input["u"]
v = self.interface.input["v"]
self.interface.output["f"] = np.cos(10 * u) + v
self.interface.transmit()
@Worker.wrap("custom_worker2")
def f(u, v) -> "f":
"""Shorthand for custom_worker."""
return np.cos(10 * u) + v
# Postprocessor
from profit.run import Postprocessor
import numpy as np
class CustomPost(Postprocessor, label="custom_post"):
"""Almost identical copy of NumpytxtPostprocessor."""
def post(self, data):
raw = np.loadtxt('mockup.out')
data['f'] = raw
@Postprocessor.wrap('custom_post2')
def custom_post(data):
"""Shorthand for custom_post."""
raw = np.loadtxt('mockup.out')
data['f'] = raw
# FileHandler in-/output file format
from profit.util.file_handler import FileHandler
@FileHandler.register("pkl")
class PickleHandler(FileHandler):
@classmethod
def save(cls, filename, data, **kwargs):
from pickle import dump
write_method = 'wb' if not 'method' in kwargs else kwargs['method']
dump(data, open(filename, write_method))
@classmethod
def load(cls, filename, as_type='raw', read_method='rb'):
from pickle import load
if as_type != 'raw':
return NotImplemented
return load(open(filename, read_method))