spatial_resample raises TypeError when spatial_size is None and spatial_rank is 1

Abierto Apto para principiantes
#9,068 2 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
85/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python, pytorch

Línea de trabajo

Comienza en monai/transforms/spatial/functional.py:159 y compara su predicado con el valor predeterminado de monai/utils/misc.py:261; inspecciona otros llamadores de fall_back_tuple que proporcionen predicados explícitos. Ejecuta tests/data/test_nifti_rw.py y tests/data/test_image_rw.py, y confirma que los tamaños espaciales None recurren correctamente al valor alternativo sin TypeError.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Describe the bug

spatial_resample passes lambda x: x >= 0 to fall_back_tuple, but that helper's default predicate is lambda x: x and x > 0, whose x and short-circuits on None. The override does not, so a None element raises TypeError instead of falling back to the default — which is the documented behaviour of fall_back_tuple, and its own docstring says so:

>>> fall_back_tuple((-1, None), (32, 32))
(32, 32)

monai/transforms/spatial/functional.py:159:

spatial_size = torch.tensor(
    fall_back_tuple(ensure_tuple(spatial_size)[:spatial_rank], in_spatial_size, lambda x: x >= 0)
)

spatial_size reaches that line as None whenever the caller did not supply one and spatial_rank <= 1: the branch above it, elif spatial_size is None and spatial_rank > 1, is the only thing that replaces None, so with a rank of 1 the None survives into ensure_tuple(None)(None,)None >= 0.

To Reproduce
import numpy as np
from monai.data.image_writer import NibabelWriter

w = NibabelWriter()
w.set_data_array(np.random.rand(3, 5), channel_dim=None)
w.set_metadata({"affine": np.diag([1, 1, 1]), "original_affine": np.diag([1.4, 1, 1])})
File "monai/data/image_writer.py", line 604, in set_metadata
File "monai/data/image_writer.py", line 273, in resample_if_needed
File "monai/transforms/spatial/array.py", line 229, in __call__
File "monai/transforms/spatial/functional.py", line 159, in <lambda>
    fall_back_tuple(ensure_tuple(spatial_size)[:spatial_rank], in_spatial_size, lambda x: x >= 0)
TypeError: '>=' not supported between instances of 'NoneType' and 'int'

Instrumenting spatial_resample confirms it is entered with spatial_size=None and img.shape=(1, 3, 5).

Expected behavior

None means "no size given for this axis" and should fall back to the corresponding in_spatial_size entry, exactly as fall_back_tuple's docstring describes.

Screenshots / test impact

This is not a corner case reachable only by hand — it fails 8 tests on current dev:

  • tests/data/test_nifti_rw.pytest_write_2d, test_write_3d
  • tests/data/test_image_rw.py — 4 failures + 4 errors across TestRegRes / writer round-trips

Reproduced on unmodified dev (c1240a2d4) in two independent environments:

Python 3.12 / torch 2.13.0 / numpy 2.x fails
Python 3.10 / torch 2.11.0 (highest version CI tests) / numpy 2.2.6 fails identically

So it is not a new-dependency artifact. git log -L159,159 dates that line to #6068 (Feb 2023).

Environment
Ensuring you use the relevant python executable, please paste the output of:
MONAI version: 1.6.0rc1+58.gc1240a2d4
Python: 3.10 and 3.12 (both affected)
PyTorch: 2.11.0 and 2.13.0 (both affected)
numpy: 2.2.6
nibabel: 5.4.2
Additional context

The narrowest fix is to make the predicate None-safe at the call site, matching the helper's default:

lambda x: x is not None and x >= 0

Worth checking the other fall_back_tuple callers that pass an explicit func for the same hazard — any predicate that does not short-circuit on None inherits it.

Lenguaje dominante
Python
Estrellas
8.7k
Forks
1.6k
Merge medio
5 d 1 h
PR fusionados (30 d)
22

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Project-MONAI/MONAI

Todos los issues de Project-MONAI/MONAI

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.