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.
.. contents:: Contents:
:local:
:depth: 2
.. Import the core module to use references throughout this page.
.. py:module:: tctrack.core
:no-index:
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 :class:`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 :class:`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 :class:`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 :class:`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 :class:`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.
* :meth:`~TCTracker.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 :class:`TCTrackerTimeMetadata` and
:class:`TCTrackerMetadata` classes.
* :meth:`~TCTracker.read_trajectories` to read any outputs generated by the tracking
algorithm and parse them into a list of :class:`Trajectory`.
This will be called by :meth:`TCTracker.to_netcdf` when converting the trajectories
into CF-compliant NetCDF output.
* :meth:`~TCTracker.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
:meth:`TCTracker.to_netcdf` that will write output data read in by
:meth:`~TCTracker.read_trajectories` to a :doc:`CF-conventions compliant NetCDF file
<../data/output_file>`.
The detailed method signatures for these can be seen in the :class:`TCTracker` abstract
class.
The coding style described in the :ref:`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 :meth:`TCTracker.to_netcdf` method provided the
:meth:`~TCTracker.read_trajectories` method has been provided.
For a full description of the output format see :doc:`../data/output_file`.
Testing
~~~~~~~
New algorithms should come with a corresponding `pytest `_
unit test suite added at ``tests/unit/test_my_tracking_algorithm.py``.
See the :ref:`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 :ref:`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.