Implement a new Function

Purpose of this Chapter

The aim of this chapter to explain how to implement a new function. This will be presented by implementing a simple example. Let’s assume that the data of our series has to be resampled before the execution of a test. To handle it, we implement a function that resamples the data to a 1-second resolution and interpolates the NaN-values and the gaps. For simplicity’s sake, we assume that we always need a 1-second resolution. Moreover, the user should have the opportunity to define the interpolation method (e.g., linear).

Define the Metadata of the Function

Note

Each function has to inherit from the abstract class BaseFunction and has to implement the abstract method apply. Moreover, each function has to provide its metadata. The following metadata has to be provided by each function: NAME and DESCRIPTION. See also: autom8qc.functions.base.BaseFunction

Warning

Make sure that the class name ends with the suffix Function. Other modules will check for the suffix to identify that the class is a function.

import numpy as np
import pandas as pd

from autom8qc.core import exceptions
from autom8qc.core.parameters import Parameter
from autom8qc.core.parameters import ParameterList
from autom8qc.functions.base import BaseFunction

class InterpolationFunction(BaseFunction):

    NAME = "Simple interpolation"
    DESCRIPTION = "Resamples the data to a 1-second resolution and fill the gaps with a interpolation"

Define the Supported Parameters

Each function has to provide the supported parameters. Therefore, you have to implement the static method supported_parameters. The method allows you to access them without creating an instance of the class. If your function doesn’t need additional parameters, you don’t have to implement it. For our example, we have the interpolation method as a parameter.

@staticmethod
def supported_parameters():
    return ParameterList(
        Parameter(
            name="method",
            description="Interpolation technique to use (e.g., linear)",
            dtype=str,
            optional=False,
            default="linear"
        )
    )

Implement the Constructor

The constructor is a method that is called when an object is created. In our case, we have to pass the parameter method to the constructor and store the value in the related Parameter which we defined in the method supported_parameters. Note that you don’t have to check the type of the parameters since a Parameter checks the type when you set the value. If you want to implement additional checks, you have to implement them in the constructor and raise an exception if a constraint is not satisfied. Finally, you have to call the super method check_metadata that checks if the instance is valid. In our example, our constructor needs the parameter method (default: linear) that defines the interpolation technique.

Note

We use the interpolation techniques that pandas provide. See also: pd.DataFrame.interpolate

Warning

Make sure that you call the super constructor before assigning the parameters.

def __init__(self, method="linear"):
    super().__init__()
    self.parameters["method"] = method
    self.check_metadata()

Implement the Abstract Method

Finally, we have to implement the abstract method apply. Our method takes a pd.Series as a parameter and returns the resampled data. For our example, we assume that we only support series. If a non-series will pass to the method, we will raise an error.

def apply(self, data):
    if not isinstance(series, pd.Series):
        raise exceptions.InvalidType("Data must be an instance of pd.Series!")
    method = self.parameters["method"].value
    data = data.resample("1s")
    return data.interpolate(method)