-
Notifications
You must be signed in to change notification settings - Fork 532
[WIP] Major refactor (nipype-1.5 ?) #1371
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
Conversation
…ipype into enh/NameSourceInBaseInterface
Used the following command line to fix all at once: ``` find . -name '*.py' | xargs perl -pi -e 's/(?<!_)(in|out)put_spec/_$1put_spec/g' ```
I don't fully understand what's going on here, but as someone with a lot of code that depends on nipype, this PR and this statement make me very nervous. It seems like a lot of stuff is changing (breaking?) without much rationale for why that is happening. |
That's why I called this transitional. With that question I just wanted to gauge how much effort we want to dedicate to backwards compatibility. If that code you (or any nipype user) have consists of, basically, workflows, it will work with some changes for certain interfaces. We can spend some time in writing the compatibility elements (mainly those changes in inputs/outputs of interfaces). If you have a lot of custom Interfaces, then changes are a bit more delicate. We could provide a version with support for the legacy code for some time, though. I would just need to re-include an empty
EDIT: Please recall that these changes are oriented to give us a more reliable base towards #1301 and additionally provide an easier access to new users (since it simplifies the inputs/outputs and automates a lot of stuff). I agree with you in not to forget about our current users, but this PR is a look into the future. And also, it is far from ready to be merged, this is also important. I early posted it because I needed to ask you for help and to open the development of this branch to discussion. In an effort to refocus the conversation on the current problems: what are your ideas regarding:
|
I find this a little confusing, since the rationale you seem to have provided appears focused entirely on the internals (i.e., not having to write a |
Sorry for my misleading statement. I have edited it in my last post. This would help new users since it will be a lot easier to create an interface in nipype for your custom software. Also, the experience when debugging workflows is a lot better using the dry_runs, for instance. There are more elements, but I think this all should go in the future documentation. |
@@ -665,14 +531,122 @@ def _run_interface(self, runtime): | |||
nrows.append(mc_in.shape[0]) | |||
matrix = self._get_spm_submatrix(spmmat, sessidx, rows) | |||
self._stimcorr_core(motparamlist[i], intensityfiles[i], |
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.
Issue found: Too many positional arguments for method call
@satra, do you think we can schedule that meeting we were considering 2 months ago? |
@oesteban - let's do it - perhaps send out a doodle poll on the mailing list. i've the theoretical refactoring of nipype engine worked out and plan to start implementing it this week. |
BTW, I haven't tried it yet, but if we make traits for everything (interfaces and workflows) as I propose, I think that we could get the FASTR-like expressions very easily using the If we finally don't get that far, using the None of these changes would necessarily affect the current ways of connecting interfaces and workflows. If we wanted to move to traitlets, this is called linking (https://ipython.org/ipython-doc/3/api/generated/IPython.utils.traitlets.html#IPython.utils.traitlets.link). This is actually pretty the same thing we are doing in the deepest core of the But honestly, I think the enthought traits are a bit more powerful. |
@oesteban - we need to follow up on this after the current release. i like many of the ideas here. let's make a concrete todo list after a discussion. |
Starting from #1240, the PR got too large so I think it is best to open a new fresh discussion, with an eye on #1301. This PR can be seen as a transitional work.
The original purpose of my refactor was to extend the
name_source
behaviour of the File traits in the CommandLine interfaces to any interface. Very soon I arrived to a quirky code with lots of branches for handling names. This was not very reliable and started to modify base things.What is new in this refactor:
BaseInterface
now is aHasTraits
object that implements (provides, in the traits jargon) theIBase
interface. Now,inputs
andoutputs
aretraits.Instance
s of the corresponding input/output interfaces (https://github.com/oesteban/nipype/blob/enh/nipype-1.5/nipype/interfaces/base/specs.py#L35). This is good because we forget about type checking, and the access is pretty convenient. It also enables theexist
check for files at the output, bringing earlier potential failures.environ
,terminal_output
,redirect_x
,always_run
,ignore_exceptions
, etc. are now traits of the interfaces (not inputs of some of them or private properties). I have found this pretty convenient so far.File
trait improved so thatexists
is also metadata, and now it can be queried.GenFile
andGenMultiFile
, including a new mini-language to create replacements. Some very cool things can be done now, like generate a range of names of files with string formatting patterns (https://github.com/oesteban/nipype/blob/enh/nipype-1.5/nipype/interfaces/fsl/preprocess.py#L245) or generate one file name for each input file in anInputMultiPath
trait (https://github.com/oesteban/nipype/blob/enh/nipype-1.5/nipype/interfaces/fsl/preprocess.py#L238), or substring patterns (https://github.com/oesteban/nipype/blob/enh/nipype-1.5/nipype/interfaces/fsl/utils.py#L826). Side note: maybe this should call theseStrTemplate
andList(StrTemplate)
and then add the implementation forGenFile
, since these generated strings do not need to be files (for instance, it could be possible to generate a title string including a file name for a report).Command
that encapsulates the code to check if the command is executable and saves the path in a metadata entry.dry_run
argument torun()
, default False, that checks the expected outputs and makes the equivalent tobash touch
on those files missing. This way, we can fake the running of interfaces, making debugging of workflows incredibly easier.parse_args
(now public) and_format_args
now are inside theCommandLineInputSpec
since they only are affected and affect the inputs.What I would propose to include:
InterfaceResult
andRuntime
should also be traited objects (IMHO). Particularly, the runtime could be anInstance
in the interface type. Allowing the use ofself.runtime.value
all along the interface. We would also replace the home-made implementation of Bunch.traits.Event
and to code the logic of interfaces with observable events by the runners... This will ease the runner codes significantly and reduce the busy waits.Workflow
class. Actually, we can make itIBase
compliant. IfWorkflows
fulfilled this interface, they would be interchangeable with unitary interfaces. The concepts would be now split as follows: running plugins only seeNodes
orTasks
to execute. ANode
has inside anIBase
instance (the actual interface) that could also be a workflow. Some little logic can be added to compute the subgraph to split tasks or run the workflow in bulk. This will also make almost immediate to implement the iterfields of workflows.Caveats and problems
_list_outputs
(now should be implemented in a method calledpost_run
, which is a more intuitive name of what you should expect to happen and when).Feedback
Right now I'm a bit stuck with the automatic investigation of outputs. Also with the handling of these automatedly generated inputs, because there are many situations in which we may want to improve the code and avoid superfluous definitions of inputs (i.e. commands that accept a prefix for each output will need an extra input to append the extension, like in some afni interfaces). Many times you find boolean switches that operate on files flags, or even
traits.Either(traits.Bool, File)
. All this logic can get complicated. I haven't tried to port ants to the new style... I bet it can be very much shortened with the new templates, but still a lot of extra definitions will be required.I'm to give myself a couple of days off this PR, so that I can come back with fresh ideas and I give you some time to get through it. Please let me know any feedback you can provide @chrisfilo, @satra, @mwaskom .