Skip to content

Commit 563376d

Browse files
authored
Merge pull request #59 from Deep-MI/dev
Introducing additional processing options
2 parents 34e06da + 9d126fa commit 563376d

26 files changed

+1933
-1258
lines changed

.github/workflows/build.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,19 @@ jobs:
1515
fail-fast: false
1616
matrix:
1717
os: [ubuntu, macos, windows]
18-
python-version: [3.8, 3.9, "3.10", "3.11"]
18+
python-version: ["3.9", "3.10", "3.11", "3.12"]
1919
name: ${{ matrix.os }} - py${{ matrix.python-version }}
2020
runs-on: ${{ matrix.os }}-latest
2121
defaults:
2222
run:
2323
shell: bash
2424
steps:
2525
- name: Checkout repository
26-
uses: actions/checkout@v3
26+
uses: actions/checkout@v4
2727
- name: Setup Python ${{ matrix.python-version }}
28-
uses: actions/setup-python@v4
28+
uses: actions/setup-python@v5
2929
with:
3030
python-version: ${{ matrix.python-version }}
31-
#architecture: 'x64'
3231
- name: Install dependencies
3332
run: |
3433
python -m pip install --progress-bar off --upgrade pip setuptools wheel

.github/workflows/code-style.yml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,18 @@ jobs:
1414
runs-on: ubuntu-latest
1515
steps:
1616
- name: Checkout repository
17-
uses: actions/checkout@v3
18-
- name: Setup Python 3.9
19-
uses: actions/setup-python@v4
17+
uses: actions/checkout@v4
18+
- name: Setup Python 3.10
19+
uses: actions/setup-python@v5
2020
with:
21-
python-version: '3.9'
21+
python-version: '3.10'
2222
architecture: 'x64'
2323
- name: Install dependencies
2424
run: |
2525
python -m pip install --progress-bar off --upgrade pip setuptools wheel
2626
python -m pip install --progress-bar off .[style]
2727
- name: Run Ruff
2828
run: ruff check .
29-
- name: Run isort
30-
uses: isort/isort-action@master
31-
- name: Run black
32-
uses: psf/black@stable
33-
with:
34-
options: "--check --verbose"
35-
version: "23.10.1"
3629
- name: Run codespell
3730
uses: codespell-project/actions-codespell@master
3831
with:

.github/workflows/doc.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ jobs:
2020
uses: actions/checkout@v4
2121
with:
2222
path: ./main
23-
- name: Setup Python 3.9
24-
uses: actions/setup-python@v4
23+
- name: Setup Python 3.10
24+
uses: actions/setup-python@v5
2525
with:
26-
python-version: 3.9
26+
python-version: '3.10'
2727
architecture: 'x64'
2828
- name: Install package
2929
run: |
@@ -56,7 +56,7 @@ jobs:
5656
name: doc-dev
5757
path: ./doc-dev
5858
- name: Deploy dev documentation
59-
uses: peaceiris/actions-gh-pages@v3
59+
uses: peaceiris/actions-gh-pages@v4
6060
with:
6161
github_token: ${{ secrets.GITHUB_TOKEN }}
6262
publish_dir: ./doc-dev

.github/workflows/publish.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ jobs:
1010
runs-on: ubuntu-latest
1111
steps:
1212
- name: Checkout repository
13-
uses: actions/checkout@v3
14-
- name: Setup Python 3.9
15-
uses: actions/setup-python@v4
13+
uses: actions/checkout@v4
14+
- name: Setup Python 3.10
15+
uses: actions/setup-python@v5
1616
with:
17-
python-version: '3.9'
17+
python-version: '3.10'
1818
architecture: 'x64'
1919
- name: Install dependencies
2020
run: |

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
This is a document summarizing the changes that are associated with (major) updates and releases. Priority is given to changes that are relevant to the user, and those that introduce new features or break compatibility with prior versions.
55

6+
## Version 2.1.0
7+
8+
- Added group-only, no-group options to allow for running the scripts at the individual or group level only. Default is to run at both levels.
9+
- Added status file and skip-existing option to allow for incremental updates of a given output directory; additional cases or additional modules will be added. Existing ones will not be recomputed.
10+
611
## Version 2.0.2
712

813
- This fixes an issue with the outlier module, which did not run for FastSurfer output due to incorrect expectations for names of stats files.

