Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,10 @@ jobs:
-v /tmp/data:/inputs \
-v /tmp:/tmp \
pennbbl/fixeldb:latest \
--relative-root /inputs \
--directions-file fixeldata/directions.mif \
--index-file fixeldata/index.mif \
--cohort-file test_cohort.csv \
--output-hdf5 fixels.h5
--directions-file /inputs/fixeldata/directions.mif \
--index-file /inputs/fixeldata/index.mif \
--cohort-file /inputs/test_cohort.csv \
--output-hdf5 /inputs/fixels.h5

- store_artifacts:
path: /tmp/data/fixels.h5
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ instance/
# Sphinx documentation
docs/_build/
docs/generated/
docs/auto_examples/

# PyBuilder
target/
Expand Down
10 changes: 10 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,18 @@
'sphinxarg.ext',
'sphinx_copybutton',
'sphinx_rtd_theme',
'sphinx_gallery.gen_gallery',
]

sphinx_gallery_conf = {
'examples_dirs': ['examples'],
'gallery_dirs': ['auto_examples'],
'filename_pattern': r'/plot_',
'abort_on_example_error': False,
'download_all_examples': False,
'plot_gallery': False,
}

templates_path = ['_templates']
source_suffix = {'.rst': 'restructuredtext'}

Expand Down
5 changes: 5 additions & 0 deletions docs/examples/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Walkthroughs
============

Step-by-step guides for converting neuroimaging data to and from the HDF5
format used by `ModelArray <https://pennlinc.github.io/ModelArray/>`_.
150 changes: 150 additions & 0 deletions docs/examples/plot_fixel_workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
"""
Fixel-wise Data Conversion
==========================

For fixel-wise data, use the **``confixel``** command from **ModelArrayIO** to convert between
MRtrix ``.mif`` files and the HDF5 format (``.h5``) used by ModelArray. This guide assumes
ModelArrayIO and MRtrix are already installed.
"""

# %%
# Prepare data
# ------------
#
# To convert a list of fixel-wise data from ``.mif`` to ``.h5`` format, prepare a cohort CSV
# file that describes every ``.mif`` file you want to include. We recommend one CSV per scalar
# (e.g. FD, FC, FDC), yielding one ``.h5`` file per scalar.
#
# Cohort CSV columns (names are fixed, not user-defined):
#
# * ``scalar_name`` — which metric is being analysed (e.g. ``FD``, ``FC``, ``FDC``)
# * ``source_file`` — path to the ``.mif`` file for this subject

# %%
# Example folder structure
# ------------------------
#
# .. code-block:: text
#
# /home/username/myProject/data
# |
# ├── cohort_FD.csv
# │
# ├── FD
# │ ├── index.mif
# │ ├── directions.mif
# │ ├── sub-01_fd.mif
# │ ├── sub-02_fd.mif
# │ ├── sub-03_fd.mif
# │ └── ...
# │
# ├── FC
# │ ├── index.mif
# │ ├── directions.mif
# │ ├── sub-01_fc.mif
# │ ├── sub-02_fc.mif
# │ ├── sub-03_fc.mif
# │ └── ...
# └── ...
#
# These ``.mif`` files are generated by MRtrix.
#
# Corresponding ``cohort_FD.csv`` for scalar FD:
#
# .. list-table::
# :header-rows: 1
# :widths: auto
#
# * - **scalar_name** *(required)*
# - **source_file** *(required)*
# - subject_id
# - age
# - sex
# * - FD
# - FD/sub-01_fd.mif
# - sub-01
# - 10
# - F
# * - FD
# - FD/sub-02_fd.mif
# - sub-02
# - 20
# - M
# * - FD
# - FD/sub-03_fd.mif
# - sub-03
# - 15
# - F
# * - ...
# - ...
# - ...
# - ...
# - ...
#
# Notes:
#
# * Column order does not matter.
# * Values are case-sensitive — folder names, file names, and scalar names must match exactly
# between the CSV and disk.

