dwi2mask: Fix for low image intensities#1083
Conversation
When an input DWI contains exceptionally low values (i.e. even in the b=0 volumes there's no voxels greater than 1.0), dwi2mask will provide an empty mask, which can cause errors at later steps (e.g. providing an empty processing mask to eddy in dwipreproc). Somehow, changing the syntax by which the sum of image intensities within a shell is calculated resolves the issue.
|
Ok, I was first a bit at a loss how that could actually make a difference. Numerically, nothing really changed. There's also only really 2 (simple) ways I can think of to compute means, both being better in one or a different scenario: you could either sum everything and divide by the count, or you could first divide everything by the count and then sum all the outcomes. The latter takes more operations but is better protected against overflow, the former is better protected against underflow or low precision or something. But those things haven't changed between both implementations... So it must be about what precision is used somehow for the summing operation. But unless the compiler does something clever (or dumb) in one of those scenarios that sets it apart from the other one, they're just both loops that each time add a number to an existing total. I'm not into what compilers these days can detect to e.g. see we're after a sum of a lot of numbers here, and then do something else than adding each number in that exact order sequentially to an accumulating total... The only thing I suspect can really drive this difference is this line having So all that to say that: I think there may be a possibility to fix it without doing away with the one liner of the original version. But it doesn't really matter in practice: if the proposed new implementation fixes it just as well, then we're good! So I'll approve the pull request already any way. |
thijsdhollander
left a comment
There was a problem hiding this comment.
If it does the job, then I'm good with it! As I mentioned, I suppose something originally led to a mix of types, and integer arithmetic then being performed at line 92.
|
OK, the explanation is much simpler: the ternary comparison operator has a return type, and that type is determined by the first return option. In other words, in Happy with the current fix as it stands though, the mean should always be considered to be floating-point even for integer inputs, and using |
|
Ah of course. Was thinking that somehow something was operating as an integer because of being an integer image type with a tiny intensity multiplier, but that never made sense to me. Prefer proposed change since it results in one call to |
When an input DWI contains exceptionally low values (i.e. even in the b=0 volumes there's no voxels greater than 1.0),
dwi2maskwill provide an empty mask, which can cause errors at later steps (e.g. providing an empty processing mask toeddyindwipreproc). Somehow, changing the syntax by which the sum of image intensities within a shell is calculated resolves the issue.Thanks to Hamed Zivariadab for reporting the issue & providing data.
It's literally this change that fixes the issue... 🤷♂️