rapidtide 3.0.11__py3-none-any.whl → 3.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rapidtide/Colortables.py +492 -27
- rapidtide/OrthoImageItem.py +1049 -46
- rapidtide/RapidtideDataset.py +1533 -86
- rapidtide/_version.py +3 -3
- rapidtide/calccoherence.py +196 -29
- rapidtide/calcnullsimfunc.py +188 -40
- rapidtide/calcsimfunc.py +242 -42
- rapidtide/correlate.py +1203 -383
- rapidtide/data/examples/src/testLD +56 -0
- rapidtide/data/examples/src/testalign +1 -1
- rapidtide/data/examples/src/testdelayvar +0 -1
- rapidtide/data/examples/src/testfmri +53 -3
- rapidtide/data/examples/src/testglmfilt +5 -5
- rapidtide/data/examples/src/testhappy +29 -7
- rapidtide/data/examples/src/testppgproc +17 -0
- rapidtide/data/examples/src/testrolloff +11 -0
- rapidtide/data/models/model_cnn_pytorch/best_model.pth +0 -0
- rapidtide/data/models/model_cnn_pytorch/loss.png +0 -0
- rapidtide/data/models/model_cnn_pytorch/loss.txt +1 -0
- rapidtide/data/models/model_cnn_pytorch/model.pth +0 -0
- rapidtide/data/models/model_cnn_pytorch/model_meta.json +68 -0
- rapidtide/decorators.py +91 -0
- rapidtide/dlfilter.py +2226 -110
- rapidtide/dlfiltertorch.py +4842 -0
- rapidtide/externaltools.py +327 -12
- rapidtide/fMRIData_class.py +79 -40
- rapidtide/filter.py +1899 -810
- rapidtide/fit.py +2011 -581
- rapidtide/genericmultiproc.py +93 -18
- rapidtide/happy_supportfuncs.py +2047 -172
- rapidtide/helper_classes.py +584 -43
- rapidtide/io.py +2370 -372
- rapidtide/linfitfiltpass.py +346 -99
- rapidtide/makelaggedtcs.py +210 -24
- rapidtide/maskutil.py +448 -62
- rapidtide/miscmath.py +827 -121
- rapidtide/multiproc.py +210 -22
- rapidtide/patchmatch.py +242 -42
- rapidtide/peakeval.py +31 -31
- rapidtide/ppgproc.py +2203 -0
- rapidtide/qualitycheck.py +352 -39
- rapidtide/refinedelay.py +431 -57
- rapidtide/refineregressor.py +494 -189
- rapidtide/resample.py +671 -185
- rapidtide/scripts/applyppgproc.py +28 -0
- rapidtide/scripts/showxcorr_legacy.py +7 -7
- rapidtide/scripts/stupidramtricks.py +15 -17
- rapidtide/simFuncClasses.py +1052 -77
- rapidtide/simfuncfit.py +269 -69
- rapidtide/stats.py +540 -238
- rapidtide/tests/happycomp +9 -0
- rapidtide/tests/test_cleanregressor.py +1 -2
- rapidtide/tests/test_dlfiltertorch.py +627 -0
- rapidtide/tests/test_findmaxlag.py +24 -8
- rapidtide/tests/test_fullrunhappy_v1.py +0 -2
- rapidtide/tests/test_fullrunhappy_v2.py +0 -2
- rapidtide/tests/test_fullrunhappy_v3.py +11 -4
- rapidtide/tests/test_fullrunhappy_v4.py +10 -2
- rapidtide/tests/test_fullrunrapidtide_v7.py +1 -1
- rapidtide/tests/test_getparsers.py +11 -3
- rapidtide/tests/test_refinedelay.py +0 -1
- rapidtide/tests/test_simroundtrip.py +16 -8
- rapidtide/tests/test_stcorrelate.py +3 -1
- rapidtide/tests/utils.py +9 -8
- rapidtide/tidepoolTemplate.py +142 -38
- rapidtide/tidepoolTemplate_alt.py +165 -44
- rapidtide/tidepoolTemplate_big.py +189 -52
- rapidtide/util.py +1217 -118
- rapidtide/voxelData.py +684 -37
- rapidtide/wiener.py +136 -23
- rapidtide/wiener2.py +113 -7
- rapidtide/workflows/adjustoffset.py +105 -3
- rapidtide/workflows/aligntcs.py +85 -2
- rapidtide/workflows/applydlfilter.py +87 -10
- rapidtide/workflows/applyppgproc.py +540 -0
- rapidtide/workflows/atlasaverage.py +210 -47
- rapidtide/workflows/atlastool.py +100 -3
- rapidtide/workflows/calcSimFuncMap.py +288 -69
- rapidtide/workflows/calctexticc.py +201 -9
- rapidtide/workflows/ccorrica.py +101 -6
- rapidtide/workflows/cleanregressor.py +165 -31
- rapidtide/workflows/delayvar.py +171 -23
- rapidtide/workflows/diffrois.py +81 -3
- rapidtide/workflows/endtidalproc.py +144 -4
- rapidtide/workflows/fdica.py +195 -15
- rapidtide/workflows/filtnifti.py +70 -3
- rapidtide/workflows/filttc.py +74 -3
- rapidtide/workflows/fitSimFuncMap.py +202 -51
- rapidtide/workflows/fixtr.py +73 -3
- rapidtide/workflows/gmscalc.py +113 -3
- rapidtide/workflows/happy.py +801 -199
- rapidtide/workflows/happy2std.py +144 -12
- rapidtide/workflows/happy_parser.py +163 -23
- rapidtide/workflows/histnifti.py +118 -2
- rapidtide/workflows/histtc.py +84 -3
- rapidtide/workflows/linfitfilt.py +117 -4
- rapidtide/workflows/localflow.py +328 -28
- rapidtide/workflows/mergequality.py +79 -3
- rapidtide/workflows/niftidecomp.py +322 -18
- rapidtide/workflows/niftistats.py +174 -4
- rapidtide/workflows/pairproc.py +98 -4
- rapidtide/workflows/pairwisemergenifti.py +85 -2
- rapidtide/workflows/parser_funcs.py +1421 -40
- rapidtide/workflows/physiofreq.py +137 -11
- rapidtide/workflows/pixelcomp.py +207 -5
- rapidtide/workflows/plethquality.py +103 -21
- rapidtide/workflows/polyfitim.py +151 -11
- rapidtide/workflows/proj2flow.py +75 -2
- rapidtide/workflows/rankimage.py +111 -4
- rapidtide/workflows/rapidtide.py +368 -76
- rapidtide/workflows/rapidtide2std.py +98 -2
- rapidtide/workflows/rapidtide_parser.py +109 -9
- rapidtide/workflows/refineDelayMap.py +144 -33
- rapidtide/workflows/refineRegressor.py +675 -96
- rapidtide/workflows/regressfrommaps.py +161 -37
- rapidtide/workflows/resamplenifti.py +85 -3
- rapidtide/workflows/resampletc.py +91 -3
- rapidtide/workflows/retrolagtcs.py +99 -9
- rapidtide/workflows/retroregress.py +176 -26
- rapidtide/workflows/roisummarize.py +174 -5
- rapidtide/workflows/runqualitycheck.py +71 -3
- rapidtide/workflows/showarbcorr.py +149 -6
- rapidtide/workflows/showhist.py +86 -2
- rapidtide/workflows/showstxcorr.py +160 -3
- rapidtide/workflows/showtc.py +159 -3
- rapidtide/workflows/showxcorrx.py +190 -10
- rapidtide/workflows/showxy.py +185 -15
- rapidtide/workflows/simdata.py +264 -38
- rapidtide/workflows/spatialfit.py +77 -2
- rapidtide/workflows/spatialmi.py +250 -27
- rapidtide/workflows/spectrogram.py +305 -32
- rapidtide/workflows/synthASL.py +154 -3
- rapidtide/workflows/tcfrom2col.py +76 -2
- rapidtide/workflows/tcfrom3col.py +74 -2
- rapidtide/workflows/tidepool.py +2971 -130
- rapidtide/workflows/utils.py +19 -14
- rapidtide/workflows/utils_doc.py +293 -0
- rapidtide/workflows/variabilityizer.py +116 -3
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/METADATA +10 -8
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/RECORD +144 -128
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/entry_points.txt +1 -0
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/WHEEL +0 -0
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/licenses/LICENSE +0 -0
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/top_level.txt +0 -0
rapidtide/workflows/happy2std.py
CHANGED
|
@@ -21,11 +21,39 @@ import glob
|
|
|
21
21
|
import os
|
|
22
22
|
import subprocess
|
|
23
23
|
import sys
|
|
24
|
+
from argparse import Namespace
|
|
25
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
|
24
26
|
|
|
25
27
|
import rapidtide.externaltools as tide_extern
|
|
26
28
|
|
|
27
29
|
|
|
28
|
-
def _get_parser():
|
|
30
|
+
def _get_parser() -> Any:
|
|
31
|
+
"""
|
|
32
|
+
Create and configure an argument parser for the rapidtide2std command-line tool.
|
|
33
|
+
|
|
34
|
+
This function sets up an `argparse.ArgumentParser` with specific arguments
|
|
35
|
+
required for registering happy output maps to standard space. It defines
|
|
36
|
+
positional and optional arguments for input file roots, output directories,
|
|
37
|
+
and various transformation options.
|
|
38
|
+
|
|
39
|
+
Returns
|
|
40
|
+
-------
|
|
41
|
+
argparse.ArgumentParser
|
|
42
|
+
Configured argument parser object with defined arguments for
|
|
43
|
+
the rapidtide2std tool.
|
|
44
|
+
|
|
45
|
+
Notes
|
|
46
|
+
-----
|
|
47
|
+
The parser is configured with a program name, description, and usage string
|
|
48
|
+
specific to the rapidtide2std tool. It expects three positional arguments:
|
|
49
|
+
inputfileroot, outputdir, and featdirectory, followed by several optional
|
|
50
|
+
flags that control the registration process.
|
|
51
|
+
|
|
52
|
+
Examples
|
|
53
|
+
--------
|
|
54
|
+
>>> parser = _get_parser()
|
|
55
|
+
>>> args = parser.parse_args()
|
|
56
|
+
"""
|
|
29
57
|
# get the command line parameters
|
|
30
58
|
parser = argparse.ArgumentParser(
|
|
31
59
|
prog="rapidtide2std",
|
|
@@ -84,16 +112,74 @@ def _get_parser():
|
|
|
84
112
|
|
|
85
113
|
|
|
86
114
|
def transformmaps(
|
|
87
|
-
thepath,
|
|
88
|
-
theoutputdir,
|
|
89
|
-
subjroot,
|
|
90
|
-
reftarget,
|
|
91
|
-
xformfuncmat,
|
|
92
|
-
warpfuncfile,
|
|
93
|
-
thefmrimaps=None,
|
|
94
|
-
theanatmaps=None,
|
|
95
|
-
preponly=False,
|
|
96
|
-
):
|
|
115
|
+
thepath: Any,
|
|
116
|
+
theoutputdir: Any,
|
|
117
|
+
subjroot: Any,
|
|
118
|
+
reftarget: Any,
|
|
119
|
+
xformfuncmat: Any,
|
|
120
|
+
warpfuncfile: Any,
|
|
121
|
+
thefmrimaps: Optional[Any] = None,
|
|
122
|
+
theanatmaps: Optional[Any] = None,
|
|
123
|
+
preponly: bool = False,
|
|
124
|
+
) -> None:
|
|
125
|
+
"""
|
|
126
|
+
Apply spatial transformations to fMRI and anatomical maps from a happy dataset using FLIRT and/or
|
|
127
|
+
copy commands.
|
|
128
|
+
|
|
129
|
+
This function applies rigid-body and non-linear transformations to a set of fMRI and/or
|
|
130
|
+
anatomical maps, based on provided transformation matrices and warp fields. It supports
|
|
131
|
+
both functional and anatomical image processing pipelines.
|
|
132
|
+
|
|
133
|
+
Parameters
|
|
134
|
+
----------
|
|
135
|
+
thepath : Any
|
|
136
|
+
Path to the directory containing input fMRI maps.
|
|
137
|
+
theoutputdir : Any
|
|
138
|
+
Directory where transformed maps will be saved.
|
|
139
|
+
subjroot : Any
|
|
140
|
+
Subject identifier used to construct input and output file names.
|
|
141
|
+
reftarget : Any
|
|
142
|
+
Reference image to which maps are transformed.
|
|
143
|
+
xformfuncmat : Any
|
|
144
|
+
Transformation matrix for functional-to-standard space alignment.
|
|
145
|
+
warpfuncfile : Any
|
|
146
|
+
Warp field file for non-linear functional-to-standard space transformation.
|
|
147
|
+
thefmrimaps : Optional[Any], default=None
|
|
148
|
+
List of fMRI map names to transform. If None, no fMRI maps are processed.
|
|
149
|
+
theanatmaps : Optional[Any], default=None
|
|
150
|
+
List of anatomical map names to transform. If None, no anatomical maps are processed.
|
|
151
|
+
preponly : bool, default=False
|
|
152
|
+
If True, only print the commands without executing them.
|
|
153
|
+
|
|
154
|
+
Returns
|
|
155
|
+
-------
|
|
156
|
+
None
|
|
157
|
+
This function does not return any value; it performs file I/O operations.
|
|
158
|
+
|
|
159
|
+
Notes
|
|
160
|
+
-----
|
|
161
|
+
- For fMRI maps, the function uses `tide_extern.makeflirtcmd` to generate and execute
|
|
162
|
+
FLIRT commands for transformation.
|
|
163
|
+
- For anatomical maps, it either copies the file or applies a transformation using
|
|
164
|
+
`tide_extern.makeflirtcmd`, depending on the `aligntohires` flag.
|
|
165
|
+
- If `preponly` is True, the commands are printed but not executed.
|
|
166
|
+
- The function assumes that input files exist and are named according to the
|
|
167
|
+
pattern: ``{subjroot}_{mapname}.nii.gz``.
|
|
168
|
+
|
|
169
|
+
Examples
|
|
170
|
+
--------
|
|
171
|
+
>>> transformmaps(
|
|
172
|
+
... thepath="/data/subj1",
|
|
173
|
+
... theoutputdir="/data/subj1/transformed",
|
|
174
|
+
... subjroot="subj1",
|
|
175
|
+
... reftarget="/data/templates/MNI152_T1_2mm.nii.gz",
|
|
176
|
+
... xformfuncmat="/data/subj1/reg/func2standard.mat",
|
|
177
|
+
... warpfuncfile="/data/subj1/reg/warpfield.nii.gz",
|
|
178
|
+
... thefmrimaps=["bold", "mask"],
|
|
179
|
+
... theanatmaps=["brain"],
|
|
180
|
+
... preponly=False
|
|
181
|
+
... )
|
|
182
|
+
"""
|
|
97
183
|
print("entering transformmaps with:")
|
|
98
184
|
print(thepath)
|
|
99
185
|
print(subjroot)
|
|
@@ -151,7 +237,53 @@ def transformmaps(
|
|
|
151
237
|
print("no hires anatomic found - skipping")
|
|
152
238
|
|
|
153
239
|
|
|
154
|
-
def happy2std(args):
|
|
240
|
+
def happy2std(args: Any) -> None:
|
|
241
|
+
"""
|
|
242
|
+
Apply FSL-based spatial transformation to fMRI data and anatomical maps.
|
|
243
|
+
|
|
244
|
+
This function performs spatial normalization of fMRI data to either high-resolution
|
|
245
|
+
or standard MNI152 space, using FSL transformation matrices and warp fields. It supports
|
|
246
|
+
both linear and nonlinear transformations, and can process either a single file or
|
|
247
|
+
a set of files based on input arguments.
|
|
248
|
+
|
|
249
|
+
Parameters
|
|
250
|
+
----------
|
|
251
|
+
args : Any
|
|
252
|
+
An object containing command-line arguments. Expected attributes include:
|
|
253
|
+
- featdirectory : str
|
|
254
|
+
Path to the FEAT directory containing registration files.
|
|
255
|
+
- aligntohires : bool
|
|
256
|
+
If True, align to high-resolution anatomical space; otherwise to standard MNI152.
|
|
257
|
+
- forcelinear : bool
|
|
258
|
+
If True, forces use of a linear transformation even if warp files are present.
|
|
259
|
+
- onefilename : str or None
|
|
260
|
+
If provided, process only this single file.
|
|
261
|
+
- preponly : bool
|
|
262
|
+
If True, print the FSL command without executing it.
|
|
263
|
+
- inputfileroot : str
|
|
264
|
+
Root path to input files for batch processing.
|
|
265
|
+
- outputdir : str
|
|
266
|
+
Output directory for transformed files.
|
|
267
|
+
- all : bool
|
|
268
|
+
If True, include additional fMRI maps in processing.
|
|
269
|
+
|
|
270
|
+
Returns
|
|
271
|
+
-------
|
|
272
|
+
None
|
|
273
|
+
This function does not return a value but may exit the program on error.
|
|
274
|
+
|
|
275
|
+
Notes
|
|
276
|
+
-----
|
|
277
|
+
This function requires the FSL environment variable ``FSLDIR`` to be set.
|
|
278
|
+
It relies on FSL tools like `applywarp` and `flirt` for transformations.
|
|
279
|
+
The function supports processing of both single files and batches of files
|
|
280
|
+
using glob patterns.
|
|
281
|
+
|
|
282
|
+
Examples
|
|
283
|
+
--------
|
|
284
|
+
>>> args = parse_args() # Assume args is parsed from command line
|
|
285
|
+
>>> happy2std(args)
|
|
286
|
+
"""
|
|
155
287
|
# make sure the appropriate transformation matrix and targets exist
|
|
156
288
|
fsldir = os.environ.get("FSLDIR")
|
|
157
289
|
if fsldir is None:
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
#
|
|
18
18
|
#
|
|
19
19
|
import argparse
|
|
20
|
+
from typing import Any, Optional
|
|
20
21
|
|
|
21
22
|
import numpy as np
|
|
22
23
|
|
|
@@ -24,19 +25,59 @@ import rapidtide.io as tide_io
|
|
|
24
25
|
import rapidtide.multiproc as tide_multiproc
|
|
25
26
|
import rapidtide.workflows.parser_funcs as pf
|
|
26
27
|
|
|
28
|
+
try:
|
|
29
|
+
import tensorflow as tf
|
|
30
|
+
tensorflowpresent = True
|
|
31
|
+
except ImportError:
|
|
32
|
+
tensorflowpresent = False
|
|
33
|
+
|
|
27
34
|
DEFAULT_ALIASEDCORRELATIONWIDTH = 5.0
|
|
28
|
-
|
|
35
|
+
DEFAULT_PULSATILITYSIGMA = 6.0
|
|
36
|
+
DEFAULT_PULSATILITYTHRESHOLD = 0.5
|
|
37
|
+
DEFAULT_TF_DL_MODEL = "model_revised_tf2"
|
|
38
|
+
DEFAULT_PT_DL_MODEL = "model_cnn_pytorch"
|
|
29
39
|
|
|
30
40
|
|
|
31
|
-
def _get_parser():
|
|
41
|
+
def _get_parser() -> Any:
|
|
32
42
|
"""
|
|
33
|
-
|
|
43
|
+
Create and configure an argument parser for the happy command-line tool.
|
|
44
|
+
|
|
45
|
+
This function sets up an `argparse.ArgumentParser` with numerous options for
|
|
46
|
+
configuring the hypersampling by analytic phase projection (HAPPY) pipeline.
|
|
47
|
+
It includes arguments for input files, processing steps, performance tuning,
|
|
48
|
+
preprocessing, cardiac and respiration estimation, output handling, and debugging.
|
|
49
|
+
|
|
50
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
argparse.ArgumentParser
|
|
53
|
+
Configured argument parser with all supported command-line options.
|
|
54
|
+
|
|
55
|
+
Notes
|
|
56
|
+
-----
|
|
57
|
+
The parser includes multiple argument groups for different functional areas:
|
|
58
|
+
- Processing steps
|
|
59
|
+
- Performance
|
|
60
|
+
- Preprocessing
|
|
61
|
+
- Cardiac estimation tuning
|
|
62
|
+
- External cardiac waveform options
|
|
63
|
+
- External respiration waveform options
|
|
64
|
+
- Output processing
|
|
65
|
+
- Output options
|
|
66
|
+
- Phase projection tuning
|
|
67
|
+
- Miscellaneous options
|
|
68
|
+
- Debugging options
|
|
69
|
+
|
|
70
|
+
Examples
|
|
71
|
+
--------
|
|
72
|
+
>>> parser = _get_parser()
|
|
73
|
+
>>> args = parser.parse_args()
|
|
34
74
|
"""
|
|
35
75
|
parser = argparse.ArgumentParser(
|
|
36
76
|
prog="happy",
|
|
37
77
|
description="Hypersampling by Analytic Phase Projection - Yay!.",
|
|
38
78
|
allow_abbrev=False,
|
|
39
79
|
)
|
|
80
|
+
|
|
40
81
|
|
|
41
82
|
# Required arguments
|
|
42
83
|
parser.add_argument(
|
|
@@ -73,18 +114,19 @@ def _get_parser():
|
|
|
73
114
|
help="Disable deep learning cardiac waveform filter. ",
|
|
74
115
|
default=True,
|
|
75
116
|
)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
117
|
+
if tensorflowpresent:
|
|
118
|
+
processing_steps.add_argument(
|
|
119
|
+
"--usesuperdangerousworkaround",
|
|
120
|
+
dest="mpfix",
|
|
121
|
+
action="store_true",
|
|
122
|
+
help=(
|
|
123
|
+
"Some versions of tensorflow seem to have some weird conflict with MKL which"
|
|
124
|
+
"I don't seem to be able to fix. If the dl filter bombs complaining about "
|
|
125
|
+
"multiple openmp libraries, try rerunning with the secret and inadvisable "
|
|
126
|
+
"'--usesuperdangerousworkaround' flag. Good luck! "
|
|
127
|
+
),
|
|
128
|
+
default=False,
|
|
129
|
+
)
|
|
88
130
|
processing_steps.add_argument(
|
|
89
131
|
"--slicetimesareinseconds",
|
|
90
132
|
action="store_true",
|
|
@@ -101,10 +143,10 @@ def _get_parser():
|
|
|
101
143
|
dest="modelname",
|
|
102
144
|
metavar="MODELNAME",
|
|
103
145
|
help=(
|
|
104
|
-
f"Use model MODELNAME for dl filter (default is {
|
|
146
|
+
f"Use model MODELNAME for dl filter (default is {DEFAULT_PT_DL_MODEL} - "
|
|
105
147
|
"from the revised NeuroImage paper.) "
|
|
106
148
|
),
|
|
107
|
-
default=
|
|
149
|
+
default=None,
|
|
108
150
|
)
|
|
109
151
|
|
|
110
152
|
# Performance
|
|
@@ -550,6 +592,31 @@ def _get_parser():
|
|
|
550
592
|
help="Restrict cardiac waveform estimation to putative arteries only.",
|
|
551
593
|
default=False,
|
|
552
594
|
)
|
|
595
|
+
phase_proj_tuning.add_argument(
|
|
596
|
+
"--pulsatilitysigma",
|
|
597
|
+
dest="pulsatilitysigma",
|
|
598
|
+
action="store",
|
|
599
|
+
metavar="SIGMAINMM",
|
|
600
|
+
type=lambda x: pf.is_float(parser, x),
|
|
601
|
+
help=(
|
|
602
|
+
"Split pulsatility map spatial frequencies with a gaussian filter with sigma=SIGMAINMM. "
|
|
603
|
+
f"Default is {DEFAULT_PULSATILITYSIGMA}mm. "
|
|
604
|
+
),
|
|
605
|
+
default=DEFAULT_PULSATILITYSIGMA,
|
|
606
|
+
)
|
|
607
|
+
phase_proj_tuning.add_argument(
|
|
608
|
+
"--pulsatilitythreshold",
|
|
609
|
+
dest="pulsatilitythreshold",
|
|
610
|
+
action="store",
|
|
611
|
+
metavar="THRESHPCT",
|
|
612
|
+
type=lambda x: pf.is_float(parser, x),
|
|
613
|
+
help=(
|
|
614
|
+
"Consider voxels with a high spatial frequency pulsatility above THRESHPCT percent "
|
|
615
|
+
"to be vessels. "
|
|
616
|
+
f"Default is {DEFAULT_PULSATILITYTHRESHOLD}mm. "
|
|
617
|
+
),
|
|
618
|
+
default=DEFAULT_PULSATILITYSIGMA,
|
|
619
|
+
)
|
|
553
620
|
|
|
554
621
|
# Add version options
|
|
555
622
|
pf.addversionopts(parser)
|
|
@@ -563,7 +630,7 @@ def _get_parser():
|
|
|
563
630
|
metavar="MASKNAME",
|
|
564
631
|
help=(
|
|
565
632
|
"Instead of dynamically generating a processing mask from the data, use "
|
|
566
|
-
"the mask specified in the file MASKNAME. "
|
|
633
|
+
"the mask specified in the file MASKNAME. "
|
|
567
634
|
"The mask must be a 3D NIFTI file with x, y, z dimensions matching the fMRI data. "
|
|
568
635
|
),
|
|
569
636
|
default=None,
|
|
@@ -613,6 +680,13 @@ def _get_parser():
|
|
|
613
680
|
help="Number of iterations for calculating Wright map. Set to 0 to disable.",
|
|
614
681
|
default=0,
|
|
615
682
|
)
|
|
683
|
+
misc_opts.add_argument(
|
|
684
|
+
"--usenewvesselmethod",
|
|
685
|
+
dest="useoriginalvesselmethod",
|
|
686
|
+
action="store_false",
|
|
687
|
+
help="Will use the new pulsatility method to find blood vessels. ",
|
|
688
|
+
default=True,
|
|
689
|
+
)
|
|
616
690
|
pf.addtagopts(
|
|
617
691
|
misc_opts,
|
|
618
692
|
helptext="Additional key, value pairs to add to the info json file (useful for tracking analyses).",
|
|
@@ -635,6 +709,13 @@ def _get_parser():
|
|
|
635
709
|
help="Disable data detrending. ",
|
|
636
710
|
default=3,
|
|
637
711
|
)
|
|
712
|
+
debug_opts.add_argument(
|
|
713
|
+
"--normvesselmap",
|
|
714
|
+
dest="unnormvesselmap",
|
|
715
|
+
action="store_false",
|
|
716
|
+
help="Find vessels using normalized phase projection. ",
|
|
717
|
+
default=True,
|
|
718
|
+
)
|
|
638
719
|
debug_opts.add_argument(
|
|
639
720
|
"--noorthog",
|
|
640
721
|
dest="orthogonalize",
|
|
@@ -740,19 +821,64 @@ def _get_parser():
|
|
|
740
821
|
help="Disable the congrid value cache completely.",
|
|
741
822
|
default=True,
|
|
742
823
|
)
|
|
824
|
+
if tensorflowpresent:
|
|
825
|
+
debug_opts.add_argument(
|
|
826
|
+
"--usetensorflow",
|
|
827
|
+
dest="usepytorch",
|
|
828
|
+
action="store_false",
|
|
829
|
+
help=("Switch to the old style tensorflow deep learning filter"),
|
|
830
|
+
default=True,
|
|
831
|
+
)
|
|
832
|
+
debug_opts.add_argument(
|
|
833
|
+
"--focaldebug",
|
|
834
|
+
dest="focaldebug",
|
|
835
|
+
action="store_true",
|
|
836
|
+
help=("Enable targeted additional debugging output (used during development)."),
|
|
837
|
+
default=False,
|
|
838
|
+
)
|
|
743
839
|
|
|
744
840
|
return parser
|
|
745
841
|
|
|
746
842
|
|
|
747
|
-
def process_args(inputargs=None):
|
|
843
|
+
def process_args(inputargs: Optional[Any] = None) -> Any:
|
|
748
844
|
"""
|
|
749
|
-
Compile arguments for
|
|
845
|
+
Compile arguments for happy workflow.
|
|
846
|
+
|
|
847
|
+
This function processes input arguments for the happy workflow, handling
|
|
848
|
+
argument parsing, command line formatting, default model selection, and post-processing
|
|
849
|
+
of various parameters. It also manages motion file specifications, multiprocessing
|
|
850
|
+
settings, and output level calculations.
|
|
851
|
+
|
|
852
|
+
Parameters
|
|
853
|
+
----------
|
|
854
|
+
inputargs : optional
|
|
855
|
+
Input arguments to be processed. If None, arguments are parsed from the command line.
|
|
856
|
+
Default is None.
|
|
857
|
+
|
|
858
|
+
Returns
|
|
859
|
+
-------
|
|
860
|
+
args : argparse.Namespace
|
|
861
|
+
Processed arguments namespace containing all parsed and defaulted values.
|
|
862
|
+
|
|
863
|
+
Notes
|
|
864
|
+
-----
|
|
865
|
+
- If no model is specified, the function sets a default based on whether PyTorch or TensorFlow
|
|
866
|
+
is being used.
|
|
867
|
+
- The function writes formatted command line arguments to files for logging purposes.
|
|
868
|
+
- Multiprocessing is currently disabled due to instability.
|
|
869
|
+
- The output level is adjusted based on user-provided increments and decrements.
|
|
870
|
+
|
|
871
|
+
Examples
|
|
872
|
+
--------
|
|
873
|
+
>>> args = process_args()
|
|
874
|
+
>>> print(args.outputroot)
|
|
875
|
+
>>> print(args.modelname)
|
|
750
876
|
"""
|
|
751
877
|
args, argstowrite = pf.setargs(_get_parser, inputargs=inputargs)
|
|
752
878
|
|
|
753
879
|
# save the raw and formatted command lines
|
|
754
880
|
args.commandline = " ".join(argstowrite)
|
|
755
|
-
tide_io.writevec([args.commandline], args.outputroot + "_commandline.txt")
|
|
881
|
+
tide_io.writevec(np.array([args.commandline]), args.outputroot + "_commandline.txt")
|
|
756
882
|
formattedcommandline = []
|
|
757
883
|
for thetoken in argstowrite[0:3]:
|
|
758
884
|
formattedcommandline.append(thetoken)
|
|
@@ -771,7 +897,19 @@ def process_args(inputargs=None):
|
|
|
771
897
|
else:
|
|
772
898
|
suffix = ""
|
|
773
899
|
formattedcommandline[i] = prefix + formattedcommandline[i] + suffix
|
|
774
|
-
tide_io.writevec(formattedcommandline, args.outputroot + "_formattedcommandline.txt")
|
|
900
|
+
tide_io.writevec(np.array(formattedcommandline), args.outputroot + "_formattedcommandline.txt")
|
|
901
|
+
|
|
902
|
+
if not tensorflowpresent:
|
|
903
|
+
args.usepytorch = True
|
|
904
|
+
args.mpfix = False
|
|
905
|
+
|
|
906
|
+
# if user did not specify a model, set the default, depending on DL library
|
|
907
|
+
if args.modelname is None:
|
|
908
|
+
if args.usepytorch:
|
|
909
|
+
args.modelname = DEFAULT_PT_DL_MODEL
|
|
910
|
+
else:
|
|
911
|
+
args.modelname = DEFAULT_TF_DL_MODEL
|
|
912
|
+
print(f"No model specified. {args.usepytorch=}, so using {args.modelname}")
|
|
775
913
|
|
|
776
914
|
if args.debug:
|
|
777
915
|
print()
|
|
@@ -788,12 +926,12 @@ def process_args(inputargs=None):
|
|
|
788
926
|
args.upsamplefac = 100
|
|
789
927
|
args.centric = True
|
|
790
928
|
args.pulsereconstepsize = 0.01
|
|
791
|
-
args.unnormvesselmap = True
|
|
792
929
|
args.histlen = 100
|
|
793
930
|
args.softvesselfrac = 0.4
|
|
794
931
|
args.savecardiacnoise = True
|
|
795
932
|
args.colnum = None
|
|
796
933
|
args.colname = None
|
|
934
|
+
args.notchrolloff = 0.5
|
|
797
935
|
|
|
798
936
|
# Additional argument parsing not handled by argparse
|
|
799
937
|
# deal with notch filter logic
|
|
@@ -807,6 +945,8 @@ def process_args(inputargs=None):
|
|
|
807
945
|
args.motionfilename = None
|
|
808
946
|
|
|
809
947
|
# set the number of worker processes if multiprocessing
|
|
948
|
+
# Multiprocessing is very broken atm. Hard disable it.
|
|
949
|
+
# args.nprocs = 1
|
|
810
950
|
if args.nprocs < 1:
|
|
811
951
|
args.nprocs = tide_multiproc.maxcpus()
|
|
812
952
|
|
rapidtide/workflows/histnifti.py
CHANGED
|
@@ -19,8 +19,11 @@
|
|
|
19
19
|
import argparse
|
|
20
20
|
import copy
|
|
21
21
|
import sys
|
|
22
|
+
from argparse import Namespace
|
|
23
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
|
22
24
|
|
|
23
25
|
import numpy as np
|
|
26
|
+
from numpy.typing import NDArray
|
|
24
27
|
from tqdm import tqdm
|
|
25
28
|
|
|
26
29
|
import rapidtide.io as tide_io
|
|
@@ -29,7 +32,47 @@ import rapidtide.util as tide_util
|
|
|
29
32
|
import rapidtide.workflows.parser_funcs as pf
|
|
30
33
|
|
|
31
34
|
|
|
32
|
-
def _get_parser():
|
|
35
|
+
def _get_parser() -> Any:
|
|
36
|
+
"""
|
|
37
|
+
Generate and return an argument parser for the histnifti command-line tool.
|
|
38
|
+
|
|
39
|
+
This function constructs an `argparse.ArgumentParser` object configured with
|
|
40
|
+
all necessary arguments for processing NIFTI files and generating histograms
|
|
41
|
+
of their voxel values. It supports various options for controlling binning,
|
|
42
|
+
masking, normalization, and display behavior.
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
argparse.ArgumentParser
|
|
47
|
+
Configured argument parser object ready to parse command-line arguments.
|
|
48
|
+
|
|
49
|
+
Notes
|
|
50
|
+
-----
|
|
51
|
+
The parser includes the following positional and optional arguments:
|
|
52
|
+
|
|
53
|
+
- Positional arguments:
|
|
54
|
+
- inputfile: Path to the input NIFTI file.
|
|
55
|
+
- outputroot: Root name for output files.
|
|
56
|
+
|
|
57
|
+
- Optional arguments:
|
|
58
|
+
- --histlen: Set histogram length to LEN (default: auto).
|
|
59
|
+
- --minval: Minimum bin value in histogram.
|
|
60
|
+
- --maxval: Maximum bin value in histogram.
|
|
61
|
+
- --robustrange: Use robust range (2nd to 98th percentile) for histogram limits.
|
|
62
|
+
- --transform: Replace data values with their percentile scores.
|
|
63
|
+
- --nozero: Exclude zero values from histogram.
|
|
64
|
+
- --nozerothresh: Threshold for considering values as zero (default: 0.01).
|
|
65
|
+
- --normhist: Return probability density instead of raw counts.
|
|
66
|
+
- --maskfile: Only process voxels within a 3D mask.
|
|
67
|
+
- --nodisplay: Do not display histogram.
|
|
68
|
+
|
|
69
|
+
Examples
|
|
70
|
+
--------
|
|
71
|
+
>>> parser = _get_parser()
|
|
72
|
+
>>> args = parser.parse_args(['input.nii', 'output_root'])
|
|
73
|
+
>>> print(args.inputfile)
|
|
74
|
+
'input.nii'
|
|
75
|
+
"""
|
|
33
76
|
# get the command line parameters
|
|
34
77
|
parser = argparse.ArgumentParser(
|
|
35
78
|
prog="histnifti",
|
|
@@ -119,7 +162,80 @@ def _get_parser():
|
|
|
119
162
|
return parser
|
|
120
163
|
|
|
121
164
|
|
|
122
|
-
def histnifti(args):
|
|
165
|
+
def histnifti(args: Any) -> None:
|
|
166
|
+
"""
|
|
167
|
+
Compute and save histograms, sorted data, and percentiles from NIfTI image data.
|
|
168
|
+
|
|
169
|
+
This function reads input NIfTI data and optionally a mask, computes histograms
|
|
170
|
+
for each voxel (or across all voxels if 3D), and saves sorted data, percentiles,
|
|
171
|
+
and histogram results as NIfTI files. It supports both 3D and 4D data processing.
|
|
172
|
+
|
|
173
|
+
Parameters
|
|
174
|
+
----------
|
|
175
|
+
args : argparse.Namespace
|
|
176
|
+
Command-line arguments containing:
|
|
177
|
+
- inputfile : str
|
|
178
|
+
Path to the input NIfTI file.
|
|
179
|
+
- maskfile : str, optional
|
|
180
|
+
Path to the mask NIfTI file. If None, a full mask is generated.
|
|
181
|
+
- outputroot : str
|
|
182
|
+
Root name for output files.
|
|
183
|
+
- robustrange : bool
|
|
184
|
+
If True, use 2nd and 98th percentiles for histogram range.
|
|
185
|
+
- minval : float, optional
|
|
186
|
+
Minimum value for histogram range.
|
|
187
|
+
- maxval : float, optional
|
|
188
|
+
Maximum value for histogram range.
|
|
189
|
+
- histlen : int, optional
|
|
190
|
+
Number of histogram bins. If None, computed based on data size.
|
|
191
|
+
- nozero : bool
|
|
192
|
+
If True, exclude zero values from histogram calculation.
|
|
193
|
+
- nozerothresh : float
|
|
194
|
+
Threshold for excluding zero-like values when `nozero` is True.
|
|
195
|
+
- transform : bool
|
|
196
|
+
If True, apply a transformation to the data.
|
|
197
|
+
- display : bool
|
|
198
|
+
If True, display histogram plots.
|
|
199
|
+
- normhist : bool
|
|
200
|
+
If True, normalize histogram values.
|
|
201
|
+
|
|
202
|
+
Returns
|
|
203
|
+
-------
|
|
204
|
+
None
|
|
205
|
+
This function does not return a value but saves multiple NIfTI files:
|
|
206
|
+
- `<outputroot>_sorted.nii.gz`: Sorted time series data.
|
|
207
|
+
- `<outputroot>_pcts.nii.gz`: Percentile values.
|
|
208
|
+
- `<outputroot>_hists.nii.gz`: Histogram data per voxel.
|
|
209
|
+
- `<outputroot>_transformed.nii.gz`: Transformed data (if `transform` is True).
|
|
210
|
+
- `<outputroot>_hist.txt`: Histogram plot (if `display` is True).
|
|
211
|
+
|
|
212
|
+
Notes
|
|
213
|
+
-----
|
|
214
|
+
- For 4D data, the function computes histograms, sorted arrays, and percentiles
|
|
215
|
+
for each voxel.
|
|
216
|
+
- For 3D data, the function can compute a global histogram or apply a transformation.
|
|
217
|
+
- The function uses `tide_io` for reading/writing NIfTI files and `tide_stats` for
|
|
218
|
+
statistical operations.
|
|
219
|
+
|
|
220
|
+
Examples
|
|
221
|
+
--------
|
|
222
|
+
>>> import argparse
|
|
223
|
+
>>> args = argparse.Namespace(
|
|
224
|
+
... inputfile='data.nii.gz',
|
|
225
|
+
... maskfile=None,
|
|
226
|
+
... outputroot='output',
|
|
227
|
+
... robustrange=False,
|
|
228
|
+
... minval=None,
|
|
229
|
+
... maxval=None,
|
|
230
|
+
... histlen=None,
|
|
231
|
+
... nozero=False,
|
|
232
|
+
... nozerothresh=0.0,
|
|
233
|
+
... transform=False,
|
|
234
|
+
... display=False,
|
|
235
|
+
... normhist=False
|
|
236
|
+
... )
|
|
237
|
+
>>> histnifti(args)
|
|
238
|
+
"""
|
|
123
239
|
# set default variable values
|
|
124
240
|
thepercentiles = [0.2, 0.25, 0.5, 0.75, 0.98]
|
|
125
241
|
thepvalnames = []
|