-
Notifications
You must be signed in to change notification settings - Fork 532
Adding niftyseg #1911
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
Adding niftyseg #1911
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1911 +/- ##
=========================================
Coverage ? 72.12%
=========================================
Files ? 1115
Lines ? 56246
Branches ? 8083
=========================================
Hits ? 40568
Misses ? 14397
Partials ? 1281
Continue to review full report at Codecov.
|
Hi, I think we are finally good with this branch to add niftyseg interface to nipype. Let me know if you have any question. Kind Regards, |
I'll look at this after #1913 is merged 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty mature and almost ready for merge. Great job!
The only outstanding issue is: why not creating just one nifty
package? Then, the niftyreg and niftyseg interfaces would be inside.
If we finally have two submodules (and not one, as I propose). I think it'd be important to remove nipype/interfaces/niftyseg/base.py
and import everything from nipype.interfaces.niftyreg.base
. All the duplicated code should be removed.
Top-level namespace for niftyseg. | ||
""" | ||
|
||
from .base import no_niftyseg, get_custom_path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these used outside the module? If not, I'd remove them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmm I don't think so. I will remove them.
return None | ||
|
||
if ranking == 'ALL': | ||
return '-%s' % ranking |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
woudn't return '-ALL'
be more readable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes indeed, we can do that.
nipype/interfaces/niftyseg/em.py
Outdated
desc='4D file containing the priors', | ||
xor=['no_prior', 'priors']) | ||
|
||
desc = 'List of priors filepaths.' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not setting this string directly on the argument? (this holds for many traits defined below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, it was for style and not go over 80 chars when they are very long but I should put this one back there as well as the other one.
try: | ||
out_files = load_json(outfile)['files'] | ||
except IOError: | ||
return self.run().outputs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am doubtful of this self.run()
, WDYT @satra?
outputs = self._outputs() | ||
# local caching for backward compatibility | ||
outfile = os.path.join(os.getcwd(), 'CalcTopNCC.json') | ||
if runtime is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't be better to check for non-empty runtime.stdout as well?:
if runtime is None or not runtime.stdout:
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure. Thanks.
nipype/interfaces/niftyseg/maths.py
Outdated
_dtypes = ['float', 'char', 'int', 'short', 'double', 'input'] | ||
|
||
desc = 'datatype to use for output (default uses input type)' | ||
output_datatype = traits.Enum(*_dtypes, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is totally stylistic, but _dtypes is not used anymore right?, why not having the options in the Enum initialization?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure.
nipype/interfaces/niftyseg/stats.py
Outdated
>>> node = niftyseg.UnaryStats() | ||
>>> node.inputs.in_file = 'im1.nii' | ||
>>> node.inputs.operation = 'v' | ||
>>> node.cmdline # doctest: +ALLOW_UNICODE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think all these interfaces would deserve some more doctests with more operations, so that we are sure that they work and that we don't break them in future maintenance.
nipype/interfaces/niftyseg/maths.py
Outdated
>>> node.inputs.operand_file = 'im2.nii' | ||
>>> node.inputs.output_datatype = 'float' | ||
>>> node.cmdline # doctest: +ALLOW_UNICODE | ||
'seg_maths im1.nii -sub im2.nii -odt float im1_sub.nii' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think all these interfaces would deserve some more doctests with more operations, so that we are sure that they work and that we don't break them in future maintenance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think I can follow fslmaths doctests to edit those ones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I had in mind is something closer to the documentation of nipype.interfaces.ants.registration.Registration
: https://github.com/nipy/nipype/blob/master/nipype/interfaces/ants/registration.py#L432-L640
Here, you'll see how the inputs to the interface are varied and then the new cmdline tested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can do that but for those interfaces it's pretty easy, only the operation changed. It's kind of the same than fslmaths.
I added different exemples for some operation but by doing so I realised that I am not checking the inputs for some argument (for example pow, thr, uthr, ... use only a float or min uses only a file). I am adding that to the interface.
Let me know if you approve this and you really want to see one test per operation.
@@ -24,6 +24,7 @@ def configuration(parent_package='', top_path=None): | |||
config.add_subpackage('mne') | |||
config.add_subpackage('mrtrix') | |||
config.add_subpackage('mrtrix3') | |||
config.add_subpackage('niftyseg') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend having only one subpackage. I'll comment on this on the summary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Niftyreg/Niftyseg/Niftyfit are different packages that you install separately. Do you think having only one package won't be odd for the user? What do you think?
I could remove probably the base and use the same commands from niftyreg.base in this package. Or do you mean moving all the code into the same folder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I don't have an special interest for having only one package. Let's observe that preference (reg/seg/fit packages) 👍 .
So if we keep the 3 packages structure, then I'm suggesting here to import from niftyreg.base and remove the duplicated code from niftyseg and niftyfit.
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes sounds good. I jut did the changes and I renamed the function in niftyreg base for something more general like no_nifty_package.
What do you think about the changes?
Also do you prefer to import NiftyRegCommand like this:
import ..niftyreg.base.NiftyRegCommand as NiftySegCommand
Or do as I did?
I will do then the edits on niftyfit when you agree with those changes.
Kind Regards,
Ben
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh there are some issues for the test since most executables in niftyseg don't have a --version options that is working.
I will work on fixing this later today.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I add back the base.py just to create NiftySegCommand because of the version that isn't available for all the executables.
I also edited slightly the base.py for NiftyRegCommand.
The test should pass now.
Let me know what you think.
Cheers,
Ben
Dear nipype team,
We are ready to add niftyseg to nipype. I copied all the interfaces we generated for this package as well as the test.
I tested it with python 2 and python 3. It's working on my computer.
Let me know if you see anything not compatible or that I should change.
Kind Regards,
Ben