def nearest_neighbor_centroid(fly1, fly2, normalized=False):
    """Finds the centroid-to-centroid distance to a Fly's nearest neighbor.

    Flies should be tracked from within the same movie.

    Parameters
    ----------
    fly1 : Fly object
        First fly; should have n_frames == fly2.n_frames.

    fly2 : Fly object
        Second fly; should have n_frames == fly1.n_frames.

    normalized : boolean (default = True)
        Whether or not the returned array should be normalized to its
        mean.

    Returns
    -------
    distances : np.ndarray | shape = [fly1.n_frames]
        Centroid-to-centroid distances between fly1 and fly2.
    """
    fly1_centroids = fly1.body.centroid.coords_xy()
    fly2_centroids = fly2.body.centroid.coords_xy()

    distances = np.sqrt((fly1_centroids[:, 0] - fly2_centroids[:, 0])**2 +
                        (fly1_centroids[:, 1] - fly2_centroids[:, 1])**2)

    if normalized:
        return normalize(distances)
    return distances
def change_in_area(fly, normalized=False):
    """Calculates the first derivative of the area
    of the ellipse fitted to a fly.

    Parameters
    ----------
    fly : Fly object

    normalized : boolean (default=False)
        Whether or not the first derivative should be normalized to its mean.

    Returns
    -------
    d_area : np.ndarray | shape = [fly.n_frames - 1]
    """
    area = fly.body.area()
    d_area = np.diff(area) / np.diff(fly.timestamps).astype(np.float)

    if normalized:
        return normalize(d_area)
    return d_area
def change_in_minor_axis_length(fly, normalized=False):
    """Calculates the first derivative of the length
    of the minor axis of the ellipse fitted to a fly.

    Parameters
    ----------
    fly : Fly object

    normalized : boolean (default=False)
        Whether or not the first derivative should be normalized to its mean.

    Returns
    -------
    d_min_ax_len : np.ndarray | shape = [fly.n_frames - 1]
    """
    min_ax_len = fly.body.minor_axis_length
    d_min_ax_len = np.diff(min_ax_len) / np.diff(fly.timestamps).astype(
        np.float)

    if normalized:
        return normalize(d_min_ax_len)
    return d_min_ax_len
def centroid_velocity(fly, normalized=False):
    """Calculates the velocity of a fly based of the movement of its centroid.

    Parameters
    ----------
    fly : Fly object

    normalized : boolean (default=False)
        Whether or not the velocity should be normalized to its mean.

    Returns
    -------
    centroid_velocity : np.ndarray | shape = [fly.n_frames]
    """
    centroids = fly.body.centroid.coords_xy()
    squared_differences = np.diff(centroids, axis=0)**2
    distance_traveled = np.sqrt(np.sum(squared_differences, axis=1))
    velocity = distance_traveled / np.diff(fly.timestamps).astype(np.float)
    velocity = np.hstack((0, velocity))

    if normalized:
        return normalize(velocity)

    return velocity