Description
In _apply_ivim_quality_and_swap() (file osipy/ivim/fitting/estimators.py), the domain quality mask is computed before the D*/D swap. Because one of the quality checks is ds_vals > d_vals, any voxel whose optimizer output has D > D* is immediately flagged as bad quality — even though the very next block of code swaps the two values and makes them valid.
Net effect: voxels that only need a harmless label-swap are silently zeroed-out by the quality mask, reducing the number of usable voxels in the perfusion-fraction map.
Steps to Reproduce
import numpy as np
from osipy.common.parameter_map import ParameterMap
# Simulate an optimizer returning D > D* (needs swap)
d_map = ParameterMap(values=np.array([2e-3]), quality_mask=np.ones(1, dtype=bool))
ds_map = ParameterMap(values=np.array([1e-3]), quality_mask=np.ones(1, dtype=bool))
f_map = ParameterMap(values=np.array([0.15]), quality_mask=np.ones(1, dtype=bool))
param_maps = {"D": d_map, "D*": ds_map, "f": f_map}
With the current code the quality check (ds_vals > d_vals) evaluates to False before the swap, so the voxel is marked bad. After swapping, D = 1e-3 and D* = 2e-3, which satisfies every domain constraint.
Expected Behavior
The swap should occur first, and the quality mask should be evaluated on the post-swap values. The voxel above would then pass all quality checks.
Root Cause (code pointer)
osipy/ivim/fitting/estimators.py, function _apply_ivim_quality_and_swap, around line 349-380.
The "Domain quality mask" block precedes the "Ensure D* > D (swap if needed)" block.
Are you working on this?
Yes
Description
In
_apply_ivim_quality_and_swap()(fileosipy/ivim/fitting/estimators.py), the domain quality mask is computed before the D*/D swap. Because one of the quality checks isds_vals > d_vals, any voxel whose optimizer output has D > D* is immediately flagged as bad quality — even though the very next block of code swaps the two values and makes them valid.Net effect: voxels that only need a harmless label-swap are silently zeroed-out by the quality mask, reducing the number of usable voxels in the perfusion-fraction map.
Steps to Reproduce
With the current code the quality check
(ds_vals > d_vals)evaluates toFalsebefore the swap, so the voxel is marked bad. After swapping, D = 1e-3 and D* = 2e-3, which satisfies every domain constraint.Expected Behavior
The swap should occur first, and the quality mask should be evaluated on the post-swap values. The voxel above would then pass all quality checks.
Root Cause (code pointer)
osipy/ivim/fitting/estimators.py, function_apply_ivim_quality_and_swap, around line 349-380.The "Domain quality mask" block precedes the "Ensure D* > D (swap if needed)" block.
Are you working on this?
Yes