DESCRIPTION.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ run_fsqc --subjects_dir <directory> --output_dir <directory>
150150
[--fornix] [--fornix-html] [--hippocampus]
151151
[--hippocampus-html] [--hippocampus-label ... ]
152152
[--hypothalamus] [--hypothalamus-html] [--shape]
153-
[--outlier] [--fastsurfer] [-h] [--more-help]
153+
[--outlier] [--fastsurfer] [--exit-on-error]
154+
[--skip-existing] [-h] [--more-help]
154155
[...]
155156
156157
@@ -194,6 +195,9 @@ optional arguments:
194195
--exit-on-error terminate the program when encountering an error;
195196
otherwise, try to continue with the next module or
196197
case
198+
--skip-existing skips processing for a given case if output
199+
already exists, even with possibly different
200+
parameters or settings.
197201
198202
getting help:
199203
-h, --help display this help message and exit

README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,9 @@ run_fsqc --subjects_dir <directory> --output_dir <directory>
222222
[--fornix] [--fornix-html] [--hippocampus]
223223
[--hippocampus-html] [--hippocampus-label ... ]
224224
[--hypothalamus] [--hypothalamus-html] [--shape]
225-
[--outlier] [--fastsurfer] [-h] [--more-help]
225+
[--outlier] [--fastsurfer] [--no-group]
226+
[--group-only] [--exit-on-error]
227+
[--skip-existing] [-h] [--more-help]
226228
[...]
227229
228230
@@ -263,9 +265,17 @@ optional arguments:
263265
--outlier-table specify normative values (only in conjunction with
264266
--outlier)
265267
--fastsurfer use FastSurfer instead of FreeSurfer output
268+
--no-group run script in subject-level mode. will compute
269+
individual files and statistics, but not create
270+
group-level summaries.
271+
--group-only run script in group mode. will create group-level
272+
summaries from existing inputs
266273
--exit-on-error terminate the program when encountering an error;
267274
otherwise, try to continue with the next module or
268275
case
276+
--skip-existing skips processing for a given case if output
277+
already exists, even with possibly different
278+
parameters or settings
269279
270280
getting help:
271281
-h, --help display this help message and exit
@@ -395,7 +405,7 @@ Call `help(fsqc.run_fsqc)` for further usage info and additional options.
395405

396406
### As a Docker image
397407

398-
We provide a configuration files that can be used to create a Docker or
408+
We provide configuration files that can be used to create a Docker or
399409
Singularity image for the fsqc scripts. Documentation can be found on the
400410
[Docker](docker/Docker.md) and [Singularity](singularity/Singularity.md) pages.
401411

@@ -467,7 +477,7 @@ ___
467477
all required packages will be installed automatically and manual installation
468478
as detailed above will not be necessary.
469479

470-
- This software has been tested on Ubuntu 20.04.
480+
- This software has been tested on Ubuntu 20.04 and 22.04.
471481

472482
- A working [FreeSurfer](https://freesurfer.net) installation (version 6 or
473483
newer) is required for running the 'shape' module of this toolbox. Also make

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.0.2
1+
2.1.0

doc/Requirements.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Requirements
1414
```
1515
- If installing the toolbox as a Python package or if using the Docker image, all required packages will be installed automatically, and manual installation as detailed above will not be necessary.
1616

17-
- This software has been tested on Ubuntu 20.04.
17+
- This software has been tested on Ubuntu 20.04 and Ubuntu 22.04.
1818

1919
- A working `FreeSurfer <https://freesurfer.net/>`_ installation (version 6 or newer) is required for running the 'shape' module of this toolbox. Also, make sure that FreeSurfer is sourced (i.e., FREESURFER_HOME is set as an environment variable) before running an analysis.
2020

doc/Usage.rst

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,25 @@ As a Command Line Tool
66

