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

Miscellaneous updates #901

Merged
merged 54 commits into from
Sep 17, 2021
Merged

Miscellaneous updates #901

merged 54 commits into from
Sep 17, 2021

Conversation

ZviBaratz
Copy link
Contributor

Getting a little acquainted with the codebase and proposing a few fixes and updates.

@ZviBaratz
Copy link
Contributor Author

4c1d755 resolves #899.

@pep8speaks
Copy link

pep8speaks commented Feb 26, 2021

Hello @ZviBaratz, Thank you for updating!

Cheers! There are no style issues detected in this Pull Request. 🍻 To test for issues locally, pip install flake8 and then run flake8 niworkflows.

Comment last updated at 2021-02-26 10:11:22 UTC

@ZviBaratz
Copy link
Contributor Author

@oesteban @effigies I'm taking a lot of liberty introducing new development dependencies and tidying up whatever I can. There are quite a few "aesthetic" changes I'm proposing (e.g. using isort, creating a messages module to store all the long strings to reduce clutter, standardizing all the caption symbols in .rst files, etc.,), I genuinely hope I'm not imposing my ideas on your project and these changes do in fact constitute a contribution and not the opposite.

Copy link
Member

@oesteban oesteban left a comment

Choose a reason for hiding this comment

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

Thanks much for this effort. I left a few comments, but this is very much needed.

.circleci/config.yml Outdated Show resolved Hide resolved
docs/source/classifier.rst Outdated Show resolved Hide resolved
docs/source/conf.py Outdated Show resolved Hide resolved
docs/source/cv/base.rst Outdated Show resolved Hide resolved
docs/source/cv/base.rst Outdated Show resolved Hide resolved
docs/source/install.rst Outdated Show resolved Hide resolved
Comment on lines +4 to +5
from mriqc.utils.bids import collect_bids_data
from mriqc.utils.misc import reorder_csv
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
from mriqc.utils.bids import collect_bids_data
from mriqc.utils.misc import reorder_csv
from .bids import collect_bids_data
from .misc import reorder_csv

Why absolute imports here?

Copy link
Member

Choose a reason for hiding this comment

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

PEP 8:

Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages) if the import system is incorrectly configured (such as when a directory inside a package ends up on sys.path):

import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example

However, explicit relative imports are an acceptable alternative to absolute imports, especially when dealing with complex package layouts where using absolute imports would be unnecessarily verbose:

from . import sibling
from .sibling import example

Standard library code should avoid complex package layouts and always use absolute imports.

Implicit relative imports should never be used and have been removed in Python 3.

On this advice, I've generally been moving toward absolute imports when I update code.

Copy link
Member

Choose a reason for hiding this comment

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

Hmmm, that would mandate to run unit tests after installing or explicitly manipulating the PYTHONPATH, correct?

I'm not convinced it is more readable and given that the recommendation is pretty soft, I honestly would rather keep the relative imports.

On the plus side, relative imports help black not to reorder the imports wrongly, alphabetically -- which is another PEP8 recommendation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmmm, that would mandate to run unit tests after installing or explicitly manipulating the PYTHONPATH, correct?

If I understand correctly then no, it shouldn't require that, but in any case let me know whatever you decide, of course I have no problem changing it back if you think it's better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

autodoc might require adding sys.path.insert(0, os.path.abspath("../../")), but considering the documentation seems to be building successfully, it doesn't seem to be an issue.

Comment on lines +17 to +18
from mriqc.workflows.anatomical import anat_qc_workflow
from mriqc.workflows.functional import fmri_qc_workflow
Copy link
Member

Choose a reason for hiding this comment

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

why absolute imports?

mriqc/workflows/anatomical.py Outdated Show resolved Hide resolved
Comment on lines +4 to +5
from mriqc.workflows.anatomical import anat_qc_workflow
from mriqc.workflows.functional import fmri_qc_workflow
Copy link
Member

Choose a reason for hiding this comment

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

absolute imports


def init_mriqc_wf():
"""Create a multi-subject MRIQC workflow."""
from .. import config
from mriqc import config
Copy link
Member

Choose a reason for hiding this comment

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

absolute import

Co-authored-by: Oscar Esteban <code@oscaresteban.es>
@ZviBaratz
Copy link
Contributor Author

Another question regarding import statements - there are many scattered lazy imports. Again, to the best of my understanding, except for some particular edge-cases and/or custom plug-in functionality, this is bad practice. Should I refactor them to appear at the top of the modules?

@oesteban
Copy link
Member

oesteban commented Feb 27, 2021

Nope, those lazy imports respond to a design problem of Nipype and the Linux compilation of cPython.

  1. The problem of cPython: Python never ever clears up memory on Linux, you might reduce a bit with large objects that are removed from the heap (those are garbage-collected) but loaded modules stay on the stack (in VM). In general, this decision is not problematic at all - however in HPC systems and others where the overcommitting policies and/or cgroups impose some limitations to memory utilization then this becomes important. If you run a multiprocessing code on Linux, you'll easily use 850 MB per process (with a very early and clean implementation, maybe you narrow it down to 550MB). With long applications spinning up many processes, the base memory footprint builds up quite a little (even using forkserver and killing workers after running one task, as fMRIPrep and MRIQC do).
  2. Nipype: we run nipype in multiprocessing mode (so we do have the problem above), and nipype loads a humongous amount of modules which build up pretty quickly. In Linux, all those imports make for a big footprint, and with thousands of nodes in the compute graph that have to fork (bc in Linux you generally don't spawn) well, you definitely reach memory limitations (typically virtual memory, so at least you don't get trapped into an infinite swapping).

