From 75c9c408aa5a9a254cfd3e2ddfd102798afb053a Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Thu, 25 Apr 2024 12:16:36 +0200 Subject: Adding __truedic__ operator to GazePosition. Adding centroid and distances method to TimestampedGazePositions. --- src/argaze/GazeFeatures.py | 53 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/src/argaze/GazeFeatures.py b/src/argaze/GazeFeatures.py index 286a554..32b7de7 100644 --- a/src/argaze/GazeFeatures.py +++ b/src/argaze/GazeFeatures.py @@ -151,6 +151,17 @@ class GazePosition(tuple, DataFeatures.TimestampedObject): The returned position timestamp is the self object timestamp. """ return GazePosition(tuple(numpy.array(self) * factor), precision=self.__precision * factor if self.__precision is not None else None, timestamp=self.timestamp) + + def __truediv__(self, factor: int | float | tuple) -> Self: + """divide position by a factor. + + !!! note + The returned position precision is also divided by the factor. + + !!! note + The returned position timestamp is the self object timestamp. + """ + return GazePosition(tuple(numpy.array(self) / factor), precision=self.__precision / factor if self.__precision is not None else None, timestamp=self.timestamp) def __pow__(self, factor: int | float) -> Self: """Power position by a factor. @@ -226,6 +237,30 @@ class TimeStampedGazePositions(DataFeatures.TimestampedObjectsList): return TimeStampedGazePositions({ast.literal_eval(ts_str): json_positions[ts_str] for ts_str in json_positions}) ''' + def centroid(self) -> numpy.array: + """Calculate positions' centroid. + + Returns: + centroid: centroid of all positions. + """ + + positions_array = numpy.asarray(self.values()) + centroid = numpy.mean(positions_array, axis=0) + + return (centroid[0], centroid[1]) + + def distances(self, point: numpy.array) -> numpy.array: + """Calculate all positions' distances to a point. + + Returns: + distances: array with all distances to the point. + """ + + positions_array = numpy.asarray(self.values()) + distances_array = numpy.sqrt(numpy.sum((positions_array - point)**2, axis=1)) + + return distances_array + @classmethod def from_dataframe(cls, dataframe: pandas.DataFrame, timestamp: str, x: str, y: str, precision: str = None, message: str = None) -> Self: @@ -370,14 +405,12 @@ class GazeMovement(TimeStampedGazePositions, DataFeatures.TimestampedObject): message: a string to describe why the movement is what it is. """ - def __new__(cls, positions: TimeStampedGazePositions = None, finished: bool = False, - message: str = None, timestamp: int | float = math.nan): + def __new__(cls, positions: TimeStampedGazePositions = None, **kwargs): # noinspection PyArgumentList return TimeStampedGazePositions.__new__(cls, positions) - def __init__(self, positions: TimeStampedGazePositions = None, finished: bool = False, - message: str = None, timestamp: int | float = math.nan): + def __init__(self, positions: TimeStampedGazePositions = None, finished: bool = False, message: str = None, timestamp: int | float = math.nan): """Initialize GazeMovement""" TimeStampedGazePositions.__init__(self, positions) @@ -476,8 +509,8 @@ class GazeMovement(TimeStampedGazePositions, DataFeatures.TimestampedObject): class Fixation(GazeMovement): """Define abstract fixation as gaze movement.""" - def __init__(self, positions: TimeStampedGazePositions = TimeStampedGazePositions(), finished: bool = False, - message: str = None, **kwargs): + def __init__(self, positions: TimeStampedGazePositions = TimeStampedGazePositions(), finished: bool = False, message: str = None, **kwargs): + super().__init__(positions, finished, message, **kwargs) self._focus = () @@ -487,11 +520,6 @@ class Fixation(GazeMovement): """Get representative position of the fixation.""" return self._focus - @focus.setter - def focus(self, focus: tuple): - """Set representative position of the fixation.""" - self._focus = focus - def merge(self, fixation) -> Self: """Merge another fixation into this fixation.""" @@ -1072,8 +1100,7 @@ class AOIScanPath(list): size = len(self.__expected_aoi) # noinspection PyAttributeOutsideInit - self.__transition_matrix = pandas.DataFrame(numpy.zeros((size, size)), index=self.__expected_aoi, - columns=self.__expected_aoi) + self.__transition_matrix = pandas.DataFrame(numpy.zeros((size, size)), index=self.__expected_aoi, columns=self.__expected_aoi) def __get_aoi_letter(self, aoi): -- cgit v1.1