docstrings
This commit is contained in:
parent
cbd0541a54
commit
94fa5e3d14
@ -4,9 +4,7 @@ import matplotlib.pyplot as plt
|
||||
import matplotlib.patches as patches
|
||||
|
||||
from skimage.draw import disk
|
||||
|
||||
from .util import RegionShape, AnalysisType, Illumination
|
||||
from IPython import embed
|
||||
|
||||
|
||||
class Region(object):
|
||||
@ -119,7 +117,14 @@ class Region(object):
|
||||
|
||||
@property
|
||||
def position(self):
|
||||
"""Returns the position and extent of the region as 4-tuple, (x, y, width, height)"""
|
||||
"""
|
||||
Get the position of the arena.
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple
|
||||
A tuple containing the x-coordinate, y-coordinate, width, and height of the arena.
|
||||
"""
|
||||
x = self._min_extent[0]
|
||||
y = self._min_extent[1]
|
||||
width = self._max_extent[0] - self._min_extent[0]
|
||||
@ -294,39 +299,39 @@ class Region(object):
|
||||
return np.array(entering), np.array(leaving)
|
||||
|
||||
def patch(self, **kwargs):
|
||||
"""
|
||||
Create and return a matplotlib patch object based on the shape type of the arena.
|
||||
|
||||
Parameters:
|
||||
- kwargs: Additional keyword arguments to customize the patch object.
|
||||
|
||||
Returns:
|
||||
- A matplotlib patch object representing the arena shape.
|
||||
|
||||
If the 'fc' (facecolor) keyword argument is not provided, it will default to None.
|
||||
If the 'fill' keyword argument is not provided, it will default to False.
|
||||
|
||||
For rectangular arenas, the patch object will be a Rectangle with width and height
|
||||
based on the arena's position.
|
||||
For circular arenas, the patch object will be a Circle with radius based on the
|
||||
arena's extent.
|
||||
|
||||
Example usage:
|
||||
```
|
||||
arena = Arena()
|
||||
patch = arena.patch(fc='blue', fill=True)
|
||||
ax.add_patch(patch)
|
||||
```
|
||||
"""
|
||||
if "fc" not in kwargs:
|
||||
kwargs["fc"] = None
|
||||
kwargs["fill"] = False
|
||||
if self._shape_type == RegionShape.Rectangular:
|
||||
w = self.position[2]
|
||||
h = self.position[3]
|
||||
return patches.Rectangle(self._origin, w, h, **kwargs)
|
||||
else:
|
||||
return patches.Circle(self._origin, self._extent, **kwargs)
|
||||
"""
|
||||
Create and return a matplotlib patch object based on the shape type of the arena.
|
||||
|
||||
Parameters:
|
||||
- kwargs: Additional keyword arguments to customize the patch object.
|
||||
|
||||
Returns:
|
||||
- A matplotlib patch object representing the arena shape.
|
||||
|
||||
If the 'fc' (facecolor) keyword argument is not provided, it will default to None.
|
||||
If the 'fill' keyword argument is not provided, it will default to False.
|
||||
|
||||
For rectangular arenas, the patch object will be a Rectangle with width and height
|
||||
based on the arena's position.
|
||||
For circular arenas, the patch object will be a Circle with radius based on the
|
||||
arena's extent.
|
||||
|
||||
Example usage:
|
||||
```
|
||||
arena = Arena()
|
||||
patch = arena.patch(fc='blue', fill=True)
|
||||
ax.add_patch(patch)
|
||||
```
|
||||
"""
|
||||
if "fc" not in kwargs:
|
||||
kwargs["fc"] = None
|
||||
kwargs["fill"] = False
|
||||
if self._shape_type == RegionShape.Rectangular:
|
||||
w = self.position[2]
|
||||
h = self.position[3]
|
||||
return patches.Rectangle(self._origin, w, h, **kwargs)
|
||||
else:
|
||||
return patches.Circle(self._origin, self._extent, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"Region: '{self._name}' of {self._shape_type} shape."
|
||||
|
@ -7,7 +7,7 @@ from ..tracking_data import TrackingData
|
||||
|
||||
|
||||
class DLCReader(object):
|
||||
|
||||
"""Class that represents the tracking data stored in a DeepLabCut hdf5 file."""
|
||||
def __init__(self, results_file, crop=(0, 0)) -> None:
|
||||
"""
|
||||
If the video data was cropped before tracking and the tracked positions are with respect to the cropped images, we may want to correct for this to convert the data back to absolute positions in the video frame.
|
||||
|
@ -6,23 +6,37 @@ class TrackingData(object):
|
||||
These data are the x, and y-positions, the time at which the agent was detected, and the quality associated with the position estimation.
|
||||
TrackingData contains these data and offers a few functions to work with it.
|
||||
Using the 'quality_threshold', 'temporal_limits', or the 'position_limits' data can be filtered (see filter_tracks function).
|
||||
The 'interpolate' function allows to fill up the gaps that be result from filtering with linearly interpolated data points.
|
||||
The 'interpolate' function allows to fill up the gaps that may result from filtering with linearly interpolated data points.
|
||||
|
||||
More may follow...
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
x,
|
||||
y,
|
||||
time,
|
||||
quality,
|
||||
node="",
|
||||
fps=None,
|
||||
quality_threshold=None,
|
||||
temporal_limits=None,
|
||||
position_limits=None,
|
||||
) -> None:
|
||||
def __init__(self, x, y, time, quality, node="", fps=None,
|
||||
quality_threshold=None, temporal_limits=None, position_limits=None) -> None:
|
||||
"""
|
||||
Initialize a TrackingData object.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : float
|
||||
The x-coordinates of the tracking data.
|
||||
y : float
|
||||
The y-coordinates of the tracking data.
|
||||
time : float
|
||||
The time vector associated with the x-, and y-coordinates.
|
||||
quality : float
|
||||
The quality score associated with the position estimates.
|
||||
node : str, optional
|
||||
The node name associated with the data. Default is an empty string.
|
||||
fps : float, optional
|
||||
The frames per second of the tracking data. Default is None.
|
||||
quality_threshold : float, optional
|
||||
The quality threshold for the tracking data. Default is None.
|
||||
temporal_limits : tuple, optional
|
||||
The temporal limits for the tracking data. Default is None.
|
||||
position_limits : tuple, optional
|
||||
The position limits for the tracking data. Default is None.
|
||||
"""
|
||||
self._orgx = x
|
||||
self._orgy = y
|
||||
self._orgtime = time
|
||||
@ -61,11 +75,19 @@ class TrackingData(object):
|
||||
|
||||
@property
|
||||
def quality_threshold(self):
|
||||
"""Property that holds the quality filter setting.
|
||||
|
||||
Returns
|
||||
-------
|
||||
float : the quality threshold
|
||||
"""
|
||||
return self._threshold
|
||||
|
||||
@quality_threshold.setter
|
||||
def quality_threshold(self, new_threshold):
|
||||
"""Setter of the quality threshold that should be applied when filterin the data. Setting this to None removes the quality filter.
|
||||
"""Setter of the quality threshold that should be applied when filtering the data. Setting this to None removes the quality filter.
|
||||
|
||||
Data points that have a quality score below the given threshold are discarded.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -76,11 +98,18 @@ class TrackingData(object):
|
||||
|
||||
@property
|
||||
def position_limits(self):
|
||||
"""
|
||||
Get the position limits of the tracking data.
|
||||
|
||||
Returns:
|
||||
tuple: A 4-tuple containing the start x, and y positions, width and height limits.
|
||||
"""
|
||||
return self._position_limits
|
||||
|
||||
@position_limits.setter
|
||||
def position_limits(self, new_limits):
|
||||
"""Sets the limits for the position filter. 'new_limits' must be a 4-tuple of the form (x0, y0, width, height). If None, the limits will be removed.
|
||||
Data points outside the position limits are discarded.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -101,16 +130,30 @@ class TrackingData(object):
|
||||
|
||||
@property
|
||||
def temporal_limits(self):
|
||||
"""
|
||||
Get the temporal limits of the tracking data.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing the start and end time of the tracking data.
|
||||
"""
|
||||
return self._time_limits
|
||||
|
||||
@temporal_limits.setter
|
||||
def temporal_limits(self, new_limits):
|
||||
"""Limits for temporal filter. The limits must be a 2-tuple of start and end time. Setting this to None removes the filter.
|
||||
|
||||
Data points the are associated with times outside the limits are discarded.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
new_limits : 2-tuple
|
||||
The new limits in the form (start, end) given in seconds.
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError if the limits are not valid.
|
||||
"""
|
||||
if new_limits is not None and not (
|
||||
isinstance(new_limits, (tuple, list)) and len(new_limits) == 2
|
||||
@ -166,7 +209,7 @@ class TrackingData(object):
|
||||
self._quality = self._quality[indices]
|
||||
|
||||
def positions(self):
|
||||
"""Returns the filtered data (if filters have been applied).
|
||||
"""Returns the filtered data (if filters have been applied, otherwise the original data).
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -184,7 +227,7 @@ class TrackingData(object):
|
||||
def speed(self, x=None, y=None, t=None):
|
||||
""" Returns the agent's speed as a function of time and position. The speed estimation is associated to the time/position between two sample points. If any of the arguments is not provided, the function will use the x,y coordinates that are stored within the object, otherwise, if all are provided, the user-provided values will be used.
|
||||
|
||||
Since the velocities are estimated from the difference between two sample points the returned velocities are assigned to positions and times between the respective sampled positions/times.
|
||||
Since the velocities are estimated from the difference between two sample points the returned velocities and positions are assigned to positions and times between the respective sampled positions/times.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -204,11 +247,12 @@ class TrackingData(object):
|
||||
The position
|
||||
"""
|
||||
if x is None or y is None or t is None:
|
||||
x = self._x
|
||||
y = self._y
|
||||
t = self._time
|
||||
speed = np.sqrt(np.diff(x)**2 + np.diff(y)**2) / np.diff(t)
|
||||
t = t[:-1] + np.diff(t) / 2
|
||||
x = self._x.copy()
|
||||
y = self._y.copy()
|
||||
t = self._time.copy()
|
||||
dt = np.diff(t)
|
||||
speed = np.sqrt(np.diff(x)**2 + np.diff(y)**2) / dt
|
||||
t = t[:-1] + dt / 2
|
||||
x = x[:-1] + np.diff(x) / 2
|
||||
y = y[:-1] + np.diff(y) / 2
|
||||
|
||||
|
@ -22,11 +22,26 @@ class RegionShape(Enum):
|
||||
|
||||
|
||||
class AnalysisType(Enum):
|
||||
"""
|
||||
Enumeration representing different types of analysis used when analyzing whether
|
||||
positions fall into a given region.
|
||||
|
||||
Possible types:
|
||||
AnalysisType.Full: considers both, the x- and the y-coordinates
|
||||
AnalysisType.CollapseX: consider only the x-coordinates
|
||||
AnalysisType.CollapseY: consider only the y-coordinates
|
||||
"""
|
||||
Full = 0
|
||||
CollapseX = 1
|
||||
CollapseY = 2
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""
|
||||
Returns the string representation of the analysis type.
|
||||
|
||||
Returns:
|
||||
str: The name of the analysis type.
|
||||
"""
|
||||
return self.name
|
||||
|
||||
class PositionType(Enum):
|
||||
|
Loading…
Reference in New Issue
Block a user