Add BIDS reading support and prepare input loading for pydra workflow#7
Add BIDS reading support and prepare input loading for pydra workflow#7me-pic merged 17 commits intophysiopy:masterfrom
Conversation
physutils/tasks.py
Outdated
| @@ -0,0 +1,34 @@ | |||
| import logging | |||
|
|
|||
| import pydra | |||
There was a problem hiding this comment.
This definitely adds complexity, but since physutils might be used by modules that are not based in pydra, could we try to create a safe import and make it optional, like the one we have for duecredit?
https://github.com/physiopy/phys2denoise/blob/master/phys2denoise/due.py
The idea would then to try from pydra.mark import task, but if it is not found, import task from a stub submodule of physutils. That task would be a decorator that returns the function.
(like here: https://github.com/BMRRgroup/wfTFI/blob/ec5a62cf2ffb347c752293e6234b7c89cebe711d/QSM.py#L7C1-L13C1)
There was a problem hiding this comment.
That task would be a decorator that returns the function
What do you mean here? I'm not sure I understand how you'd like this to be done (mostly given the duecredit example).
I tried doing smth like this, but it didn't really work out
def mark_task_wrapper(func):
try:
import pydra
logger.debug("Pydra is installed and is currently enabled.")
return pydra.mark.task(func)
except ImportError:
logger.warning("Pydra is not installed and is currently disabled. Please install it to use this module.")
return func
There was a problem hiding this comment.
@smoia feel free to check, I implemented it with just a wrapper and it seems to work
|
Other than the changes requested by Stef, LGTM ! |
physutils/tasks.py
Outdated
|
|
||
| @pydra.mark.task | ||
| def transform_to_physio( | ||
| input_file: str, mode="physio", fs=None, bids_parameters=dict(), bids_channel=None |
There was a problem hiding this comment.
It makes a lot of sense to add this as a task, great addition to the phys2denoise workflow and to continue to build up physutils :)
I'd like to suggest changing the name of bids_channel to col_physio_type to increase consistency with the load_from_bids function - since there is not a lot of documentation within the code itself, I think it's important to try to maintain intuitive links!
Beyond that, I'm wondering why the task is named transform_to_physio when it can either transform to physio or read-in an existing physio object. Perhaps e.g. generate_physio would be more appropriate? At minimum I think it's helpful to describe the goal of this task and its potential use cases in the description for the PR. Also, please indicate the change type in the PR description :)
Other than these considerations and what Stef mentioned above regarding avoiding a dependency on pydra, this looks good to me!
There was a problem hiding this comment.
Imo, it's ok as transform_to_physio, as even in case it reads a .phys file, it transforms a pickled Physio object file, into a Physio object instance to be used in further tasks.
Also maybe it'd be better to change the variable name in load_from_bids? It's not an interface variable (not used outside the function scope) so I don't think we should take this naming as a basis
There was a problem hiding this comment.
Kudos on changing name to generate_physio or something similar.
Double kudos on adding a good docstring for explanations!
|
I also added an auto mode, as per physiopy/phys2denoise#57 (comment) |
physutils/tasks.py
Outdated
| def mark_task(pydra_imported=pydra_imported): | ||
| def decorator(func): | ||
| if pydra_imported: | ||
| # If the decorator exists, apply it | ||
| @wraps(func) | ||
| def wrapped_func(*args, **kwargs): | ||
| logger.debug(f"Creating pydra task for {func.__name__}") | ||
| return pydra.mark.task(func)(*args, **kwargs) | ||
|
|
||
| return wrapped_func | ||
| # Otherwise, return the original function | ||
| return func | ||
|
|
||
| return decorator |
There was a problem hiding this comment.
That may work, but I honestly was thinking about something like:
def task(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
In a utils module, and then here:.
try:
from pydra.mark import task
except ImportError:
from .utils import task
physutils/tasks.py
Outdated
| input_file: str, mode="physio", fs=None, bids_parameters=dict(), bids_channel=None | ||
| ) -> Physio: | ||
| if not pydra_imported: | ||
| LGR.warning( |
There was a problem hiding this comment.
| LGR.warning( | |
| LGR.debug( |
setup.cfg
Outdated
| numpy >=1.9.3 | ||
| scipy | ||
| loguru | ||
| pydra |
setup.cfg
Outdated
| scipy | ||
| loguru | ||
| pydra | ||
| pybids |
There was a problem hiding this comment.
Eventually, we need to move this to extras as well (it comes with SO MANY dependencies). Could you please open an issue to generically move as many dependencies as possible to extra dependencies? Not now, but it would be good to do so later.
|
@maestroque do you need any help addressing @smoia's comments? |
|
@maestroque any progress on this side? |
|
@smoia @m-miedema I didnt have in mind that there was something pending for this sorry. As far as i can tell only the dependencies issue opening |
physutils/tasks.py
Outdated
| if not fs: | ||
| fs = None |
There was a problem hiding this comment.
I'm a bit confused about these two lines, was there something you were trying to check?
…trings, rename transform_to_physio function
|
@maestroque @m-miedema @me-pic I opened a PR to @maestroque 's branch: It should take care of most issues. Emphasis on should. |
|
The only thing is that logging is still a bit weird cause it uses logging on one side and loguru on the other. Maybe we should just use logging for the moment? |
A few mods stemming from PR convo
physutils/tests/test_tasks.py
Outdated
| input_file=bids_dir, | ||
| mode="bids", | ||
| bids_parameters=bids_parameters, | ||
| bids_channel="cardiac", |
There was a problem hiding this comment.
This is failing since bids_channel is not a valid argument in the generate_physio function
There was a problem hiding this comment.
Ok just realized looking at the previous comments that bids_channel was changed to col_physio_type in generate_physio, but the test_tasks.py have not been update accordingly
| assert task.inputs.input_file == physio_file | ||
| assert task.inputs.mode == "physio" | ||
| assert task.inputs.fs is None |
There was a problem hiding this comment.
pytest is failing.. inputs is not an attribute included in the Physio class, nor input_file or mode...
There was a problem hiding this comment.
inputs is a pydra task attribute specifying the input struct of the task, it may be that the new changes making pydra optional broke the tests. Before the tests were successful
physutils/tasks.py
Outdated
| # from loguru import logger | ||
|
|
||
| try: | ||
| from pydra import task |
There was a problem hiding this comment.
@smoia Is it possible that here it should be from pydra.mark import task instead of from pydra import task ?
There was a problem hiding this comment.
With that change test_generate_physio_bids_file and test_generate_physio_auto in test_tasks.py are now passing 🤔
There was a problem hiding this comment.
Yes that could be it actually. Thank you for catching it!
|
🚀 PR was released in |
Closes #9
Proposed Changes
transform_to_physiopydra task to be used in all worfklowsChange Type
bugfix(+0.0.1)minor(+0.1.0)major(+1.0.0)refactoring(no version update)test(no version update)infrastructure(no version update)documentation(no version update)otherChecklist before review