77
.. code-block:: sh
88
9-
run_fsqc
10-
--subjects_dir <directory>
9+
run_fsqc
10+
--subjects_dir <directory>
1111
--output_dir <directory>
12-
[--subjects SubjectID]
12+
[--subjects SubjectID [SubjectID ...]]
1313
[--subjects-file <file>] [--screenshots]
1414
[--screenshots-html] [--surfaces] [--surfaces-html]
1515
[--skullstrip] [--skullstrip-html]
1616
[--fornix] [--fornix-html] [--hippocampus]
1717
[--hippocampus-html] [--hippocampus-label ... ]
1818
[--hypothalamus] [--hypothalamus-html] [--shape]
19-
[--outlier] [--fastsurfer] [-h] [--more-help]
19+
[--outlier] [--fastsurfer] [--no-group]
20+
[--group-only] [--exit-on-error]
21+
[--skip-existing] [-h] [--more-help]
2022
[...]
2123
2224
Required Arguments:
2325
-------------------
2426
--subjects_dir <directory>
25-
Subjects directory with a set of Freesurfer- or
27+
Subjects directory with a set of Freesurfer- or
2628
Fastsurfer-processed individual datasets.
2729
2830
--output_dir <directory>
@@ -88,9 +90,18 @@ As a Command Line Tool
8890
--fastsurfer
8991
Use FastSurfer instead of FreeSurfer output
9092
93+
--no-group
94+
run script in subject-level mode. will compute individual files and statistics, but not create group-level summaries.
95+
96+
--group-only
97+
run script in group mode. will create group-level summaries from existing inputs. needs to be run on output directory with already existing results.
98+
9199
--exit-on-error
92100
Terminate the program when encountering an error; otherwise, try to continue with the next module or case
93101
102+
--skip-existing
103+
skips processing for a given case if output already exists, even with possibly different parameters or settings
104+
94105
Getting Help:
95106
-------------
96107
-h, --help
@@ -102,34 +113,34 @@ As a Command Line Tool
102113
---------------
103114
--screenshots_base <image>
104115
Filename of an image that should be used instead of
105-
norm.mgz as the base image for the screenshots. Can be
106-
an individual file (which would not be appropriate for
107-
multi-subject analysis) or can be a file without
116+
norm.mgz as the base image for the screenshots. Can be
117+
an individual file (which would not be appropriate for
118+
multi-subject analysis) or can be a file without
108119
pathname and with the same filename across subjects within the 'mri'
109-
subdirectory of an individual FreeSurfer results directory
120+
subdirectory of an individual FreeSurfer results directory
110121
(which would be appropriate for multi-subject analysis).
111122
112123
--screenshots_overlay <image>
113-
Path to an image that should be used instead of aseg.mgz
114-
as the overlay image for the screenshots can also be none.
115-
Can be an individual file (which would not be appropriate
124+
Path to an image that should be used instead of aseg.mgz
125+
as the overlay image for the screenshots can also be none.
126+
Can be an individual file (which would not be appropriate
116127
for multi-subject analysis) or can be a file without pathname
117128
and with the same filename across subjects within the 'mri' subdirectory
118-
of an individual FreeSurfer results directory
129+
of an individual FreeSurfer results directory
119130
(which would be appropriate for multi-subject analysis).
120131
121132
--screenshots_surf <surf> [<surf> ...]
122-
One or more surface files that should be used instead of
133+
One or more surface files that should be used instead of
123134
[lr]h.white and [lr]h.pial; can also be none.
124-
Can be one or more individual file(s) (which would not
135+
Can be one or more individual file(s) (which would not
125136
be appropriate for multi-subject analysis) or
126-
can be a (list of) file(s) without pathname and with the same
137+
can be a (list of) file(s) without pathname and with the same
127138
filename across subjects within the 'surf'
128-
subdirectory of an individual FreeSurfer results directory
139+
subdirectory of an individual FreeSurfer results directory
129140
(which would be appropriate for multi-subject analysis).
130141
131142
--screenshots_views <view> [<view> ...]
132-
One or more views to use for the screenshots in the form of
143+
One or more views to use for the screenshots in the form of
133144
x=<numeric> y=<numeric> and/or z=<numeric>.
134145
Order does not matter. Default views are x=-10 x=10 y=0 z=0.
135146

fsqc/checkCCSize.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def checkCCSize(subjects_dir, subject):
7070
relative_cc = sum_cc / intracranial_volume
7171

7272
logging.info(
73-
"Relative size of the corpus callosum is " + "{:.4}".format(relative_cc)
73+
"Relative size of the corpus callosum is " + f"{relative_cc:.4}"
7474
)
7575

7676
# Return

fsqc/checkContrast.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,23 @@ def checkContrast(subjects_dir, subject):
4949
# Check if files exist
5050
path_pct_lh = os.path.join(subjects_dir, subject, "surf", "lh.w-g.pct.mgh")
5151
if not os.path.exists(path_pct_lh):
52-
warnings.warn("WARNING: could not find " + path_pct_lh + ", returning NaNs")
52+
warnings.warn("WARNING: could not find " + path_pct_lh + ", returning NaNs",
53+
stacklevel = 2)
5354
return numpy.nan
5455

5556
path_pct_rh = os.path.join(subjects_dir, subject, "surf", "rh.w-g.pct.mgh")
5657
if not os.path.exists(path_pct_rh):
57-
warnings.warn("WARNING: could not find " + path_pct_rh + ", returning NaNs")
58+
warnings.warn("WARNING: could not find " + path_pct_rh + ", returning NaNs",
59+
stacklevel = 2)
5860
return numpy.nan
5961

6062
path_label_cortex_lh = os.path.join(
6163
subjects_dir, subject, "label", "lh.cortex.label"
6264
)
6365
if not os.path.exists(path_label_cortex_lh):
6466
warnings.warn(
65-
"WARNING: could not find " + path_label_cortex_lh + ", returning NaNs"
67+
"WARNING: could not find " + path_label_cortex_lh + ", returning NaNs",
68+
stacklevel = 2
6669
)
6770
return numpy.nan
6871

@@ -71,7 +74,8 @@ def checkContrast(subjects_dir, subject):
7174
)
7275
if not os.path.exists(path_label_cortex_rh):
7376
warnings.warn(
74-
"WARNING: could not find " + path_label_cortex_rh + ", returning NaNs"
77+
"WARNING: could not find " + path_label_cortex_rh + ", returning NaNs",
78+
stacklevel = 2
7579
)
7680
return numpy.nan
7781

@@ -91,14 +95,14 @@ def checkContrast(subjects_dir, subject):
9195
con_lh_std = numpy.std(con_lh)
9296
con_lh_snr = con_lh_mean / con_lh_std
9397
logging.info(
94-
"WM/GM contrast SNR for the left hemisphere: " + "{:.4}".format(con_lh_snr)
98+
"WM/GM contrast SNR for the left hemisphere: " + f"{con_lh_snr:.4}"
9599
)
96100

97101
con_rh_mean = numpy.mean(con_rh)
98102
con_rh_std = numpy.std(con_rh)
99103
con_rh_snr = con_rh_mean / con_rh_std
100104
logging.info(
101-
"WM/GM contrast SNR for the right hemisphere: " + "{:.4}".format(con_rh_snr)
105+
"WM/GM contrast SNR for the right hemisphere: " + f"{con_rh_snr:.4}"
102106
)
103107

104108
# Return

fsqc/checkRotation.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ def checkRotation(subjects_dir, subject):
5050

5151
if importlib.util.find_spec("transforms3d") is None:
5252
warnings.warn(
53-
"WARNING: 'transforms3d' package required for running this script, returning NaNs."
53+
"WARNING: 'transforms3d' package required for running this script, returning NaNs.",
54+
stacklevel = 2
5455
)
5556
return np.nan, np.nan, np.nan
5657
else:
@@ -64,12 +65,13 @@ def checkRotation(subjects_dir, subject):
6465
warnings.warn(
6566
"WARNING: could not open "
6667
+ os.path.join(subjects_dir, subject, "mri", "transforms", "talairach.lta")
67-
+ ", returning NaNs."
68+
+ ", returning NaNs.",
69+
stacklevel = 2
6870
)
6971
return np.nan, np.nan, np.nan
7072

7173
with open(
72-
os.path.join(subjects_dir, subject, "mri", "transforms", "talairach.lta"), "r"
74+
os.path.join(subjects_dir, subject, "mri", "transforms", "talairach.lta")
7375
) as datafile:
7476
lines = datafile.readlines()
7577

@@ -102,11 +104,11 @@ def checkRotation(subjects_dir, subject):
102104

103105
logging.info(
104106
"Found Talairach rotation angles: x = "
105-
+ "{:.3}".format(rot_x)
107+
+ f"{rot_x:.3}"
106108
+ ", y = "
107-
+ "{:.3}".format(rot_y)
109+
+ f"{rot_y:.3}"
108110
+ ", z = "
109-
+ "{:.3}".format(rot_z)
111+
+ f"{rot_z:.3}"
110112
+ " radians.",
111113
)
112114

0 commit comments

Comments
 (0)