So, although they are annoying to read, our tendency is going more and more towards these lazy imports.

@ZviBaratz
Copy link
Contributor Author

ZviBaratz commented Feb 28, 2021

@oesteban Thank you! I really appreciate the clear explanation. No problem, lazy imports it is.

Also, it seems I managed to break something already - mriqc_wf in the CLI's run module raises a ModuleNotFoundError for the common module I refactored into two separate interface modules. It seems to have something to do with nipype's caching mechanism trying to load some pickled file, is either of you familiar with this?

@ZviBaratz
Copy link
Contributor Author

Looking at the logs, the execution of niworkflows.interfaces.bids.ReadSidecarJSON is failing because it tries to read the cached results but can't due to the changes in the general structure of the files (common module having been refactored). Is there any easy way to run the tests (once?) without nipype's caching? Could changing the hash_method in nipype's configuration file help?
I realize refactoring the common module is probably not the highest priority at the moment, however, the more I understand how to introduce changes and manage the tests (etc), the more I will be able to contribute in maintaining this repo.

@ZviBaratz
Copy link
Contributor Author

I recreated the interfaces.common module as a directory, which seems to solve the issue with the pickled results. If either of you has any thoughts regarding the exception that was raised it would still be good to know, since I'm assuming we'll encounter it again if things are moved around.

@ZviBaratz
Copy link
Contributor Author

Let me know if there's any verdict regarding absolute imports - I think once that's resolved this PR could be merged, unless there's anything else in this "general scope" of updates that you think would best be included here.

@effigies
Copy link
Member

effigies commented Mar 4, 2021

Hi @ZviBaratz, is there any chance this could be split into separate PRs? With 98 files touched, it's going to be hard to find time to review this in a single go. For instance, reformatted docs would be an easy PR to review in isolation.

I don't know if @oesteban has been able to follow along more closely, and if so, I'm happy to let him finish this review off.

@ZviBaratz
Copy link
Contributor Author

ZviBaratz commented Mar 4, 2021

@effigies other than separating the documentation changes from the rest of the updates (which should be trivial), isolating other changes might be somewhat challenging due to the project-wide actions made to fix linting issues and standardize code formatting. I realize this makes for a somewhat troublesome review, however, if we can get this one massive PR out of the way, in the future I promise to behave.

mriqc/bin/mriqc_clf.py Outdated Show resolved Hide resolved
ZviBaratz and others added 2 commits March 4, 2021 21:21
Co-authored-by: Chris Markiewicz <effigies@gmail.com>
CHANGES.txt Outdated Show resolved Hide resolved
mriqc/classifier/data.py Outdated Show resolved Hide resolved
mriqc/classifier/helper.py Outdated Show resolved Hide resolved
mriqc/cli/run.py Outdated Show resolved Hide resolved
mriqc/cli/run.py Outdated Show resolved Hide resolved
@oesteban oesteban merged commit d4c13bb into nipreps:master Sep 17, 2021
oesteban added a commit that referenced this pull request Oct 4, 2021
21.0.0rc2

First official release after migrating the repository into the *NiPreps*' organization.
This release updates the Docker image with up-to-date dependencies, updates
*MRIQC*'s codebase to the latest *NiTransforms* and includes some minor bugfixes.
Finally, this release also contains a major code style overhaul by Zvi Baratz.
With thanks to @ZviBaratz, @nbeliy, @octomike, @benkay86, @verdurin, and @utooley for their contributions.

  * FIX: ``template_resolution`` deprecation warning (#941)
  * FIX: Set entity ``datatype`` in ``BIDSLayout`` queries (#942)
  * FIX: T2w image of MNI template unavailable in Singularity (#940)
  * FIX: Release process -- Docker deployment not working + Python package lacks WebAPI token (#938)
  * FIX: Revise building documentation at RTD after migration (#935)
  * FIX: Final touch-ups in the maintenance of Docker image + CI (#928)
  * FIX: Update unit tests (#927)
  * FIX: Update dependencies and repair BOLD workflow accordingly (#926)
  * FIX: Update dependencies and repair T1w workflow accordingly (#925)
  * FIX: Set ``matplotlib`` on ``Agg`` output mode (#892)
  * ENH: Optimize *PyBIDS*' layout initialization (#939)
  * ENH: Refactored long strings to a :mod:`mriqc.messages` module (#901)
  * ENH: Refactored :mod:`mriqc.interfaces.common` module (#901)
  * DOC: Various fixes to "Running mriqc" section (#897)
  * MAINT: Updates to ``CONTRIBUTORS.md`` file
  * MAINT: Revise Docker image settings & CircleCI (#937)
  * MAINT: Finalize transfer to ``nipreps`` organization (#936)
  * MAINT: Relicensing to Apache-2.0, for compliance with *NiPreps* and prior transfer to the org (#930)
  * MAINT: New Docker layer caching system of other *NiPreps* (#929)
  * MAINT: Code style overhaul (#901)
  * MAINT: Update ``Dockerfile`` and catch-up with *fMRIPrep*'s (#924)
  * STY: Run ``black`` at the top of the repo (#932)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants