Skip to content

cpmorphology.maximum_position gives inconsistent results based on values outside the region of interest #130

@afermg

Description

@afermg

This was detected on cp_measure, and I'm pretty sure it's a scipy issue, as I could reproduce the behaviour by directly calling scipy's maximum_position.

import numpy as np
from centrosome.cpmorphology import distance_to_edge, maximum_position_of_labels

masks = np.zeros((240, 240), dtype=int)
masks[50:100, 50:100] = 1  # First square 50x50
masks[80:120, 90:120] = 1  # Major asymmetries on bottom right edge
masks[150:200, 150:200] = 2  # Second square 50x50
masks[175:180, 180:210] = 2  # Minor asymmetries on bottom right edge

masks1 = np.zeros_like(masks)
masks1[50:100, 50:100] = 1  # First square 50x50
masks1[80:120, 90:120] = 1  # Major asymmetries on bottom right edge

masks2 = np.zeros_like(masks)
masks2[150:200, 150:200] = 1  # Second square 50x50
masks2[175:180, 180:210] = 1  # Minor asymmetries on bottom right edge

res = []
for m in (masks, masks1, masks2):
    uniq = np.unique(m)
    d_to_edge = distance_to_edge(m)
    maxpos = maximum_position_of_labels(d_to_edge, m, uniq[uniq > 0])
    res.append(maxpos)

np.testing.assert_array_equal(
    res[0], np.concatenate((res[1], res[2]), axis=1)
)
"""
AssertionError: 
Arrays are not equal

Max absolute difference: 1
Max relative difference: 0.01351351
 x: array([[ 75, 175],
       [ 75, 175]])
 y: array([[ 75, 174],
       [ 74, 175]])
"""

The behaviour seems to change when there are other values outside the region, even if they belong to another label, the maximum value has a one-off error.

import numpy as np
from scipy.ndimage import maximum_position
from centrosome.cpmorphology import distance_to_edge

masks = np.zeros((240, 240), dtype=int)
masks[50:100, 50:100] = 1  # First square 50x50
masks[80:120, 90:120] = 1  # Major asymmetries on bottom right edge
masks[150:200, 150:200] = 2  # Second square 50x50
masks[175:180, 180:210] = 2  # Minor asymmetries on bottom right edge

d_to_edge = distance_to_edge(masks)
d_to_edge_one_object = d_to_edge.copy()
d_to_edge_one_object[masks == 2] = 0
np.testing.assert_array_equal(
    maximum_position(d_to_edge, masks, [1]),
    maximum_position(d_to_edge_one_object, masks, [1]),
)
"""
AssertionError: 
Arrays are not equal

Mismatched elements: 1 / 2 (50%)
Max absolute difference: 1
Max relative difference: 0.01351351
 x: array([[75, 75]])
 y: array([[75, 74]])
"""

I'll check the code of scipy.ndimage.maximum_position to see if I can figure it out, but I wanted to record this in an issue here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions