rapidtide 3.0.10__py3-none-any.whl → 3.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.
Files changed (141) hide show
  1. rapidtide/Colortables.py +492 -27
  2. rapidtide/OrthoImageItem.py +1053 -47
  3. rapidtide/RapidtideDataset.py +1533 -86
  4. rapidtide/_version.py +3 -3
  5. rapidtide/calccoherence.py +196 -29
  6. rapidtide/calcnullsimfunc.py +191 -40
  7. rapidtide/calcsimfunc.py +245 -42
  8. rapidtide/correlate.py +1210 -393
  9. rapidtide/data/examples/src/testLD +56 -0
  10. rapidtide/data/examples/src/testalign +1 -1
  11. rapidtide/data/examples/src/testdelayvar +0 -1
  12. rapidtide/data/examples/src/testfmri +19 -1
  13. rapidtide/data/examples/src/testglmfilt +5 -5
  14. rapidtide/data/examples/src/testhappy +30 -1
  15. rapidtide/data/examples/src/testppgproc +17 -0
  16. rapidtide/data/examples/src/testrolloff +11 -0
  17. rapidtide/data/models/model_cnn_pytorch/best_model.pth +0 -0
  18. rapidtide/data/models/model_cnn_pytorch/loss.png +0 -0
  19. rapidtide/data/models/model_cnn_pytorch/loss.txt +1 -0
  20. rapidtide/data/models/model_cnn_pytorch/model.pth +0 -0
  21. rapidtide/data/models/model_cnn_pytorch/model_meta.json +68 -0
  22. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm.nii.gz +0 -0
  23. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm_mask.nii.gz +0 -0
  24. rapidtide/decorators.py +91 -0
  25. rapidtide/dlfilter.py +2225 -108
  26. rapidtide/dlfiltertorch.py +4843 -0
  27. rapidtide/externaltools.py +327 -12
  28. rapidtide/fMRIData_class.py +79 -40
  29. rapidtide/filter.py +1899 -810
  30. rapidtide/fit.py +2004 -574
  31. rapidtide/genericmultiproc.py +93 -18
  32. rapidtide/happy_supportfuncs.py +2044 -171
  33. rapidtide/helper_classes.py +584 -43
  34. rapidtide/io.py +2363 -370
  35. rapidtide/linfitfiltpass.py +341 -75
  36. rapidtide/makelaggedtcs.py +211 -20
  37. rapidtide/maskutil.py +423 -53
  38. rapidtide/miscmath.py +827 -121
  39. rapidtide/multiproc.py +210 -22
  40. rapidtide/patchmatch.py +234 -33
  41. rapidtide/peakeval.py +32 -30
  42. rapidtide/ppgproc.py +2203 -0
  43. rapidtide/qualitycheck.py +352 -39
  44. rapidtide/refinedelay.py +422 -57
  45. rapidtide/refineregressor.py +498 -184
  46. rapidtide/resample.py +671 -185
  47. rapidtide/scripts/applyppgproc.py +28 -0
  48. rapidtide/simFuncClasses.py +1052 -77
  49. rapidtide/simfuncfit.py +260 -46
  50. rapidtide/stats.py +540 -238
  51. rapidtide/tests/happycomp +9 -0
  52. rapidtide/tests/test_dlfiltertorch.py +627 -0
  53. rapidtide/tests/test_findmaxlag.py +24 -8
  54. rapidtide/tests/test_fullrunhappy_v1.py +0 -2
  55. rapidtide/tests/test_fullrunhappy_v2.py +0 -2
  56. rapidtide/tests/test_fullrunhappy_v3.py +1 -0
  57. rapidtide/tests/test_fullrunhappy_v4.py +2 -2
  58. rapidtide/tests/test_fullrunrapidtide_v7.py +1 -1
  59. rapidtide/tests/test_simroundtrip.py +8 -8
  60. rapidtide/tests/utils.py +9 -8
  61. rapidtide/tidepoolTemplate.py +142 -38
  62. rapidtide/tidepoolTemplate_alt.py +165 -44
  63. rapidtide/tidepoolTemplate_big.py +189 -52
  64. rapidtide/util.py +1217 -118
  65. rapidtide/voxelData.py +684 -37
  66. rapidtide/wiener.py +19 -12
  67. rapidtide/wiener2.py +113 -7
  68. rapidtide/wiener_doc.py +255 -0
  69. rapidtide/workflows/adjustoffset.py +105 -3
  70. rapidtide/workflows/aligntcs.py +85 -2
  71. rapidtide/workflows/applydlfilter.py +87 -10
  72. rapidtide/workflows/applyppgproc.py +522 -0
  73. rapidtide/workflows/atlasaverage.py +210 -47
  74. rapidtide/workflows/atlastool.py +100 -3
  75. rapidtide/workflows/calcSimFuncMap.py +294 -64
  76. rapidtide/workflows/calctexticc.py +201 -9
  77. rapidtide/workflows/ccorrica.py +97 -4
  78. rapidtide/workflows/cleanregressor.py +168 -29
  79. rapidtide/workflows/delayvar.py +163 -10
  80. rapidtide/workflows/diffrois.py +81 -3
  81. rapidtide/workflows/endtidalproc.py +144 -4
  82. rapidtide/workflows/fdica.py +195 -15
  83. rapidtide/workflows/filtnifti.py +70 -3
  84. rapidtide/workflows/filttc.py +74 -3
  85. rapidtide/workflows/fitSimFuncMap.py +206 -48
  86. rapidtide/workflows/fixtr.py +73 -3
  87. rapidtide/workflows/gmscalc.py +113 -3
  88. rapidtide/workflows/happy.py +813 -201
  89. rapidtide/workflows/happy2std.py +144 -12
  90. rapidtide/workflows/happy_parser.py +149 -8
  91. rapidtide/workflows/histnifti.py +118 -2
  92. rapidtide/workflows/histtc.py +84 -3
  93. rapidtide/workflows/linfitfilt.py +117 -4
  94. rapidtide/workflows/localflow.py +328 -28
  95. rapidtide/workflows/mergequality.py +79 -3
  96. rapidtide/workflows/niftidecomp.py +322 -18
  97. rapidtide/workflows/niftistats.py +174 -4
  98. rapidtide/workflows/pairproc.py +88 -2
  99. rapidtide/workflows/pairwisemergenifti.py +85 -2
  100. rapidtide/workflows/parser_funcs.py +1421 -40
  101. rapidtide/workflows/physiofreq.py +137 -11
  102. rapidtide/workflows/pixelcomp.py +208 -5
  103. rapidtide/workflows/plethquality.py +103 -21
  104. rapidtide/workflows/polyfitim.py +151 -11
  105. rapidtide/workflows/proj2flow.py +75 -2
  106. rapidtide/workflows/rankimage.py +111 -4
  107. rapidtide/workflows/rapidtide.py +272 -15
  108. rapidtide/workflows/rapidtide2std.py +98 -2
  109. rapidtide/workflows/rapidtide_parser.py +109 -9
  110. rapidtide/workflows/refineDelayMap.py +143 -33
  111. rapidtide/workflows/refineRegressor.py +682 -93
  112. rapidtide/workflows/regressfrommaps.py +152 -31
  113. rapidtide/workflows/resamplenifti.py +85 -3
  114. rapidtide/workflows/resampletc.py +91 -3
  115. rapidtide/workflows/retrolagtcs.py +98 -6
  116. rapidtide/workflows/retroregress.py +165 -9
  117. rapidtide/workflows/roisummarize.py +173 -5
  118. rapidtide/workflows/runqualitycheck.py +71 -3
  119. rapidtide/workflows/showarbcorr.py +147 -4
  120. rapidtide/workflows/showhist.py +86 -2
  121. rapidtide/workflows/showstxcorr.py +160 -3
  122. rapidtide/workflows/showtc.py +159 -3
  123. rapidtide/workflows/showxcorrx.py +184 -4
  124. rapidtide/workflows/showxy.py +185 -15
  125. rapidtide/workflows/simdata.py +262 -36
  126. rapidtide/workflows/spatialfit.py +77 -2
  127. rapidtide/workflows/spatialmi.py +251 -27
  128. rapidtide/workflows/spectrogram.py +305 -32
  129. rapidtide/workflows/synthASL.py +154 -3
  130. rapidtide/workflows/tcfrom2col.py +76 -2
  131. rapidtide/workflows/tcfrom3col.py +74 -2
  132. rapidtide/workflows/tidepool.py +2972 -133
  133. rapidtide/workflows/utils.py +19 -14
  134. rapidtide/workflows/utils_doc.py +293 -0
  135. rapidtide/workflows/variabilityizer.py +116 -3
  136. {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/METADATA +10 -9
  137. {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/RECORD +141 -122
  138. {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/entry_points.txt +1 -0
  139. {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/WHEEL +0 -0
  140. {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/licenses/LICENSE +0 -0
  141. {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/top_level.txt +0 -0
@@ -18,8 +18,11 @@
18
18
  #
19
19
  import argparse
20
20
  import sys
21
+ from argparse import Namespace
22
+ from typing import Any, Callable, Dict, List, Optional, Tuple, Union
21
23
 
22
24
  import numpy as np
25
+ from numpy.typing import NDArray
23
26
  from sklearn.decomposition import PCA, FastICA, SparsePCA
24
27
 
25
28
  import rapidtide.filter as tide_filt
@@ -27,9 +30,47 @@ import rapidtide.io as tide_io
27
30
  from rapidtide.workflows.parser_funcs import is_float, is_valid_file
28
31
 
29
32
 
30
- def _get_parser(decompaxis):
33
+ def _get_parser(decompaxis: Any) -> Any:
31
34
  """
32
- Argument parser for spatialdecomp and temporaldecomp
35
+ Argument parser for spatialdecomp and temporaldecomp.
36
+
37
+ This function constructs and returns an `argparse.ArgumentParser` object
38
+ configured for either spatial or temporal decomposition tasks. The parser
39
+ is tailored to handle common arguments required for PCA or ICA decomposition
40
+ of neuroimaging data (e.g., NIfTI files).
41
+
42
+ Parameters
43
+ ----------
44
+ decompaxis : Any
45
+ Specifies the axis along which decomposition is performed. Must be
46
+ either "temporal" or "spatial". Determines the program name and
47
+ description of the parser.
48
+
49
+ Returns
50
+ -------
51
+ argparse.ArgumentParser
52
+ Configured argument parser for the specified decomposition type.
53
+
54
+ Raises
55
+ ------
56
+ ValueError
57
+ If `decompaxis` is not "temporal" or "spatial".
58
+
59
+ Notes
60
+ -----
61
+ The returned parser includes support for:
62
+ - Input data file validation
63
+ - Output root naming
64
+ - Data masking
65
+ - Number of components to extract
66
+ - Spatial smoothing
67
+ - Decomposition type (PCA, ICA, sparse)
68
+ - Preprocessing options such as demeaning and variance normalization
69
+
70
+ Examples
71
+ --------
72
+ >>> parser = _get_parser("temporal")
73
+ >>> args = parser.parse_args(['data.nii', 'output_root'])
33
74
  """
34
75
  if decompaxis == "temporal":
35
76
  parser = argparse.ArgumentParser(
@@ -109,15 +150,96 @@ def _get_parser(decompaxis):
109
150
  return parser
110
151
 
111
152
 
112
- def _get_parser_temporal():
153
+ def _get_parser_temporal() -> Any:
154
+ """
155
+ Get parser for the temporal variant of the program.
156
+
157
+ This function is a convenience wrapper that calls the internal `_get_parser`
158
+ function with the argument "temporal" to obtain the temporal parser object.
159
+
160
+ Returns
161
+ -------
162
+ Any
163
+ The temporal parser instance. The specific type depends on the implementation
164
+ of the underlying `_get_parser` function and the temporal parser configuration.
165
+
166
+ Notes
167
+ -----
168
+ This function is intended for internal use only and should not be called directly
169
+ by end users. The returned parser is typically used for parsing temporal data
170
+ such as dates, times, and time intervals.
171
+
172
+ Examples
173
+ --------
174
+ >>> parser = _get_parser_temporal()
175
+ >>> # Use parser for temporal data processing
176
+ """
113
177
  return _get_parser("temporal")
114
178
 
115
179
 
116
- def _get_parser_spatial():
180
+ def _get_parser_spatial() -> Any:
181
+ """
182
+ Get parser for the spatial variant of the program.
183
+
184
+ Returns
185
+ -------
186
+ Any
187
+ The spatial parser object returned by `_get_parser` function.
188
+
189
+ Notes
190
+ -----
191
+ This function is a convenience wrapper that calls `_get_parser` with the
192
+ argument "spatial". It is used internally to retrieve spatial parsing
193
+ capabilities for the application.
194
+
195
+ Examples
196
+ --------
197
+ >>> parser = _get_parser_spatial()
198
+ >>> isinstance(parser, SomeParserClass)
199
+ True
200
+ """
117
201
  return _get_parser("spatial")
118
202
 
119
203
 
120
- def transposeifspatial(data, decompaxis="temporal"):
204
+ def transposeifspatial(data: Any, decompaxis: str = "temporal") -> None:
205
+ """
206
+ Transpose data if decomposition axis is spatial.
207
+
208
+ Parameters
209
+ ----------
210
+ data : Any
211
+ Input data to be transposed if necessary
212
+ decompaxis : str, default="temporal"
213
+ Decomposition axis specification. If "spatial", the data will be transposed
214
+ using numpy.transpose() function. Otherwise, the original data is returned
215
+ unchanged.
216
+
217
+ Returns
218
+ -------
219
+ Any
220
+ Transposed data if decompaxis is "spatial", otherwise returns the original data
221
+
222
+ Notes
223
+ -----
224
+ This function provides a conditional transpose operation based on the decomposition
225
+ axis specification. It's useful in scenarios where data processing needs to
226
+ adapt based on the spatial or temporal nature of the decomposition.
227
+
228
+ Examples
229
+ --------
230
+ >>> import numpy as np
231
+ >>> data = np.array([[1, 2, 3], [4, 5, 6]])
232
+ >>> transposed = transposeifspatial(data, decompaxis="spatial")
233
+ >>> print(transposed)
234
+ [[1 4]
235
+ [2 5]
236
+ [3 6]]
237
+
238
+ >>> original = transposeifspatial(data, decompaxis="temporal")
239
+ >>> print(original)
240
+ [[1 2 3]
241
+ [4 5 6]]
242
+ """
121
243
  if decompaxis == "spatial":
122
244
  return np.transpose(data)
123
245
  else:
@@ -125,16 +247,90 @@ def transposeifspatial(data, decompaxis="temporal"):
125
247
 
126
248
 
127
249
  def niftidecomp_workflow(
128
- decompaxis,
129
- datafilelist,
130
- datamaskname=None,
131
- decomptype="pca",
132
- pcacomponents=0.5,
133
- icacomponents=None,
134
- varnorm=True,
135
- demean=True,
136
- sigma=0.0,
137
- ):
250
+ decompaxis: Any,
251
+ datafilelist: Any,
252
+ datamaskname: Optional[Any] = None,
253
+ decomptype: str = "pca",
254
+ pcacomponents: float = 0.5,
255
+ icacomponents: Optional[Any] = None,
256
+ varnorm: bool = True,
257
+ demean: bool = True,
258
+ sigma: float = 0.0,
259
+ ) -> None:
260
+ """
261
+ Perform PCA or ICA decomposition on 4D NIfTI data along a specified axis.
262
+
263
+ This function reads a list of NIfTI files, applies optional smoothing and masking,
264
+ and performs either Principal Component Analysis (PCA) or Independent Component Analysis (ICA)
265
+ on the data. The decomposition is performed along either the temporal or spatial axis,
266
+ depending on the `decompaxis` parameter. The results include component images, coefficients,
267
+ and inverse-transformed data.
268
+
269
+ Parameters
270
+ ----------
271
+ decompaxis : Any
272
+ Axis along which to perform decomposition. Either "temporal" or "spatial".
273
+ datafilelist : Any
274
+ List of paths to NIfTI data files to be processed.
275
+ datamaskname : Any, optional
276
+ Path to a NIfTI mask file. If provided, only voxels within the mask will be processed.
277
+ Default is None.
278
+ decomptype : str, optional
279
+ Type of decomposition to perform. Either "pca" or "ica". Default is "pca".
280
+ pcacomponents : float, optional
281
+ Number of components to retain for PCA. If less than 1, specifies the fraction of
282
+ variance to retain. Default is 0.5.
283
+ icacomponents : Any, optional
284
+ Number of components to retain for ICA. If None, all components are returned.
285
+ Default is None.
286
+ varnorm : bool, optional
287
+ Whether to perform variance normalization. Default is True.
288
+ demean : bool, optional
289
+ Whether to demean the data. Default is True.
290
+ sigma : float, optional
291
+ Standard deviation for Gaussian smoothing. If 0.0, no smoothing is applied.
292
+ Default is 0.0.
293
+
294
+ Returns
295
+ -------
296
+ tuple
297
+ A tuple containing:
298
+ - outputcomponents : ndarray
299
+ Decomposed components reshaped to original spatial dimensions.
300
+ - outputcoefficients : ndarray
301
+ Coefficients of the decomposition.
302
+ - outinvtrans : ndarray
303
+ Inverse-transformed data.
304
+ - exp_var : ndarray
305
+ Explained variance for each component.
306
+ - exp_var_pct : ndarray
307
+ Explained variance percentage for each component.
308
+ - datafile_hdr : dict
309
+ Header of the input data file.
310
+ - datafiledims : list
311
+ Dimensions of the input data file.
312
+ - datafilesizes : list
313
+ Size parameters of the input data file.
314
+
315
+ Notes
316
+ -----
317
+ - The function assumes all input NIfTI files have matching spatial and temporal dimensions.
318
+ - For ICA, the `FastICA` algorithm is used.
319
+ - For PCA, both regular PCA and Sparse PCA are supported.
320
+ - If `datamaskname` is provided, the mask is applied before decomposition.
321
+ - The output data is reshaped to match the original NIfTI dimensions.
322
+
323
+ Examples
324
+ --------
325
+ >>> niftidecomp_workflow(
326
+ ... decompaxis="temporal",
327
+ ... datafilelist=["data1.nii", "data2.nii"],
328
+ ... decomptype="pca",
329
+ ... pcacomponents=0.95,
330
+ ... varnorm=True,
331
+ ... demean=True
332
+ ... )
333
+ """
138
334
  print(f"Will perform {decomptype} analysis along the {decompaxis} axis")
139
335
 
140
336
  if decompaxis == "temporal":
@@ -360,7 +556,55 @@ def niftidecomp_workflow(
360
556
  )
361
557
 
362
558
 
363
- def main(decompaxis, args):
559
+ def main(decompaxis: Any, args: Any) -> None:
560
+ """
561
+ Main function for performing decomposition analysis on neuroimaging data.
562
+
563
+ This function handles the configuration of decomposition parameters based on
564
+ the number of components specified (`ncomp`), and then executes the decomposition
565
+ workflow using `niftidecomp_workflow`. It saves the results including components,
566
+ coefficients, and explained variance to disk.
567
+
568
+ Parameters
569
+ ----------
570
+ decompaxis : Any
571
+ The axis along which decomposition is performed (e.g., 'temporal' or 'spatial').
572
+ args : Any
573
+ A dictionary containing various configuration parameters such as:
574
+ - `ncomp`: Number of components to extract.
575
+ - `datafile`: Path to the input data file.
576
+ - `datamaskname`: Path to the data mask file.
577
+ - `decomptype`: Type of decomposition (e.g., PCA, ICA).
578
+ - `varnorm`: Whether to normalize variance.
579
+ - `demean`: Whether to demean the data.
580
+ - `sigma`: Sigma value for smoothing.
581
+ - `outputroot`: Root name for output files.
582
+
583
+ Returns
584
+ -------
585
+ None
586
+ This function does not return a value but writes multiple output files to disk.
587
+
588
+ Notes
589
+ -----
590
+ - If `ncomp` is less than 0.0, `pcacomponents` is set to 0.5 and `icacomponents` is set to None.
591
+ - If `ncomp` is between 0.0 and 1.0, `pcacomponents` is set to `ncomp` and `icacomponents` is set to None.
592
+ - Otherwise, both `pcacomponents` and `icacomponents` are set to the integer value of `ncomp`.
593
+
594
+ Examples
595
+ --------
596
+ >>> args = {
597
+ ... "ncomp": 5,
598
+ ... "datafile": "data.nii.gz",
599
+ ... "datamaskname": "mask.nii.gz",
600
+ ... "decomptype": "pca",
601
+ ... "varnorm": True,
602
+ ... "demean": True,
603
+ ... "sigma": 2.0,
604
+ ... "outputroot": "output"
605
+ ... }
606
+ >>> main("temporal", args)
607
+ """
364
608
  if args["ncomp"] < 0.0:
365
609
  args["pcacomponents"] = 0.5
366
610
  args["icacomponents"] = None
@@ -448,9 +692,69 @@ def main(decompaxis, args):
448
692
  )
449
693
 
450
694
 
451
- def main_temporal(args):
695
+ def main_temporal(args: Any) -> None:
696
+ """
697
+ Execute main function for temporal processing.
698
+
699
+ This function serves as a wrapper that calls the main execution function
700
+ with "temporal" as the processor type and converts the arguments to a dictionary.
701
+
702
+ Parameters
703
+ ----------
704
+ args : Any
705
+ Command line arguments or configuration arguments containing
706
+ parameters needed for temporal processing. Typically contains
707
+ various temporal processing options and settings.
708
+
709
+ Returns
710
+ -------
711
+ None
712
+ This function does not return any value.
713
+
714
+ Notes
715
+ -----
716
+ The function delegates to a main execution function with "temporal" processor
717
+ type, making it a specialized entry point for temporal data processing workflows.
718
+
719
+ Examples
720
+ --------
721
+ >>> import argparse
722
+ >>> parser = argparse.ArgumentParser()
723
+ >>> parser.add_argument('--input', type=str, help='Input file path')
724
+ >>> args = parser.parse_args(['--input', 'data.csv'])
725
+ >>> main_temporal(args)
726
+ """
452
727
  main("temporal", vars(args))
453
728
 
454
729
 
455
- def main_spatial(args):
730
+ def main_spatial(args: Any) -> None:
731
+ """
732
+ Main function for spatial processing pipeline.
733
+
734
+ This function serves as the entry point for spatial data processing operations,
735
+ delegating to the main processing function with "spatial" as the operation type.
736
+
737
+ Parameters
738
+ ----------
739
+ args : Any
740
+ Command line arguments or configuration parameters containing spatial
741
+ processing options. Expected to be an argparse.Namespace or similar
742
+ structure with relevant attributes for spatial operations.
743
+
744
+ Returns
745
+ -------
746
+ None
747
+ This function does not return any value.
748
+
749
+ Notes
750
+ -----
751
+ The function internally calls `main("spatial", vars(args))` which routes
752
+ the spatial processing workflow to the main execution engine.
753
+
754
+ Examples
755
+ --------
756
+ >>> import argparse
757
+ >>> args = argparse.Namespace(input_file="data.csv", output_dir="output/")
758
+ >>> main_spatial(args)
759
+ """
456
760
  main("spatial", vars(args))
@@ -21,8 +21,11 @@ import copy
21
21
  import platform
22
22
  import sys
23
23
  import time
24
+ from argparse import Namespace
25
+ from typing import Any, Callable, Dict, List, Optional, Tuple, Union
24
26
 
25
27
  import numpy as np
28
+ from numpy.typing import NDArray
26
29
  from scipy.stats import ttest_ind, ttest_rel
27
30
  from tqdm import tqdm
28
31
 
@@ -33,7 +36,44 @@ import rapidtide.util as tide_util
33
36
  from rapidtide.workflows.parser_funcs import is_float, is_valid_file
34
37
 
35
38
 
36
- def _get_parser(calctype="icc"):
39
+ def _get_parser(calctype: str = "icc") -> Any:
40
+ """
41
+ Generate an argument parser for ICC or t-test calculation workflows.
42
+
43
+ This function creates an `argparse.ArgumentParser` tailored for either
44
+ calculating per-voxel Intraclass Correlation Coefficient (ICC(3,1)) or
45
+ performing per-voxel t-tests on 4D NIfTI images.
46
+
47
+ Parameters
48
+ ----------
49
+ calctype : str, optional
50
+ Type of calculation to perform. Either "icc" for ICC(3,1) or "ttest"
51
+ for t-test. Default is "icc".
52
+
53
+ Returns
54
+ -------
55
+ argparse.ArgumentParser
56
+ Configured argument parser for the specified calculation type.
57
+
58
+ Raises
59
+ ------
60
+ ValueError
61
+ If `calctype` is not "icc" or "ttest".
62
+
63
+ Notes
64
+ -----
65
+ The parser supports both required and optional arguments depending on
66
+ the calculation type. For ICC, an additional `measurementlist` argument
67
+ is required. For t-test, optional arguments such as `--paired` and
68
+ `--alternative` are available.
69
+
70
+ Examples
71
+ --------
72
+ >>> parser = _get_parser("icc")
73
+ >>> args = parser.parse_args(["file1.nii", "file2.nii", "output_root"])
74
+ >>> parser = _get_parser("ttest")
75
+ >>> args = parser.parse_args(["file1.nii", "file2.nii", "output_root"])
76
+ """
37
77
  if calctype == "icc":
38
78
  parser = argparse.ArgumentParser(
39
79
  prog="calcicc",
@@ -161,7 +201,55 @@ def _get_parser(calctype="icc"):
161
201
  return parser
162
202
 
163
203
 
164
- def parsemeasurementlist(measlist, numfiles, debug=False):
204
+ def parsemeasurementlist(measlist: Any, numfiles: Any, debug: bool = False) -> None:
205
+ """
206
+ Parse a measurement list to extract file and volume indices from string components.
207
+
208
+ This function processes a 2D array of strings, where each string contains either
209
+ one or two comma-separated integers representing file and volume indices. It
210
+ validates the indices against the number of available files and returns two
211
+ arrays of the same shape as `measlist` containing the parsed file and volume
212
+ indices.
213
+
214
+ Parameters
215
+ ----------
216
+ measlist : array-like
217
+ A 2D array of strings, where each string represents a measurement entry.
218
+ Each entry can contain one or two comma-separated integers:
219
+ - One integer: interpreted as volume index (file index defaults to 0)
220
+ - Two integers: interpreted as file index and volume index
221
+ numfiles : int
222
+ The total number of available files. Used to validate file indices.
223
+ debug : bool, optional
224
+ If True, prints debug information for each parsed element. Default is False.
225
+
226
+ Returns
227
+ -------
228
+ tuple of ndarray
229
+ A tuple containing two 2D arrays of integers:
230
+ - `filesel`: File indices parsed from `measlist`
231
+ - `volumesel`: Volume indices parsed from `measlist`
232
+
233
+ Notes
234
+ -----
235
+ - Entries in `measlist` must be strings that can be split by commas.
236
+ - File indices are validated to ensure they do not exceed `numfiles - 1`.
237
+ - If an entry has more than one comma, the function will exit with an error.
238
+ - The function prints error messages and exits if invalid input is detected.
239
+
240
+ Examples
241
+ --------
242
+ >>> import numpy as np
243
+ >>> measlist = np.array([['0,5', '1,3'], ['2', '0,7']])
244
+ >>> numfiles = 5
245
+ >>> filesel, volumesel = parsemeasurementlist(measlist, numfiles)
246
+ >>> print(filesel)
247
+ [[0 1]
248
+ [2 0]]
249
+ >>> print(volumesel)
250
+ [[5 3]
251
+ [2 7]]
252
+ """
165
253
  nummeas, numsubjs = measlist.shape[0], measlist.shape[1]
166
254
  filesel = np.zeros((nummeas, numsubjs), dtype=int)
167
255
  volumesel = np.zeros((nummeas, numsubjs), dtype=int)
@@ -189,7 +277,53 @@ def parsemeasurementlist(measlist, numfiles, debug=False):
189
277
  return filesel, volumesel
190
278
 
191
279
 
192
- def makdcommandlinelist(arglist, starttime, endtime, extra=None):
280
+ def makdcommandlinelist(
281
+ arglist: Any, starttime: Any, endtime: Any, extra: Optional[Any] = None
282
+ ) -> None:
283
+ """
284
+ Create a list of command line information for processing logs.
285
+
286
+ This function generates diagnostic information about a processing run including
287
+ timestamps, version information, and the command that was executed.
288
+
289
+ Parameters
290
+ ----------
291
+ arglist : Any
292
+ List of command line arguments that were used to invoke the process
293
+ starttime : Any
294
+ Start time of the process, typically a timestamp
295
+ endtime : Any
296
+ End time of the process, typically a timestamp
297
+ extra : Any, optional
298
+ Additional information to include in the output, by default None
299
+
300
+ Returns
301
+ -------
302
+ list of str
303
+ List containing diagnostic lines including:
304
+ - Processing date and time
305
+ - Processing duration
306
+ - Version and system information
307
+ - Extra information (if provided)
308
+ - The original command line
309
+
310
+ Notes
311
+ -----
312
+ The function uses `time.strftime` to format the start time and calculates
313
+ the processing duration as the difference between endtime and starttime.
314
+ The version information is retrieved using `tide_util.version()`.
315
+
316
+ Examples
317
+ --------
318
+ >>> arglist = ['python', 'script.py', '--input', 'data.txt']
319
+ >>> starttime = time.time() - 10
320
+ >>> endtime = time.time()
321
+ >>> makdcommandlinelist(arglist, starttime, endtime)
322
+ ['# Processed on Mon, 01 Jan 2024 12:00:00 UTC.',
323
+ '# Processing took 10.000 seconds.',
324
+ '# Using hostname (1.0.0, 2024-01-01)',
325
+ 'python script.py --input data.txt']
326
+ """
193
327
  # get the processing date
194
328
  dateline = (
195
329
  "# Processed on "
@@ -226,7 +360,43 @@ def makdcommandlinelist(arglist, starttime, endtime, extra=None):
226
360
  return [dateline, timeline, nodeline, commandline]
227
361
 
228
362
 
229
- def niftistats_main(calctype="icc"):
363
+ def niftistats_main(calctype: str = "icc") -> None:
364
+ """
365
+ Main function for computing intraclass correlation (ICC) or two-sample t-test on NIfTI files.
366
+
367
+ This function processes NIfTI data files to compute either an intraclass correlation (ICC)
368
+ or a two-sample t-test across subjects and measurements. It supports reading data from
369
+ multiple NIfTI files, applying smoothing, masking, and performing statistical analysis
370
+ voxel-wise. The results are saved as NIfTI files with corresponding statistics.
371
+
372
+ Parameters
373
+ ----------
374
+ calctype : str, optional
375
+ Type of statistical calculation to perform. Options are:
376
+ - "icc": Compute intraclass correlation (default)
377
+ - "ttest": Compute two-sample t-test
378
+ Default is "icc".
379
+
380
+ Returns
381
+ -------
382
+ None
383
+ This function does not return a value but saves output NIfTI files and a command-line
384
+ log file to disk.
385
+
386
+ Notes
387
+ -----
388
+ For ICC calculation:
389
+ - Requires at least two measurements per subject.
390
+ - Outputs ICC, variance components, and session effect F-statistic.
391
+ For t-test calculation:
392
+ - Requires exactly two measurements.
393
+ - Outputs t-statistic and p-value.
394
+
395
+ Examples
396
+ --------
397
+ >>> niftistats_main(calctype="icc")
398
+ >>> niftistats_main(calctype="ttest")
399
+ """
230
400
  try:
231
401
  args = _get_parser(calctype=calctype).parse_args()
232
402
  except SystemExit: