Tracker

giant.ufo.ekf_tracker:

class giant.ufo.ekf_tracker.Tracker(camera, scene, dynamics, state_initializer, search_distance_function, observation_trees=None, observation_ids=None, initial_euclidean_threshold=300, measurement_covariance=None, maximum_image_timedelta=datetime.timedelta(seconds=3600), maximum_paths_per_image=10, maximum_paths_total=15, maximum_forward_images=2, maximum_track_length=15, maximum_mahalanobis_distance_squared=25, expected_convergence_number=4, reduced_paths_forward_per_image=3, minimum_number_of_measurements=4, maximum_residual_standard_deviation=20, maximum_time_outs=50, maximum_tracking_time_per_image=3600, kernels_to_load=None)[source]

This class provides an interface for autonomously tracking UFOs through subsequent images in time.

There are 2 main components to this tracker. The first is the use of EKFs to follow most of the possible paths forward from a single starting particle in an image. This can result in hundreds of thousands (if not millions) of possible tracks for a set of images with fairly dense UFO detections. The second component is then the filtering of these EKFs, which is done based on length (the number of measurements included in the EKF), post-fit residual statistics, and uniqueness (each starting particle only gets the best track assigned to it, and once a particle has been assigned to a track it can’t be assigned to others). This filtering process normally brings the number of tracks down to a much more manageable 10s to 100s.

Explicit details on how this tracker works are provided in the paper at https://agupubs.onlinelibrary.wiley.com/doi/pdf/10.1029/2019EA000843 and are not repeated here.

To use this class, provide the (numerous) initialization values (the defaults will be fine for many cases) and then call method track(). The results will then be stored in the confirmed_filters, confirmed_particles, and confirmed_standard_deviations attributes. In general, you may not directly interact with this class however, and instead will use the UFO interface class to both detect and track particles.

Parameters:
  • camera (Camera) – The Camera containing the images to process and the camera model

  • scene (Scene) – The Scene describing the location of the central body with respect to the camera.

  • dynamics (Dynamics) – The dynamics model to use in the EKF for propagating the state from one time to another

  • state_initializer (Callable[[Measurement, Type[State]], State]) – A callable which takes in a Measurement instance and Dynamics.State class object and returns an initialized state.

  • search_distance_function (Callable[[ExtendedKalmanFilter], Real]) – A callable which takes in an ExtendedKalmanFilter and returns what the Euclidean search distance should be for that EKF in pixels. This is only applied after the first pair has been made

  • observation_trees (List[KDTree | None] | None) – A list of scipy.spatial KDTree objects that are built on the pixel locations of the detections for each image

  • observation_ids (List[List[int] | None] | None) – A list of the ids for each observation contained in the trees in order.

  • initial_euclidean_threshold (Real) – The threshold in pixels for points to be paired form the first image to a subsequent image. This is not applied after the first pair has been made.

  • measurement_covariance (ndarray | None) – The covariance matrix of the measurements as a 2x2 array. This should have units of pixels squared.

  • maximum_image_timedelta (timedelta) – The maximum time separation between images to attempt either initial or subsequent pairings as a timedelta object

  • maximum_paths_per_image (int) – The maximum number of forward paths for a single particle to the next image to consider

  • maximum_paths_total (int) – The total maximum number of forward paths for a single image across all images to consider

  • maximum_forward_images (int) – The maximum number of images to retrieve potential pairs from (images will be processed in time order)

  • maximum_track_length (int) – The maximum length of a track before it is artificially terminated. The length of a track is defined as the number of measurements that it has ingested

  • maximum_mahalanobis_distance_squared (float) – The maximum squared Mahalanobis distance for subsequent (not initial) observations to be paired to a track.

  • expected_convergence_number (int) – The number of ingested measurements at which point tracks are expected to be fairly converged. At this point, more stringent filtering is used in determining forward paths.

  • reduced_paths_forward_per_image (int) – The number of paths forward per image that are considered once a track is considered converged.

  • minimum_number_of_measurements (int) – The minimum number of measurements in a track for it to be considered a potential good track. Typically 4 should be the absolute minimum, but in some cases it may need to be even higher than that.

  • maximum_residual_standard_deviation (Real) – The maximum standard deviation of the post-fit residuals in an EKF for it to be considered a potentially good track.

  • maximum_time_outs (int) – The maximum number of time outs that can occur when attempting to retrieve tracking results from the children processes before we assume something has gone wrong and terminate all of the processes.

  • maximum_tracking_time_per_image (Real) – The maximum amount of time to attempt tracking in the image before we assume something has gone wrong and terminate all of the processes.

  • kernels_to_load (List[str] | None) – The spice kernels to load in each subprocess. This is required if you are using spice because the kernel pool does not subsist across processes. It should either be None if you’re not using spice or a list of strings if you are.

