Distribution Statement
# # # This source code is subject to the license referenced at

Extend GeoIPS with a new Algorithm#

To extend GeoIPS with a new algorithm plugin, first follow the instructions for setting up a plugin package.

In GeoIPS 2.0, algorithms are class-based plugins: a Python class that subclasses the algorithm base class and sets three class attributes:

  • interface

  • family

  • name

See Writing a class-based plugin for the full class-based plugin contract, and the algorithm interface for the argument model. If you are migrating a 1.x module-based algorithm, see Converting module-based plugins to class-based.

Creating an Algorithm#

The following steps teach you how to create a custom algorithm plugin. Change directories to your package’s classes algorithm directory:

cd $MY_PKG_DIR/$MY_PKG_NAME/plugins/classes/algorithms

Create a file called my_cloud_depth.py. A class-based algorithm subclasses BaseAlgorithmPlugin, sets interface/family/name, and implements a call method. The call method is where the data manipulation happens; GeoIPS invokes it for you (directly, or as a step in an OBP workflow).

The complete plugin looks like this:

"""Cloud depth product.

Difference of cloud top height and cloud base height.

This is the doc-owned example used by the :ref:`algorithm tutorial <add-an-algorithm>`.
It is imported and executed by ``tests/unit_tests/docs/test_tutorial_examples.py``
so the code shown in the tutorial is exercised in CI.
"""

import logging

from xarray import DataArray

from geoips.interfaces.class_based.algorithms import BaseAlgorithmPlugin

LOG = logging.getLogger(__name__)


class MyCloudDepthAlgorithmPlugin(BaseAlgorithmPlugin):
    """My cloud depth algorithm plugin.

    Difference of cloud top height and cloud base height, scaled to kilometers.
    """

    interface = "algorithms"
    family = "xarray_to_xarray"
    name = "my_cloud_depth"

    def call(
        self,
        xobj,  # xarray Dataset holding the input variables
        variables,  # ordered list of required input variables (see product plugin)
        product_name,
        output_data_range,  # range of values the algorithm will output
        scale_factor,  # converts input meters to output kilometers
        min_outbounds="crop",
        max_outbounds="mask",
        norm=False,
        inverse=False,
    ):
        """Apply the cloud-depth manipulation steps to the input data."""
        from geoips.data_manipulations.corrections import apply_data_range

        cth = xobj[variables[0]]
        cbh = xobj[variables[1]]

        out = (cth - cbh) * scale_factor

        data = apply_data_range(
            out,
            min_val=output_data_range[0],
            max_val=output_data_range[1],
            min_outbounds=min_outbounds,
            max_outbounds=max_outbounds,
            norm=norm,
            inverse=inverse,
        )
        xobj[product_name] = DataArray(data)

        return xobj


# Tells pluginify (the plugin registry) which object in this module is the plugin.
PLUGIN_CLASS = MyCloudDepthAlgorithmPlugin

A few things to note:

  • The class name follows the <Name><Interface>Plugin convention (MyCloudDepthAlgorithmPlugin).

  • family (here xarray_to_xarray) determines the call signature and how GeoIPS converts data into and out of your plugin. To see the arguments each family expects, see the algorithm base class.

  • variables is ordered — it matches the order you define variables in your product plugin, so variables[0] and variables[1] are cloud top height and cloud base height respectively.

  • You can add as many keyword arguments as you need, provided your product supplies them.

  • The module ends with PLUGIN_CLASS = MyCloudDepthAlgorithmPlugin. This tells the plugin registry (pluginify) which class in the file is the plugin to register.

After adding the plugin, rebuild the plugin registries so GeoIPS can find it:

geoips config create-registries
geoips list algorithms          # confirm my_cloud_depth appears
geoips describe alg my_cloud_depth

Note

The plugin above is a real, tested example. It lives at docs/source/tutorials/extending-with-plugins/examples/my_cloud_depth.py and is imported and executed by tests/unit_tests/docs/test_tutorial_examples.py, so this tutorial’s code stays runnable.

Using your algorithm#

Algorithms are not used on their own — they are one step of a larger product. If you have already created a Product in the Products section, revisit your My-Cloud-Depth product definition to reference the algorithm you just created. The product (or the workflow that includes it) supplies the variables, output_data_range, and scale_factor arguments your call method expects.

Your algorithm then runs as part of an Order-Based Processing workflow, either directly (geoips run order_based <workflow> <files>) or via a product step. The same class can also be called from a Python script — see Scripting with GeoIPS plugins.