# %%
# Convert .mif files to HDF5
# --------------------------
#
# Using the FD dataset from the example above:
#
# .. code-block:: console
#
# # activate your conda environment first
# conda activate <env_name>
#
# confixel \
# --index-file /home/username/myProject/data/FD/index.mif \
# --directions-file /home/username/myProject/data/FD/directions.mif \
# --cohort-file /home/username/myProject/data/cohort_FD.csv \
# --output-hdf5 /home/username/myProject/data/FD.h5
#
# This produces ``FD.h5`` in ``/home/username/myProject/data``. You can then use
# `ModelArray <https://pennlinc.github.io/ModelArray/>`_ to run statistical analyses on it.

# %%
# Convert result .h5 back to .mif files
# --------------------------------------
#
# After running ModelArray and obtaining statistical results inside ``FD.h5`` (suppose the
# analysis name is ``"mylm"``), use ``fixelstats_write`` to export them as ``.mif`` files.
# The command also copies the original ``index.mif`` and ``directions.mif`` into the output
# folder.
#
# .. code-block:: console
#
# fixelstats_write \
# --index-file /home/username/myProject/data/FD/index.mif \
# --directions-file /home/username/myProject/data/FD/directions.mif \
# --cohort-file /home/username/myProject/data/cohort_FD.csv \
# --analysis-name mylm \
# --input-hdf5 /home/username/myProject/data/FD.h5 \
# --output-dir /home/username/myProject/data/FD_stats
#
# The results in ``FD_stats`` can now be viewed in ``mrview``.
#
# .. warning::
#
# **Existing files are not overwritten.** ``fixelstats_write`` calls ``mrconvert`` without
# ``-force``, so any ``.mif`` file already present in ``--output-dir`` with the same name
# will be left unchanged. If ``--output-dir`` itself already exists you will see a
# ``WARNING: Output directory exists`` message, but no files will be deleted. To start
# fresh, manually remove the output directory before re-running ``fixelstats_write``.

# %%
# Additional help
# ---------------
#
# Full argument documentation is available from the command line:
#
# .. code-block:: console
#
# confixel --help
# fixelstats_write --help
#
# or in the :doc:`/usage` page of this documentation.
183 changes: 183 additions & 0 deletions docs/examples/plot_voxel_workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
"""
Voxel-wise Data Conversion
==========================

For voxel-wise data, use the **``convoxel``** command from **ModelArrayIO** to convert NIfTI
files to the HDF5 format (``.h5``) used by ModelArray, and ``volumestats_write`` to export
results back to NIfTI. The voxel workflow is very similar to the fixel workflow
(:ref:`sphx_glr_auto_examples_plot_fixel_workflow.py`).
"""

# %%
# Prepare data
# ------------
#
# To convert a list of voxel-wise NIfTI files to ``.h5`` format, you need:
#
# 1. **A cohort CSV** describing every NIfTI file to include (one CSV per scalar recommended).
# 2. **A group mask** — only voxels inside the group mask are kept during conversion.
# 3. **Subject-specific masks** *(optional)* — voxels outside each subject's mask are set to
# ``NaN`` after conversion. If you do not have per-subject masks, supply the group mask for
# every subject (see the CSV example below).
#
# Cohort CSV columns (names are fixed, not user-defined):
#
# * ``scalar_name`` — which metric is being analysed (e.g. ``FA``)
# * ``source_file`` — path to the subject's NIfTI file
# * ``source_mask_file`` — path to the subject-specific mask (or the group mask if none exists)

