Cross-platform program that calculates head circumference from MRI data (.nii
, .nii.gz
, .nrrd
).
The demo is slightly outdated, but most information is relevant.
If you want 😉 format is bibtex.
@misc{neuroruler,
title={NeuroRuler},
author={Wei, Jesse and Lester, Madison and He, Peifeng and Schneider, Eric and Styner, Martin},
howpublished={\url{https://github.com/NIRALUser/NeuroRuler}},
year={2023}
}
Your Python version needs to be 3.8+. Check with python --version
. Install with pip.
pip install NeuroRuler
If python
or pip
don't work, try python3
and pip3
.
On Linux, please make sure that you have xcb, xcb-util, and xcb-util-cursor packages installed on your system. NeuroRuler further needs a QT6 installation (either user or system).
Download the latest release.
The gui.py and cli.py scripts are entry points for NeuroRuler's GUI and CLI.
gui_config.json and cli_config.json set default settings for the GUI and CLI. For more information, see Configure default settings.
Developers contributing to the repository should clone the repository. gui.py
and cli.py
will then import from the local repository and reflect changes made to the codebase.
Developers should also run pip install -r requirements.txt
to install additional development dependencies and pre-commit install
to install pre-commit git hooks.
Note: Cloning (but not installing via pip) will use ~2G because of the large data files in data/ used in our unit tests.
To improve this, please see issue #93.
python gui.py
Run python gui.py -h
to see command-line options.
The GUI can also be run from any directory from a Python terminal. After opening a Python terminal, run these commands:
from NeuroRuler.GUI import gui
gui()
Same as the code in gui.py
python cli.py <file>
See test_cli.py for example usages. Note that the CLI script accepts only one file at a time because it's expected that you'll use a shell script to loop over multiple files.
usage: cli.py [-h] [-d] [-r] [-x X] [-y Y] [-z Z] [-s SLICE] [-c CONDUCTANCE] [-i ITERATIONS] [-t STEP] [-f FILTER] [-l LOWER]
[-u UPPER]
file
A program that calculates head circumference from MRI data (``.nii``, ``.nii.gz``, ``.nrrd``).
positional arguments:
file file to compute circumference from, file format must be *.nii.gz, *.nii, or *.nrrd
options:
-h, --help show this help message and exit
-d, --debug print debug info
-r, --raw print just the "raw" circumference
-x X, --x X x rotation (in degrees)
-y Y, --y Y y rotation (in degrees)
-z Z, --z Z z rotation (in degrees)
-s SLICE, --slice SLICE
slice (Z slice, 0-indexed)
-c CONDUCTANCE, --conductance CONDUCTANCE
conductance smoothing parameter
-i ITERATIONS, --iterations ITERATIONS
smoothing iterations
-t STEP, --step STEP time step (smoothing parameter)
-f FILTER, --filter FILTER
which filter to use (Otsu or binary), default is Otsu
-l LOWER, --lower LOWER
lower threshold for binary threshold
-u UPPER, --upper UPPER
upper threshold for binary threshold
Output of python cli.py -h
(could be outdated)
In the GUI's "circumference mode" (after clicking Apply), click the large Export button under the image to export image settings JSON file(s) containing the circumferences of all loaded images and the settings applied to each image.
You can then use File > Import Image Settings to import an image settings JSON to load the same image with the same settings.
Here is an example:
{
"input_image_path": "/Users/jesse/Documents/GitHub/COMP523/NeuroRuler/data/MicroBiome_1month_T1w.nii.gz",
"output_contoured_slice_path": "/Users/jesse/Documents/GitHub/COMP523/NeuroRuler/output/MicroBiome_1month_T1w/MicroBiome_1month_T1w_contoured.png",
"circumference": 285.04478394448125,
"x_rotation": -17,
"y_rotation": -18,
"z_rotation": 24,
"slice": 131,
"smoothing_conductance": 4.0,
"smoothing_iterations": 10,
"smoothing_time_step": 0.08,
"threshold_filter": "Otsu"
}
When multiple images are exported, the output directory structure looks like this:
output
├── 150649_V06_t1w
│ ├── 150649_V06_t1w_contoured.png
│ └── 150649_V06_t1w_settings.json
└── MicroBiome_1month_T1w
├── MicroBiome_1month_T1w_contoured.png
└── MicroBiome_1month_T1w_settings.json
Edit the JSON configuration files gui_config.json and cli_config.json. gui.py
and cli.py
will create these files if they don't exist.
Command-line arguments supplied to the gui.py or cli.py scripts override settings in the JSON configuration files. JSON settings are default values for the GUI and CLI: If a setting in the JSON file is not overriden by a CLI argument, the JSON file setting will be used.
To test locally, run pytest
.
Our algorithm tests assert that our GUI calculations have at least a 0.98 R2 value with ground truth data from the old Head Circumference Tool (the .tsv
files in data/
). In all unit tests, we calculate circumference from the middle axial slice with all rotation values set to 0. Also, we use the default smoothing parameters and Otsu threshold.
We use a similar R2 test to verify that our circumference result is correct for images with non-(1.0, 1.0, 1.0) pixel spacing. We verified manually (no unit test) that the GUI computes similar circumferences for (a, b, c) pixel spacing images generated from (1.0, 1.0, 1.0) pixel spacing images.
To test CLI, we test that our CLI produces the same results as the GUI.
Our tests run on GitHub Actions on push and PR via tox
(tests.yml). If the image below says "passing," then the tests are passing.
https://NeuroRuler.readthedocs.io
To contribute, see docs/. Build/setup instructions here. Note that it is possible to write site content in Markdown and inline RST in the Markdown file when needed - I just didn't find out until after this project was completed.
To test the package locally before releasing on PyPI, use the testdist script. If using macOS, run with . ./testdist
. If using Windows, you may need to modify the script slightly.
You should test from a directory that isn't NeuroRuler/
. If your directory is NeuroRuler/
, then imports will import from the source code, not the package.
To publish to PyPI, edit the version number in setup.py. Then push to a branch called release-pypi
(create it if it doesn't exist). This will trigger pypi.yml, which will run tests and publish to PyPI if the tests pass.
To publish to Test PyPI, do the same as above, but push to a branch called release-testpypi
.
If any of these files changes, they should be re-released on our GitHub release page: gui.py
, cli.py
, gui_config.json
, cli_config.json
.
Additionally, these files should be updated: CITATION.cff