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.Runner
Set inrun
config:runner: label_of_custom_runner
- RunnerInterface & WorkerInterface
- Base class:
profit.run.RunnerInterface
&profit.run.WorkerInterface
Set inrun
config:interface: label_of_custom_interface
- Worker
- Base class:
profit.run.Worker
Set inrun
config:worker: label_of_custom_worker
- Preprocessor
- Base class:
profit.run.Preprocessor
Set inrun.runner(command)
config:pre: label_of_custom_preprocessor
- Postprocessor
- Base class:
profit.run.Postprocessor
Set inrun.runner(command)
config:post: label_of_custom_postprocessor
- Surrogate model
- Base class:
profit.sur.Surrogate
Set infit
config:surrogate: label_of_custom_surrogate
- Active learning algorithm
- Base class:
profit.al.ActiveLearning
Set inactive_learning
config:algorithm: label_of_custom_al_algorithm
- Acquisition function
- Base class:
profit.al.acquisition_functions.AcquisitionFunction
Set inactive_learning/algorithm
config:acquisition_function: label_of_custom_acquisition_function
- FileHandler in-/output file format
- Base class:
profit.util.file_handler.FileHandler
Set infiles
config: 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))