Writing an ancillary application with UG-ANTS#

The ugants.abc.Application abstract base class provides provides a common interface for writing applications for generating unstructured grid ancillaries, providing functionality common to most applications:

  • A standardised command line interface is automatically generated from the application signature.

  • Load and save methods are provided by the base class. These are intended to provide a sensible default, but can be overridden in specific applications if necessary.

The __init__() and run() methods must be provided when subclassing Application. See the documentation for these methods for more detail.

Example user-defined application#

A user defined application is created by subclassing the Application base class, and providing the required __init__() and run() methods:

# example_application.py
from iris.cube import CubeList
from iris.experimental.ugrid import Mesh
from typing import Literal

class UserDefinedApplication(Application):
    '''An example user-defined application inheriting from the Application ABC.

    Parameters
    ----------
    source
        UGrid source data.
    target_mesh
        The target mesh to regrid to.
    number
        A number.
    scheme
        The regrid scheme to be used.
    option
        An arbitrary option.
    '''
    def __init__(
        self,
        source: CubeList,
        target_mesh: Mesh,
        number: int,
        scheme: Literal["conservative", "bilinear"] = "conservative",
        option: str = None
    ):
        self.source = source
        self.target_mesh = target_mesh
        self.number = number
        self.scheme = scheme
        self.option = option

    def run(self):
        '''Run the UserDefinedApplication.

        In this case, just print some of the application attributes,
        then set self.result.
        '''
        print(f"Running application")
        print(f"Using scheme '{self.scheme}' and number {self.number}")
        print(f"Option is: {self.option}")
        self.results = self.source

if __name__ == "__main__":
    app_instance = UserDefinedApplication.from_command_line()
    app_instance.run()
    app_instance.save()

The most common way of instantiating and running an application is via the command line interface. This is achieved by calling the from_command_line() method, which will parse arguments from the command line. In the case of the UserDefinedApplication example above, the following command line interface will be generated:

usage: example_application.py [-h] --target-mesh-name TARGET_MESH_NAME
                                --target-mesh TARGET_MESH --number NUMBER
                                [--scheme {conservative,bilinear}]
                                [--option OPTION]
                                source output

An example user-defined application inheriting from the Application ABC.

Parameters
----------
source
    UGrid source data.
target_mesh
    The target mesh to regrid to.
number
    A number.
scheme
    The regrid scheme to be used.
option
    An arbitrary option.

positional arguments:
source                Path to source.
output                Path to output the results from
                        UserDefinedApplication.

options:
-h, --help            show this help message and exit
--target-mesh-name TARGET_MESH_NAME
                        The name of the mesh contained in the file provided to
                        '--target-mesh'.
--target-mesh TARGET_MESH
                        Path to target_mesh.
--number NUMBER
--scheme {conservative,bilinear}
                        Default is conservative.
--option OPTION       Default is None.

The application is then run and the results saved by calling the run() and save() methods. The results will be saved to the file specified by the output attribute on the class instance, which is automatically set by the output command line argument.

The above python script is then run as follows:

$ python example_application.py --target-mesh-name dynamics --target-mesh path/to/target/mesh.nc --number 1 --scheme conservative --option foo path/to/source.nc path/to/output.nc
Running application
Using scheme 'conservative' and number 1
Option is: foo

An application can be also instantiated and run using the API. Using the above application class, and assuming a CubeList source and a Mesh mesh have already been loaded, the application is instantiated and run as follows:

>>> app_instance = UserDefinedApplication(source=source, target_mesh=mesh, number=3, scheme="bilinear")
>>> app_instance.run()
Running application
Using scheme 'bilinear' and number 3
Option is: None

The results are stored in the results attribute. To save the results, set the output attribute, then call save().

>>> app_instance.output = "path/to/output/result.nc"
>>> app_instance.save()