-
Notifications
You must be signed in to change notification settings - Fork 180
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
WIP: Implement Pydra code-generators #2665
base: dev
Are you sure you want to change the base?
Conversation
As mentioned in #2605, Python will require #1392 via ankitasanil#1 to have typed command-line parameters. |
I have written the Python version as best as I can with the current level of typing, but you are right that it will need more type information to get it to work in a guaranteed way. On typing of files, how many different formats does MRtrix interact with (e.g. bvec, bval, response.txt, etc...) and would it be too much to ask to be able to give each format its own ArgType (like Image* and Track* do currently)? Because I have a PR that refactors Pydra's type-checking to be aware of file-formats (nipype/pydra#662), and it would be great to be able to specify them exactly instead of defaulting to a generic |
Assuming upstream exclusion of images & tractograms from that set, here's what comes to mind:
As far as further custom types in user interfacing, I would argue that:
Curious to hear others' thoughts. |
Yes, maybe file formats is a bit of a misnomer, data types would be more accurate/actually what is captured in Pydra. In any case, it would be very helpful on the Pydra code-gen front if these file-data-types could be specified at bit finer granularity |
Ok, so this just needs some unit tests to test out the generated Pydra interfaces and to wait for #1392. @Lestropie, on the unit tests, do you think it would be an issue if I added a |
If you don't want to clutter the help menu further, maybe there could be special configure arg to insert it in? |
One note I might throw in here just because I encountered it while working on the code and it's of some limited relevance. For a command-line option, in C++, you specify the option, and then you can specify some number of compulsory command-line arguments that must follow that option, and get consumed from the command-line by the parser immediately following the appearance of the option. Each of those arguments may have its own type. In Python, this can't currently be done. In |
cb2e711
to
0dff23a
Compare
I think the typical way to represent this is to use the |
Having had a small taste of Pydra now, this might be better than doing the most permissible thing of just accepting any string in such a scenario, but doesn't fully address the issue to the extent that the MRtrix3 C++ interface does, at least to the best of my understanding. Say for instance a command-line option takes as input a string and then an integer. Yes you could make that command-line option a PS. Relevance to #2580: making the argument types in C++ a bitwise flag indicating what set of types is permissible would be faithful to the |
…make it more pydronic
@tclose: After discussion with @jdtournier, there is trepidation about embedding the Pydra interfaces within the repository. On the plus side, it would enforce consistency, PR changeset would show interface changes that might otherwise be invisible to the CI checks of the online documentation, and be convenient from the perspective of workflow managers grabbing both the software and the interface to it. On the minus side, it's implicitly taking on management responsibility for interfaces to an environment for which none of the core development team have experience; even if the interfaces were to be committed in a functional state, and the MRtrix3 commands were to not change, it would nevertheless be possible for there to be changes to Pydra that would necessitate revisions here. What would it look like from the Pydra perspective if the MRtrix3 Pydra interface were to be provided as a stand-alone repository? Ie. What would be the magnitude of inconvenience? There's obviously the issue that on a tagged release of MRtrix3 you would need to update that external repository and generate a corresponding tag. |
@Lestropie @jdtournier just to clarify that the interfaces are not being stored, instead generated from the MRtrix C++ & Python command declarations (see It would be great if the print_usage_pydra special command (or whatever it is called) can live in the MRtrix source, as I'm not sure it will be easy to implement/maintain that in a separate code-base (if possible at all). However, the generation code and Python package can be stored in a separate repository if required. This is what has been typically done for other toolboxes. We are hoping to move to a model where the Pydra interfaces could be integrated into the tool source repos to make it easier for them them stay in step with each other. Given it is my code, I'm happy to put my hand up to deal with any issues that might arise, as I would need to do this if it were stored in a separate repository. But in any case, totally up to you guys, I can integrate the changes into the existing nipype/pydra-mrtrix3 repo instead. |
Hey @tclose! No problem at all from our point of view to include the code responsible for producing the interface definitions. That would indeed be really tricky to maintain outside of the core repo, but it's not something that I expect to change much once implemented, and it makes sense for it to be there. I would opt for a name such as The bigger question from my point of view is whether to store the generated definitions in the core repo. It's trivial to generate them at build-time, and maybe make it part of the CMake install or something. But that doesn't require the generated interface definitions themselves to also be stored on the main repo. What I was trying to figure out was how you envisage these files to be used in practice. If they're stored alongside a full MRtrix install, it would be possible for an application like Pydra to query them at run-time and offer a version of the interface that is always guaranteed to be in lock-step with the version of MRtrix installed. If they're stored elsewhere, then there is always the risk of a mismatch between the version installed and the interface files, which could lead to odd errors. I expect with that kind of approach, you would need to host interface definitions for each version of MRtrix, along with the ability to determine the current version of MRtrix, and would only guarantee correct operation for official release versions. But the main reason I'm discussing this is because in the former case, I don't see a need to host these interface definitions on the main repo, while I might see a call for that with the latter approach (though I still think it would be cleaner from our point of view to have them hosted elsewhere, presumably somewhere more obviously related to the Pydra project). What do you reckon? |
It might be the case that we need to consider separately:
I wondered about an intermediate solution where we do 1 and 2 but not 3. However I don't think that that solves @jdtournier's concerns, and it might not make @tclose's handling any cleaner. |
Ooops, I just realised that in between switching between the old build script and the cmake version I inadvertently committed my old pre-cmake build directory to the branch, which might have been confusing things. After speaking to Rob today we decided to strip everything out of this PR except to the The Pydra export is actually Python code rather than JSON so it will need to be specific to Pydra if that is ok. Also, the interface syntax is likely/hopefully going to change a fair bit in the near future if my proposal is accepted, so we can probably just leave this PR as a WIP until then (I can build and release the package on PyPI with this dev branch in the mean time) and the first cmake release. |
@@ -57,7 +57,7 @@ void usage() { | |||
ARGUMENTS | |||
+ Argument ("amps", "the amplitudes image").type_image_in() | |||
+ Argument ("mask", "the mask containing the voxels from which to estimate the response function").type_image_in() | |||
+ Argument ("directions", "a 4D image containing the estimated fibre directions").type_image_in() | |||
+ Argument ("directions_image", "a 4D image containing the estimated fibre directions").type_image_in() |
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 changed this to avoid a clash with an option of the same name
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.
(Hid / resolved prior post about the same issue)
Issue here is that the argument "directions
" and the command-line option "directions
" encode two very different pieces of information; so disambiguating by calling one an "image" may not be the optimal change. I'm hesitant to change the command-line option, as there are many commands relating to "amp
" images that have an option "-directions
" (even if it's not currently centralised with a const Option
in core/
/ src/
). Conversely, the functionality of the positional argument here also appears in other commands; so renaming it to something different only here would also be slightly unusual.
A few possibilities come to mind:
-
Across various commands (thinking
dwi2response
in particular), where an image encoding a unit 3-vector per voxel is used, adopt "orientations
" rather than "directions
". -
While it's technically applicable to the data type in terms of command naming convention, "
peaks
" would likely not be a good choice here, since can't have multiple vectors per voxel, and the data may have been derived using some approach other than ODF peak-finding. -
Rename here (and preferably in other comparable instances also) to "
fibre_directions
". -
Create a function that returns an
Option
, creating the current "-directions
" command-line option with a custom help string per use (I'm pretty sure from experience it's the considerable difference in these help strings that has caused there to not be centralisation of this command-line option). Once this works, change the command-line option name to something like "-amp_directions
".
(We might need to think carefully about our use of the header field"Directions"
also...)
|
Implementation of #2605
Tasks:
__print_pydra_usage__
for C++ commands.__print_pydra_usage__
for Python commandshatchling
?)pydra-mrtrix3
package to PyPIBlocked by:
run.command()
: Support for command-line piping #1392 so that Python commands type file-types