|
| 1 | +""" |
| 2 | +Voxel-wise Data Conversion |
| 3 | +========================== |
| 4 | +
|
| 5 | +For voxel-wise data, use the **``convoxel``** command from **ModelArrayIO** to convert NIfTI |
| 6 | +files to the HDF5 format (``.h5``) used by ModelArray, and ``volumestats_write`` to export |
| 7 | +results back to NIfTI. The voxel workflow is very similar to the fixel workflow |
| 8 | +(:ref:`sphx_glr_auto_examples_plot_fixel_workflow.py`). |
| 9 | +""" |
| 10 | + |
| 11 | +# %% |
| 12 | +# Prepare data |
| 13 | +# ------------ |
| 14 | +# |
| 15 | +# To convert a list of voxel-wise NIfTI files to ``.h5`` format, you need: |
| 16 | +# |
| 17 | +# 1. **A cohort CSV** describing every NIfTI file to include (one CSV per scalar recommended). |
| 18 | +# 2. **A group mask** — only voxels inside the group mask are kept during conversion. |
| 19 | +# 3. **Subject-specific masks** *(optional)* — voxels outside each subject's mask are set to |
| 20 | +# ``NaN`` after conversion. If you do not have per-subject masks, supply the group mask for |
| 21 | +# every subject (see the CSV example below). |
| 22 | +# |
| 23 | +# Cohort CSV columns (names are fixed, not user-defined): |
| 24 | +# |
| 25 | +# * ``scalar_name`` — which metric is being analysed (e.g. ``FA``) |
| 26 | +# * ``source_file`` — path to the subject's NIfTI file |
| 27 | +# * ``source_mask_file`` — path to the subject-specific mask (or the group mask if none exists) |
| 28 | + |
| 29 | +# %% |
| 30 | +# Example folder structure |
| 31 | +# ------------------------ |
| 32 | +# |
| 33 | +# .. code-block:: text |
| 34 | +# |
| 35 | +# /home/username/myProject/data |
| 36 | +# | |
| 37 | +# ├── cohort_FA.csv |
| 38 | +# ├── group_mask.nii.gz |
| 39 | +# │ |
| 40 | +# ├── FA |
| 41 | +# │ ├── sub-01_FA.nii.gz |
| 42 | +# │ ├── sub-02_FA.nii.gz |
| 43 | +# │ ├── sub-03_FA.nii.gz |
| 44 | +# │ └── ... |
| 45 | +# │ |
| 46 | +# ├── individual_masks |
| 47 | +# │ ├── sub-01_mask.nii.gz |
| 48 | +# │ ├── sub-02_mask.nii.gz |
| 49 | +# │ ├── sub-03_mask.nii.gz |
| 50 | +# │ └── ... |
| 51 | +# └── ... |
| 52 | +# |
| 53 | +# Corresponding ``cohort_FA.csv`` for scalar FA: |
| 54 | +# |
| 55 | +# .. list-table:: |
| 56 | +# :header-rows: 1 |
| 57 | +# :widths: auto |
| 58 | +# |
| 59 | +# * - **scalar_name** *(required)* |
| 60 | +# - **source_file** *(required)* |
| 61 | +# - **source_mask_file** *(required)* |
| 62 | +# - subject_id |
| 63 | +# - age |
| 64 | +# - sex |
| 65 | +# * - FA |
| 66 | +# - FA/sub-01_FA.nii.gz |
| 67 | +# - individual_masks/sub-01_mask.nii.gz |
| 68 | +# - sub-01 |
| 69 | +# - 10 |
| 70 | +# - F |
| 71 | +# * - FA |
| 72 | +# - FA/sub-02_FA.nii.gz |
| 73 | +# - individual_masks/sub-02_mask.nii.gz |
| 74 | +# - sub-02 |
| 75 | +# - 20 |
| 76 | +# - M |
| 77 | +# * - FA |
| 78 | +# - FA/sub-03_FA.nii.gz |
| 79 | +# - individual_masks/sub-03_mask.nii.gz |
| 80 | +# - sub-03 |
| 81 | +# - 15 |
| 82 | +# - F |
| 83 | +# * - ... |
| 84 | +# - ... |
| 85 | +# - ... |
| 86 | +# - ... |
| 87 | +# - ... |
| 88 | +# - ... |
| 89 | +# |
| 90 | +# Notes: |
| 91 | +# |
| 92 | +# * Column order does not matter. |
| 93 | +# * Values are case-sensitive — folder names, file names, and scalar names must match exactly |
| 94 | +# between the CSV and disk. |
| 95 | + |
| 96 | +# %% |
| 97 | +# Convert NIfTI files to HDF5 |
| 98 | +# ---------------------------- |
| 99 | +# |
| 100 | +# Using the FA dataset from the example above: |
| 101 | +# |
| 102 | +# .. code-block:: console |
| 103 | +# |
| 104 | +# # activate your conda environment first |
| 105 | +# conda activate <env_name> |
| 106 | +# |
| 107 | +# convoxel \ |
| 108 | +# --group-mask-file /home/username/myProject/data/group_mask.nii.gz \ |
| 109 | +# --cohort-file /home/username/myProject/data/cohort_FA.csv \ |
| 110 | +# --output-hdf5 /home/username/myProject/data/FA.h5 |
| 111 | +# |
| 112 | +# This produces ``FA.h5`` in ``/home/username/myProject/data``. You can then use |
| 113 | +# `ModelArray <https://pennlinc.github.io/ModelArray/>`_ to run statistical analyses on it. |
| 114 | + |
| 115 | +# %% |
| 116 | +# Convert result .h5 back to NIfTI |
| 117 | +# --------------------------------- |
| 118 | +# |
| 119 | +# After running ModelArray and obtaining statistical results inside ``FA.h5`` (suppose the |
| 120 | +# analysis name is ``"mylm"``), use ``volumestats_write`` to export them as NIfTI files. |
| 121 | +# |
| 122 | +# .. code-block:: console |
| 123 | +# |
| 124 | +# volumestats_write \ |
| 125 | +# --group-mask-file /home/username/myProject/data/group_mask.nii.gz \ |
| 126 | +# --cohort-file /home/username/myProject/data/cohort_FA.csv \ |
| 127 | +# --analysis-name mylm \ |
| 128 | +# --input-hdf5 /home/username/myProject/data/FA.h5 \ |
| 129 | +# --output-dir /home/username/myProject/data/FA_stats \ |
| 130 | +# --output-ext .nii.gz |
| 131 | +# |
| 132 | +# All converted volume data are saved as ``float32``. Results in ``FA_stats`` can be viewed |
| 133 | +# with any NIfTI image viewer. |
| 134 | +# |
| 135 | +# .. warning:: |
| 136 | +# |
| 137 | +# If ``--output-dir`` already exists, ``volumestats_write`` will not delete it — you will |
| 138 | +# see ``WARNING: Output directory exists``. Existing files that are **not** part of the |
| 139 | +# current output list are left unchanged. Existing files that **are** part of the current |
| 140 | +# output list will be overwritten (unlike the fixel ``fixelstats_write``, which does not |
| 141 | +# overwrite via ``mrconvert``). To avoid confusion, consider manually deleting the output |
| 142 | +# directory before re-running ``volumestats_write``. |
| 143 | + |
| 144 | +# %% |
| 145 | +# Number-of-observations image |
| 146 | +# ----------------------------- |
| 147 | +# |
| 148 | +# If you requested ``nobs`` during model fitting in ModelArray, after conversion you will find |
| 149 | +# an image called ``*_model.nobs.nii*``. With subject-specific masks, this image may be |
| 150 | +# inhomogeneous across voxels. |
| 151 | +# |
| 152 | +# Voxels that did not have sufficient subjects (due to subject-specific masking) are stored as |
| 153 | +# ``NaN`` in the HDF5 file. How different viewers display these voxels: |
| 154 | +# |
| 155 | +# .. list-table:: |
| 156 | +# :header-rows: 1 |
| 157 | +# :widths: auto |
| 158 | +# |
| 159 | +# * - Viewer |
| 160 | +# - Regular voxel |
| 161 | +# - Voxel without sufficient subjects |
| 162 | +# * - nibabel (Python) |
| 163 | +# - e.g. ``nobs: 209.0``, ``p.value: 0.01`` |
| 164 | +# - ``NaN`` |
| 165 | +# * - MRtrix mrview |
| 166 | +# - e.g. ``nobs: 209``, ``p.value: 0.01`` |
| 167 | +# - ``?`` |
| 168 | +# * - ITK-SNAP |
| 169 | +# - e.g. ``nobs: 209``, ``p.value: 0.01`` |
| 170 | +# - ``0`` (displayed, but excluded when thresholding) |
| 171 | + |
| 172 | +# %% |
| 173 | +# Additional help |
| 174 | +# --------------- |
| 175 | +# |
| 176 | +# Full argument documentation is available from the command line: |
| 177 | +# |
| 178 | +# .. code-block:: console |
| 179 | +# |
| 180 | +# convoxel --help |
| 181 | +# volumestats_write --help |
| 182 | +# |
| 183 | +# or in the :doc:`/usage` page of this documentation. |
0 commit comments