Source code for ddd_pylib.tracking._points_tracking_operator

from ddd_pylib._base import PointsOperator
import numpy as np
import pandas as pd
from._tracking_base import TrackingBase

# The mainDataFrame will likely come from Napari. In this case, coordinates of points are
# expressed in pixels and the scale of the layer makes them show in the correct location.
# However, we still want the user to express the searching range or the memory in physical units
# for them to be consistent with the rest of the analysis.
# However, most tracking libraries expect:
#   - the T axis to be in frames (integers) which corresponds to an uncalibrated value.
#   - the spatial coordinates to be expressed in the same units as the searching range (e.g. microns)
# When comes tracking, we need to:
#   - create a temporary dataframe that keeps the T column as integers AND convert the memory to frames (integers) using the calibration.
#   - convert the spatial coordinates to the same units as the searching range (e.g. microns) using the calibration.

[docs] class PointsTrackingOperator(TrackingBase, PointsOperator): def __init__(self): super().__init__() def _applyToFrame(self, frameData, t, nT): raise RuntimeError("This operator does not support frame-wise processing. Use the 'linkTracks' method instead.")
[docs] def getPrefix(self) -> str: return "Tracked-"
[docs] def checkAxes(self): if self._strategy is None: raise ValueError("Tracking strategy has not been set.") in_axes = set(self.getMainDataFrame().columns) if 'T' not in in_axes: raise ValueError("The 'T' axis is required for tracking.") if len(in_axes.intersection({'X', 'Y'})) != 2: raise ValueError("The minimal setup is 2D tracking and requireds both 'X' and 'Y' axes.")
[docs] def getCalibratedDataFrame(self) -> pd.DataFrame: df = self.getMainDataFrame().copy() calib = self.getCalibration() # Convert spatial coordinates to physical units for ax in ['X', 'Y', 'Z']: if ax in df.columns: df[ax] = df[ax] * calib['scale'][ax] return df
def _setResultFromCalibratedDataFrame(self, df: pd.DataFrame): calib = self.getCalibration() # Convert spatial coordinates back to pixel units for ax in ['X', 'Y', 'Z']: if ax in df.columns: df[ax] = df[ax] / calib['scale'][ax] self._result = df def _run(self): self.checkAxes() s = self.getStrategy() s._updateOperator(self) s.run() linked_df = s.getResult() self._setResultFromCalibratedDataFrame(linked_df) yield 0