camera: Camera

The Camera containing the images to process and the camera model

scene: Scene

The Scene describing the location of the central body with respect to the camera.

The central body should be the first “target” in the scene. It doesn’t need to have a shape associated with it (it can be a Point object) and in fact is encouraged not to (to avoid large memory overhead)

observation_trees: List[KDTree | None]

A list of KDTrees built on the observed UFO locations.

If any elements are None then it is assumed that no detections exist for that image.

observation_ids: List[List[Hashable] | None]

A list of the ids for each observation contained in the trees.

These should be unique Hashable objects like ints or strings, not mutable like lists/arrays/dictionaries. They should uniquely identify an observation.

processes: List[Process]

A List of Processes that are working

confirmed_particles

A set of particles that have been assigned to a track already

dynamics: Dynamics

The dynamics model to use to propagate the states from one time to another.

measurement_covariance: ndarray | None

The 2x2 measurement covariance matrix (or None to use the identify matrix) with units of pixels squared.

state_initializer: Callable[[Measurement, Type[State]], State]

The state initializer callable to use to initialize the state vector given the initial measurement and the type of the state vector to be initialized

maximum_image_timedelta: timedelta

The maximum separation in time between images for them to be paired subsequently

initial_euclidean_threshold: float

The threshold in pixels for points to be paired from the first image to a subsequent image

maximum_paths_per_image: int

The maximum number of pairs from one image to the next for a single possible particle

maximum_paths_total: int

The maximum number of pairs from one image to all images for a single particle

maximum_forward_images: int

The maximum number of images to pair with

maximum_track_length: int

The maximum length of a track to consider before terminating.

the length of a track is defined as the number of measurements that it has ingested.

This is necessary for memory management purposes as long tracks frequently have many variants that are being tracked and can take up a lot of memory.

search_distance_function: Callable[[ExtendedKalmanFilter], Real]

A function which returns what the search distance should be in pixels when trying to match the current EKF to new images.

maximum_mahalanobis_distance_squared: float

This specifies the maximum Mahalanobis distance squared for a potential detection to be paired to a track

The Mahalanobis distance is roughly equivalent to the sigma normalized error between the predicted and observed location. Therefore a Mahalanobis distance squares of 25 roughly corresponds to only accepting pairings that are within 5 sigma of the predicted location.

expected_convergence_number: int

This specifies the number of measurements at which it is expected the filter will have mostly converged and we should become more selective with which paths forward we follow.

reduced_paths_forward_per_image: int

This specifies the reduced number of paths forward we should follow once the filter should be converged.

minimum_number_of_measurements: int

The minimum number of measurements for an EKF to be considered a track.

maximum_residual_standard_deviation: float

The maximum post-fit standard deviation of the residuals in an EKF for it to be considered a valid fit

maximum_time_outs: int

The maximum number of time outs in a row before we stop trying to process an image

maximum_tracking_time_per_image: float

The maximum amount of time to attempt tracking in an image in seconds.

confirmed_filters: List[ExtendedKalmanFilter]

This list stores the confirmed EKFs

confirmed_standard_deviations: List[float]

This list stores the standard deviation of the post-fit residuals of the confirmed EKFs

kernels_to_load: List[str] | None

The spice kernels to load in each subprocess.

This is required if you are using spice because the kernel pool does not subsist across processes. It should either be None if you’re not using spice or a list of strings if you are.

Summary of Methods

filter_ekfs

This method does backwards smoothing on each EKF and figures out which are actually valid

find_initial_pairs

This method finds the initial pairs for the input image.

save_results

This method saves the final ekfs to a csv file.

track

This method tracks particles from image to image using the EKF.