# %%
# Example folder structure
# ------------------------
#
# .. code-block:: text
#
# /home/username/myProject/data
# |
# ├── cohort_FA.csv
# ├── group_mask.nii.gz
# │
# ├── FA
# │ ├── sub-01_FA.nii.gz
# │ ├── sub-02_FA.nii.gz
# │ ├── sub-03_FA.nii.gz
# │ └── ...
# │
# ├── individual_masks
# │ ├── sub-01_mask.nii.gz
# │ ├── sub-02_mask.nii.gz
# │ ├── sub-03_mask.nii.gz
# │ └── ...
# └── ...
#
# Corresponding ``cohort_FA.csv`` for scalar FA:
#
# .. list-table::
# :header-rows: 1
# :widths: auto
#
# * - **scalar_name** *(required)*
# - **source_file** *(required)*
# - **source_mask_file** *(required)*
# - subject_id
# - age
# - sex
# * - FA
# - FA/sub-01_FA.nii.gz
# - individual_masks/sub-01_mask.nii.gz
# - sub-01
# - 10
# - F
# * - FA
# - FA/sub-02_FA.nii.gz
# - individual_masks/sub-02_mask.nii.gz
# - sub-02
# - 20
# - M
# * - FA
# - FA/sub-03_FA.nii.gz
# - individual_masks/sub-03_mask.nii.gz
# - sub-03
# - 15
# - F
# * - ...
# - ...
# - ...
# - ...
# - ...
# - ...
#
# Notes:
#
# * Column order does not matter.
# * Values are case-sensitive — folder names, file names, and scalar names must match exactly
# between the CSV and disk.

# %%
# Convert NIfTI files to HDF5
# ----------------------------
#
# Using the FA dataset from the example above:
#
# .. code-block:: console
#
# # activate your conda environment first
# conda activate <env_name>
#
# convoxel \
# --group-mask-file /home/username/myProject/data/group_mask.nii.gz \
# --cohort-file /home/username/myProject/data/cohort_FA.csv \
# --output-hdf5 /home/username/myProject/data/FA.h5
#
# This produces ``FA.h5`` in ``/home/username/myProject/data``. You can then use
# `ModelArray <https://pennlinc.github.io/ModelArray/>`_ to run statistical analyses on it.

# %%
# Convert result .h5 back to NIfTI
# ---------------------------------
#
# After running ModelArray and obtaining statistical results inside ``FA.h5`` (suppose the
# analysis name is ``"mylm"``), use ``volumestats_write`` to export them as NIfTI files.
#
# .. code-block:: console
#
# volumestats_write \
# --group-mask-file /home/username/myProject/data/group_mask.nii.gz \
# --cohort-file /home/username/myProject/data/cohort_FA.csv \
# --analysis-name mylm \
# --input-hdf5 /home/username/myProject/data/FA.h5 \
# --output-dir /home/username/myProject/data/FA_stats \
# --output-ext .nii.gz
#
# All converted volume data are saved as ``float32``. Results in ``FA_stats`` can be viewed
# with any NIfTI image viewer.
#
# .. warning::
#
# If ``--output-dir`` already exists, ``volumestats_write`` will not delete it — you will
# see ``WARNING: Output directory exists``. Existing files that are **not** part of the
# current output list are left unchanged. Existing files that **are** part of the current
# output list will be overwritten (unlike the fixel ``fixelstats_write``, which does not
# overwrite via ``mrconvert``). To avoid confusion, consider manually deleting the output
# directory before re-running ``volumestats_write``.

# %%
# Number-of-observations image
# -----------------------------
#
# If you requested ``nobs`` during model fitting in ModelArray, after conversion you will find
# an image called ``*_model.nobs.nii*``. With subject-specific masks, this image may be
# inhomogeneous across voxels.
#
# Voxels that did not have sufficient subjects (due to subject-specific masking) are stored as
# ``NaN`` in the HDF5 file. How different viewers display these voxels:
#
# .. list-table::
# :header-rows: 1
# :widths: auto
#
# * - Viewer
# - Regular voxel
# - Voxel without sufficient subjects
# * - nibabel (Python)
# - e.g. ``nobs: 209.0``, ``p.value: 0.01``
# - ``NaN``
# * - MRtrix mrview
# - e.g. ``nobs: 209``, ``p.value: 0.01``
# - ``?``
# * - ITK-SNAP
# - e.g. ``nobs: 209``, ``p.value: 0.01``
# - ``0`` (displayed, but excluded when thresholding)

# %%
# Additional help
# ---------------
#
# Full argument documentation is available from the command line:
#
# .. code-block:: console
#
# convoxel --help
# volumestats_write --help
#
# or in the :doc:`/usage` page of this documentation.
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
.. toctree::
:maxdepth: 2

auto_examples/index
usage
api
Loading