graphomotor.features.drawing_error

Feature extraction module for drawing error-based metrics in spiral drawing data.

 1"""Feature extraction module for drawing error-based metrics in spiral drawing data."""
 2
 3import numpy as np
 4from shapely import geometry, ops
 5
 6from graphomotor.core import models
 7
 8
 9def calculate_area_under_curve(
10    drawn_spiral: models.Spiral, reference_spiral: np.ndarray
11) -> dict[str, float]:
12    """Calculate the area between drawn and reference spirals.
13
14    This function measures the deviation between drawn and reference spirals by
15    computing the enclosed area between them using the shapely library. Lower values
16    indicate better adherence to the template. The algorithm works by creating polygons
17    that connect spiral endpoints, finding intersections between lines, and calculating
18    the total area of the resulting polygons.
19
20    Args:
21        drawn_spiral: The spiral drawn by the subject.
22        reference_spiral: The reference spiral.
23
24    Returns:
25        Dictionary containing the area under curve metric
26    """
27    spiral = drawn_spiral.data[["x", "y"]].values
28    line_drawn = geometry.LineString(spiral)
29    line_reference = geometry.LineString(reference_spiral)
30    first_segment = geometry.LineString([spiral[0], reference_spiral[0]])
31    last_segment = geometry.LineString([spiral[-1], reference_spiral[-1]])
32    merged_line = ops.unary_union(
33        [line_drawn, line_reference, first_segment, last_segment]
34    )
35    polygons = list(ops.polygonize(merged_line))
36    return {"area_under_curve": sum(p.area for p in polygons)}
def calculate_area_under_curve( drawn_spiral: graphomotor.core.models.Spiral, reference_spiral: numpy.ndarray) -> dict[str, float]:
10def calculate_area_under_curve(
11    drawn_spiral: models.Spiral, reference_spiral: np.ndarray
12) -> dict[str, float]:
13    """Calculate the area between drawn and reference spirals.
14
15    This function measures the deviation between drawn and reference spirals by
16    computing the enclosed area between them using the shapely library. Lower values
17    indicate better adherence to the template. The algorithm works by creating polygons
18    that connect spiral endpoints, finding intersections between lines, and calculating
19    the total area of the resulting polygons.
20
21    Args:
22        drawn_spiral: The spiral drawn by the subject.
23        reference_spiral: The reference spiral.
24
25    Returns:
26        Dictionary containing the area under curve metric
27    """
28    spiral = drawn_spiral.data[["x", "y"]].values
29    line_drawn = geometry.LineString(spiral)
30    line_reference = geometry.LineString(reference_spiral)
31    first_segment = geometry.LineString([spiral[0], reference_spiral[0]])
32    last_segment = geometry.LineString([spiral[-1], reference_spiral[-1]])
33    merged_line = ops.unary_union(
34        [line_drawn, line_reference, first_segment, last_segment]
35    )
36    polygons = list(ops.polygonize(merged_line))
37    return {"area_under_curve": sum(p.area for p in polygons)}

Calculate the area between drawn and reference spirals.

This function measures the deviation between drawn and reference spirals by computing the enclosed area between them using the shapely library. Lower values indicate better adherence to the template. The algorithm works by creating polygons that connect spiral endpoints, finding intersections between lines, and calculating the total area of the resulting polygons.

Arguments:
  • drawn_spiral: The spiral drawn by the subject.
  • reference_spiral: The reference spiral.
Returns:

Dictionary containing the area under curve metric