Skip to content

get_volume_positions: with allow_missing_positions the tolerances are applied in slices, not mm #464

Description

@CedricConday

In get_volume_positions, the allow_missing_positions=True branch measures how far each slice sits from its nearest integer multiple of the spacing in units of the spacing:

origin_distance_multiples = (origin_distances - origin_distances.min()) / spacing
is_regular = np.allclose(origin_distance_multiples, origin_distance_multiples.round(), rtol=rtol, atol=atol)

atol is documented in mm, and in the regularly-spaced branch it is applied in mm (np.isclose(spacings, spacing, rtol=rtol, atol=atol)). In the missing-positions branch the same atol therefore accepts a larger physical deviation the wider the spacing: a slice 0.5 mm out of place is rejected with atol=0.1 at 1 mm spacing (deviation 0.5 slices) but accepted at 20 mm spacing (deviation 0.025 slices). rtol has the same problem in the other direction: np.allclose makes it relative to the rounded multiple, so it scales with the slice index rather than with the spacing as it does in the regular branch, and the logged "maximum spacing deviation" is printed in slices while the message reads as mm.

Reproduction:

from highdicom.spatial import get_volume_positions
orientation = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
for spacing in [1.0, 5.0, 10.0, 20.0]:
    positions = [[0, 0, 0], [0, 0, spacing], [0, 0, 2 * spacing + 0.5]]
    print(spacing, get_volume_positions(positions, orientation, allow_missing_positions=True, atol=0.1)[0])
# 1.0 None
# 5.0 None
# 10.0 None
# 20.0 20.0   <- 0.5 mm off, accepted

A small fix (compute the deviation in mm against round(multiple) * spacing + min, compare with atol + rtol * |spacing|, log in mm) with a test over several spacings is in #465, in case that is easier to judge than the description; happy to close it if you read this differently.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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