Adding a Tracking Algorithm to TCTrack

If you want to extend TCTrack to add a new tracking algorithm, the documentation on this page provides guidance about how to do this to fit with the existing software.

Code

Packaging and Location

Each new tracking algorithm should be added as a subpackage to the TCTrack package.

New code should go into a directory src/tctrack/my_tracking_algorithm/. The main code (i.e. the Tracker) should be in a file my_tracking_algorithm.py. Include an __init__.py file defining the user-facing namespace, and add the relevant parts as an import to the main package namespace defined in src/tctrack/__init__.py. Further information about packaging in Python can be found in the Python Packaging User Guide.

Existing base classes

TCTrack comes with a number of base classes from which new trackers should be built. These provides a number of base methods to standardise the use

The first is TCTrackerParameters, a base dataclass for holding algorithm parameters. This should be subclassed with the @dataclass(repr=False) decorator and have the parameters you require added (alongside a docstring for each).

The second is TCTracker which provides a base class for a Tracking algorithm including common methods used by all implementations and placeholders for required methods.

Structure

New algorithms should build off the provided base classes listed above, and follow a similar structure to the existing implementations. This allows TCTrack to provide a familiar and standardised interface to a number of different algorithms/codes.

The code is written in an object-oriented approach with the main item being a class MyNewAlgorithmTracker subclassed from TCTracker.

Initialisation of this class will take as input(s) the various specific parameters required by the algorithm, setting them as instance attributes. Parameter lists are subclassed from TCTrackerParameters and a Tracker may take multiple of these parameter lists as inputs where appropriate.

Examples of things to be included in MyNewAlgorithmParameters include input data, output locations, algorithm-specific parameters, and any information controlling outputs. Default values for parameters (instance attributes) should be set where possible such that they can be used to generate sensible results without modification.

When writing a new instance of TCTracker, MyNewTracker, any functionalities from the algorithm/code should be wrapped as class methods callable from an instance of the class.

The class must contain a number of methods prescribed by the base Tracker class:

  • an __init__ method to take parameter classes as inputs and assign to internal attributes. This should perform any compatibility checking of inputs and raise warnings as required.

  • set_metadata() to set global, variable, and time metadata. It should start with a call to super().set_metadata(). Parameters should be added to global metadata in json format and the time and variable metadata should be set appropriately based on the input data and using the TCTrackerTimeMetadata and TCTrackerMetadata classes.

  • read_trajectories() to read any outputs generated by the tracking algorithm and parse them into a list of Trajectory. This will be called by TCTracker.to_netcdf() when converting the trajectories into CF-compliant NetCDF output.

  • run_tracker() that will perform end-to-end tracking, reading inputs and generating tracks as cf-compliant NetCDF output. This is intended to provide easy top-level usage and match the interface of other algorithms in the TCTrack package. It should be assembled from smaller, more specific methods that allow experienced users increased control over the functionality before finally calling the existing TCTracker.to_netcdf() that will write output data read in by read_trajectories() to a CF-conventions compliant NetCDF file.

The detailed method signatures for these can be seen in the TCTracker abstract class.

The coding style described in the developer guidelines should be followed for all new code.

Data

Outputs from TCTrack algorithms are expected to be in a format that is compliant with the cf-conventions, specifically in the Trajectory format. This is handled by the TCTracker.to_netcdf() method provided the read_trajectories() method has been provided.

For a full description of the output format see Output File Format.

Testing

New algorithms should come with a corresponding pytest unit test suite added at tests/unit/test_my_tracking_algorithm.py. See the testing section of the developer guidelines for more information.

Integration tests for small dummy datasets can be added to tests/integration/test_my_tracking_algorithm.py

Documentation

There are two pieces of documentation required for new algorithms. Developers should follow the general documentation guidelines for TCTrack, with further guidance below.

The first documentation is of the code itself. All Python code should be annotated using docstrings following the numpy style. These should then be used to auto-generate API documentation by adding a file at docs/api/my_tracking_algorithm_api.rst and including it in the index.

The second documentation is user information about your tracking algorithm. This should be added as a page at docs/tracking-algorithms/my_tracking_algorithm.rst, again adding to the main index. This should include a brief description of the algorithm, comprehensive instructions for how to obtain and install any external dependencies to TCTrack, examples for usage and getting started, and any key references or other information as required.