Writing plugins#

By writing a plugin, you can define your own analysis routines and specify them in your configuration file.

Note

If you are not familiar with plugins and entrypoints, you may want to read Python packaging guide and Setuptools documentation first.

Analyzer#

Let us suppose that we want to implement an analysis type Foo for the following configuration file entry:

foo:
    type: Foo
    ...

For this, we can write a simple plugin named wettingfront-foo. The package structure will be:

wettingfront-foo
├── pyproject.toml
└── foo.py

In foo.py we define:

def foo_analyzer(k: str, v: dict):
    ... # do whatever you want

The signature of analyzer is specified in analyze_files(). Then, in pyproject.toml we define a table to register foo_analyzer() to Foo:

[project.entry-points."wettingfront.analyzers"]
Foo = "foo:foo_analyzer"

Now, by installing the wettingfront-foo package, the analysis type Foo will be recognized.

Models#

During the analysis, you are likely to interpret the data using models describing rate of penetration, such as fit_washburn(). Instead of using default models, you can define your own by writing plugin.

With the package structure described above, in foo.py we define:

def my_model(t, x):
    ... # define your model

and register an entry point in pyproject.toml:

[project.entry-points."wettingfront.models"]
MyModel = "foo:my_model"

Note that the model must strictly adhere to the prescribed function signature.

Arguments#

  1. Timestamp

    1-D array with shape (M,).

  2. Penetration length

    1-D array with shape (M,).

Returns#

  1. Predictor function

    Unary callable which takes 1-D array of timestamp and returns 1-D array of predicted penetration length.

  2. Fitted parameters (tuple)

    Analyzer can refer to this value for further use.

Samples#

As shown in Tutorial, WettingFront supports ‘wettingfront samples’ command to print the path to the directory where sample files are stored. If your plugin has its own sample directory, you can register it to the same API.

To distribute the sample files as package data, the wettingfront-foo needs to be a little more complicated:

wettingfront-foo
├── pyproject.toml
├── MANIFEST.in
└── src
    └── foo
        ├── samples
        └── __init__.py

Make sure that the sample directory is included in MANIFEST.in. Then, in __init__.py we define:

from importlib.resources import files

def sample_path():
    return str(files("wettingfront-foo").joinpath("samples"))

And in pyproject.toml we define a table:

[project.entry-points."wettingfront.samples"]
foo = "foo:sample_path"

Then, invoking wettingfront samples foo will print the path to the samples directory. Note that sample_path() can have different signature as long as it returns the correct path when called with empty argument.