Distribution Statement
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:
interfacefamilyname
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>Pluginconvention (MyCloudDepthAlgorithmPlugin).family(herexarray_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.variablesis ordered — it matches the order you define variables in your product plugin, sovariables[0]andvariables[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.