Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add merge ROIs feature #9

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

marcobarilari
Copy link
Collaborator

@marcobarilari marcobarilari commented Mar 31, 2021

Open questions:

  • load_nii() is not happy with masks that, I guess, are not resliced in MNI space cause of distortions in the image. Solution? Seems that load_untouch.nii() ignores these distortions but not 100% sure about what it does.

  • how naming the resulting *mask.nii from 2 or more masks? @Remi-Gau

  • sum more than 1 matrix in an elegant way (no for loop)

@marcobarilari marcobarilari added the enhancement New feature or request label Mar 31, 2021
@Remi-Gau
Copy link
Contributor

Remi-Gau commented Apr 1, 2021

Open questions:

* [ ]  `load_nii()` is not happy with masks that, I guess, are not resliced in MNI space cause of distortions in the image. Solution? Seems that `load_untouch.nii()` ignores these distortions but not 100% sure about what it does.

I would try spm_read_vols(spm_vol()) instead.

* [ ]  how naming the resulting `*mask.nii` from 2 or more masks? @Remi-Gau
* [ ]  sum more than 1 matrix in an elegant way (no `for loop`)

My 2 cents: load all images as a "4D" image and use any along the fourth dimension

images = {filenameA; filenameB};

mask = spm_read_vols(spm_vol(images));

mask = any(mask, 4);

This will give a logical true value to any voxel along the 4th dimension that has some non-zero values in it.

So assuming that you gave binary masks as inputs this should be fine.

Further assumptions we have here are the images have the same dimensions.

I think we can make this more flexible by making some sort of recusive call to createROI('mask') but let's worry about that later.

@@ -146,6 +146,33 @@

mask = createRoiLabel(mask);

case 'merge'

roiImages = specification;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are still developping this but I suspect we'll want to have the same way to use specification for all "cases":

so that it will be something like :

specification(1).mask = roi_filenameA
specification(2).mask = roi_filenameB

not necessary to have now but just to let you know that the "API" and the type and name of arguments for this function are still a moving target. :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if this replys to it but in a batch file you would have eg

roiImages = {fullfile(opt.ROI.roiDir, 'label-sphere5xMinus40yMinus50zMinus22_mask.nii'); ...
             fullfile(opt.ROI.roiDir, 'label-sphere5x36yMinus46zMinus17_mask.nii')};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More like this

specification(1).mask = fullfile(opt.ROI.roiDir, 'label-sphere5xMinus40yMinus50zMinus22_mask.nii');
specification(2).mask = fullfile(opt.ROI.roiDir, 'label-sphere5x36yMinus46zMinus17_mask.nii');

end

% check that there are no >1s
mask.img(mask.img > 1) = 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am pretty sure that in this case you can just convert mask.img to a logical array:

mask.img = logical(mask.img);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that using

      % merge the logical masks into one
      mask = any(mask, 4);

will save us from having values >1

although, maybe for the future, we would like to have different values for each single single ROI merged

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you mean having a single image that combines different masks has a different "label" for each ROI: I agree but I would have that as an entirely different function.
And I think that MarsBar must have some functions to do that.

@marcobarilari
Copy link
Collaborator Author

Thanks Remi :)

My 2 cents: load all images as a "4D" image and use any along the fourth dimension

images = {filenameA; filenameB};

mask = spm_read_vols(spm_vol(images));

mask = any(mask, 4);

I am not sure that spm_read_vols(spm_vol(images)) can read multiple files at once.

This will give a logical true value to any voxel along the 4th dimension that has some non-zero values in it.

So assuming that you gave binary masks as inputs this should be fine.

ok great!

Further assumptions we have here are the images have the same dimensions.

Yes indeed, would you add a check for that?

I think we can make this more flexible by making some sort of recusive call to createROI('mask') but let's worry about that later.

@marcobarilari
Copy link
Collaborator Author

last but not least, what about the name? Tricky one if we don't want to end up with a very long one eg:

mask1 = 'label-sphere5xMinus40yMinus50zMinus22_mask.nii'; 

mask2 = 'label-sphere5x36yMinus46zMinus17_mask.nii';

maskMerged = 'label-sphere5xMinus40yMinus50zMinus22PLUSsphere5x36yMinus46zMinus17_mask.nii'

@marcobarilari
Copy link
Collaborator Author

also (this one can become an issue by itself), do you think it would be possible to have a more human-readable label like

label-sphere5leftMT_mask.nii

instead of

label-sphere5xMinus40yMinus50zMinus22_mask.nii,

this way we can have a nicer name for the merged masks like

label-sphere5leftMTsphere5rightMT_mask.nii

@Remi-Gau
Copy link
Contributor

Remi-Gau commented Apr 2, 2021

last but not least, what about the name? Tricky one if we don't want to end up with a very long one eg:

mask1 = 'label-sphere5xMinus40yMinus50zMinus22_mask.nii'; 

mask2 = 'label-sphere5x36yMinus46zMinus17_mask.nii';

maskMerged = 'label-sphere5xMinus40yMinus50zMinus22PLUSsphere5x36yMinus46zMinus17_mask.nii'

I mean I think that last one rolls off the tongue quite easily...

@Remi-Gau
Copy link
Contributor

Remi-Gau commented Apr 2, 2021

I am not sure that spm_read_vols(spm_vol(images)) can read multiple files at once.

I think that if you sue spm_select to create your list of files it will work.

@Remi-Gau
Copy link
Contributor

Remi-Gau commented Apr 2, 2021

also (this one can become an issue by itself), do you think it would be possible to have a more human-readable label like

label-sphere5leftMT_mask.nii

instead of

label-sphere5xMinus40yMinus50zMinus22_mask.nii,

this way we can have a nicer name for the merged masks like

label-sphere5leftMTsphere5rightMT_mask.nii

I would use the renameFile function for that:

roiImage = `label-sphere5xMinus40yMinus50zMinus22_mask.nii`;

roiImage = renameFile(roiImage, ...
                          struct('label', 'sphere 5 left MT', ...
                                 'hs', 'lh'));

See the other_demo.m

@CerenB
Copy link
Collaborator

CerenB commented Apr 2, 2021

I am not sure that spm_read_vols(spm_vol(images)) can read multiple files at once.

I think that if you sue spm_select to create your list of files it will work.

Yes, I "grew up" using load_nii and load_untouch_nii and I investigated it a bit these differences recently. I used load_nii
with MNI space images and load_untouch_nii for native space images/ROIs . And we started using these two because this is what cosmo-mvpa uses. If spm is better (i have only used it recently...) then yes, let's switch to spm for dealing with nii files!

I'm adding @mohmdrezk here in case he has a preference for nifti toolbox some reason that I do not know!

@marcobarilari marcobarilari linked an issue Apr 12, 2021 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ENH] Merge ROIs
4 participants