MRtrix3 / mrtrix3

MRtrix3 provides a set of tools to perform various advanced diffusion MRI analyses, including constrained spherical deconvolution (CSD), probabilistic tractography, track-density imaging, and apparent fibre density
http://www.mrtrix.org
Mozilla Public License 2.0
294 stars 180 forks source link

New command: maskmath #417

Open Lestropie opened 8 years ago

Lestropie commented 8 years ago

Many people don't appreciate that bitwise image operations can be handled using mrcalc or mrmath. I wonder if having a maskmath command, that would handle bitwise operations (and, or, xor) either across volumes, or across an axis, would be more discoverable?

dchristiaens commented 8 years ago

What are the objections to handling bitwise operations in mrcalc? I, for one, am not one of those people...

jdtournier commented 8 years ago

I guess this relates to some of the discussion we had a while back about separating bitwise operation into a dedicated maskfilter command, leaving the continuous operations into mrfilter. I wasn't too convinced about having these commands separated, but at least I could see the rationale for it - and more importantly I didn't see any obvious downsides. In this case however, I really think it would be a bad idea. I often find myself mimicking binary operations of this kind using ad-hoc methods, for example:

$ mrcalc in.mif 50 -gt in.mif 100 -lt -mult mask.mif
mrcalc: [100%] computing: ((in.mif > 50) * (in.mif < 100)) ...

to generate a mask of voxels where the input values are between 50 and 100. This would be better written as:

$ mrcalc in.mif 50 -gt in.mif 100 -lt -and mask.mif
mrcalc: [100%] computing: ((in.mif > 50) && (in.mif < 100)) ...

but in the absence of the -and operator, at least I could use -mult to do what I needed. I've been meaning to add binary operations in there for a while...

The main point here however is that I'm using a binary operation together with non-binary inputs - you couldn't do this if you were to split this up into separate commands - or at least it would be more awkward. Here's a more compelling example:

$ mrcalc in.mif 50 -gt in.mif 100 -lt -mult in.mif NaN -if 
mrcalc: [100%] computing: (((in.mif > 50) * (in.mif < 100)) ? in.mif : nan) ...

In this case, we're using a binary operation, but the input and output images are both non-binary.

So to cut a long story short: I think these operations squarely belong in mrcalc...

jdtournier commented 8 years ago

Sorry, just noticed you're talking specifically about mrmath / maskmath... But then we don't have binary operations in mrmath currently...(?)

thijsdhollander commented 8 years ago

To be honest, I was actually confused for a while on where to find erosion/dilation filters when I first started using MRtrix3; as I was looking for them in mrfilter... :wink: After discovering maskfilter, I could somehow understand the decision for that case (even though erosion/dilation operations can also be defined on non-binary images; but we don't have that implemented currently); but as Donald mentioned, that logic doesn't really apply for the cases of mrcalc and mrmath. It's nice to have these commands just working with any datatype, I reckon.

Lestropie commented 8 years ago

Personally I agree, but I get a lot of users asking how to do this kind of thing; many seem to not piece together the equivalence of masking and multiplication. And stack-based calculation / piping is not as comfortable for others as it is for us folk. Maybe 'discoverability' isn't the right term so much as exploiting the binary naming convention: hoping that someone wanting to 'add their masks' might tab-complete mask*, see maskmath, and have a look at the help page. Isn't necessarily mutually exclusive with mrcalc bitwise operators either. Then again, maybe just FAQ entries would be adequate...?

jdtournier commented 8 years ago

That would definitely be my preferred option. Fits in nicely with #328 too...