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.
Files changed (144) hide show
  1. rapidtide/Colortables.py +492 -27
  2. rapidtide/OrthoImageItem.py +1049 -46
  3. rapidtide/RapidtideDataset.py +1533 -86
  4. rapidtide/_version.py +3 -3
  5. rapidtide/calccoherence.py +196 -29
  6. rapidtide/calcnullsimfunc.py +188 -40
  7. rapidtide/calcsimfunc.py +242 -42
  8. rapidtide/correlate.py +1203 -383
  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 +53 -3
  13. rapidtide/data/examples/src/testglmfilt +5 -5
  14. rapidtide/data/examples/src/testhappy +29 -7
  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/decorators.py +91 -0
  23. rapidtide/dlfilter.py +2226 -110
  24. rapidtide/dlfiltertorch.py +4842 -0
  25. rapidtide/externaltools.py +327 -12
  26. rapidtide/fMRIData_class.py +79 -40
  27. rapidtide/filter.py +1899 -810
  28. rapidtide/fit.py +2011 -581
  29. rapidtide/genericmultiproc.py +93 -18
  30. rapidtide/happy_supportfuncs.py +2047 -172
  31. rapidtide/helper_classes.py +584 -43
  32. rapidtide/io.py +2370 -372
  33. rapidtide/linfitfiltpass.py +346 -99
  34. rapidtide/makelaggedtcs.py +210 -24
  35. rapidtide/maskutil.py +448 -62
  36. rapidtide/miscmath.py +827 -121
  37. rapidtide/multiproc.py +210 -22
  38. rapidtide/patchmatch.py +242 -42
  39. rapidtide/peakeval.py +31 -31
  40. rapidtide/ppgproc.py +2203 -0
  41. rapidtide/qualitycheck.py +352 -39
  42. rapidtide/refinedelay.py +431 -57
  43. rapidtide/refineregressor.py +494 -189
  44. rapidtide/resample.py +671 -185
  45. rapidtide/scripts/applyppgproc.py +28 -0
  46. rapidtide/scripts/showxcorr_legacy.py +7 -7
  47. rapidtide/scripts/stupidramtricks.py +15 -17
  48. rapidtide/simFuncClasses.py +1052 -77
  49. rapidtide/simfuncfit.py +269 -69
  50. rapidtide/stats.py +540 -238
  51. rapidtide/tests/happycomp +9 -0
  52. rapidtide/tests/test_cleanregressor.py +1 -2
  53. rapidtide/tests/test_dlfiltertorch.py +627 -0
  54. rapidtide/tests/test_findmaxlag.py +24 -8
  55. rapidtide/tests/test_fullrunhappy_v1.py +0 -2
  56. rapidtide/tests/test_fullrunhappy_v2.py +0 -2
  57. rapidtide/tests/test_fullrunhappy_v3.py +11 -4
  58. rapidtide/tests/test_fullrunhappy_v4.py +10 -2
  59. rapidtide/tests/test_fullrunrapidtide_v7.py +1 -1
  60. rapidtide/tests/test_getparsers.py +11 -3
  61. rapidtide/tests/test_refinedelay.py +0 -1
  62. rapidtide/tests/test_simroundtrip.py +16 -8
  63. rapidtide/tests/test_stcorrelate.py +3 -1
  64. rapidtide/tests/utils.py +9 -8
  65. rapidtide/tidepoolTemplate.py +142 -38
  66. rapidtide/tidepoolTemplate_alt.py +165 -44
  67. rapidtide/tidepoolTemplate_big.py +189 -52
  68. rapidtide/util.py +1217 -118
  69. rapidtide/voxelData.py +684 -37
  70. rapidtide/wiener.py +136 -23
  71. rapidtide/wiener2.py +113 -7
  72. rapidtide/workflows/adjustoffset.py +105 -3
  73. rapidtide/workflows/aligntcs.py +85 -2
  74. rapidtide/workflows/applydlfilter.py +87 -10
  75. rapidtide/workflows/applyppgproc.py +540 -0
  76. rapidtide/workflows/atlasaverage.py +210 -47
  77. rapidtide/workflows/atlastool.py +100 -3
  78. rapidtide/workflows/calcSimFuncMap.py +288 -69
  79. rapidtide/workflows/calctexticc.py +201 -9
  80. rapidtide/workflows/ccorrica.py +101 -6
  81. rapidtide/workflows/cleanregressor.py +165 -31
  82. rapidtide/workflows/delayvar.py +171 -23
  83. rapidtide/workflows/diffrois.py +81 -3
  84. rapidtide/workflows/endtidalproc.py +144 -4
  85. rapidtide/workflows/fdica.py +195 -15
  86. rapidtide/workflows/filtnifti.py +70 -3
  87. rapidtide/workflows/filttc.py +74 -3
  88. rapidtide/workflows/fitSimFuncMap.py +202 -51
  89. rapidtide/workflows/fixtr.py +73 -3
  90. rapidtide/workflows/gmscalc.py +113 -3
  91. rapidtide/workflows/happy.py +801 -199
  92. rapidtide/workflows/happy2std.py +144 -12
  93. rapidtide/workflows/happy_parser.py +163 -23
  94. rapidtide/workflows/histnifti.py +118 -2
  95. rapidtide/workflows/histtc.py +84 -3
  96. rapidtide/workflows/linfitfilt.py +117 -4
  97. rapidtide/workflows/localflow.py +328 -28
  98. rapidtide/workflows/mergequality.py +79 -3
  99. rapidtide/workflows/niftidecomp.py +322 -18
  100. rapidtide/workflows/niftistats.py +174 -4
  101. rapidtide/workflows/pairproc.py +98 -4
  102. rapidtide/workflows/pairwisemergenifti.py +85 -2
  103. rapidtide/workflows/parser_funcs.py +1421 -40
  104. rapidtide/workflows/physiofreq.py +137 -11
  105. rapidtide/workflows/pixelcomp.py +207 -5
  106. rapidtide/workflows/plethquality.py +103 -21
  107. rapidtide/workflows/polyfitim.py +151 -11
  108. rapidtide/workflows/proj2flow.py +75 -2
  109. rapidtide/workflows/rankimage.py +111 -4
  110. rapidtide/workflows/rapidtide.py +368 -76
  111. rapidtide/workflows/rapidtide2std.py +98 -2
  112. rapidtide/workflows/rapidtide_parser.py +109 -9
  113. rapidtide/workflows/refineDelayMap.py +144 -33
  114. rapidtide/workflows/refineRegressor.py +675 -96
  115. rapidtide/workflows/regressfrommaps.py +161 -37
  116. rapidtide/workflows/resamplenifti.py +85 -3
  117. rapidtide/workflows/resampletc.py +91 -3
  118. rapidtide/workflows/retrolagtcs.py +99 -9
  119. rapidtide/workflows/retroregress.py +176 -26
  120. rapidtide/workflows/roisummarize.py +174 -5
  121. rapidtide/workflows/runqualitycheck.py +71 -3
  122. rapidtide/workflows/showarbcorr.py +149 -6
  123. rapidtide/workflows/showhist.py +86 -2
  124. rapidtide/workflows/showstxcorr.py +160 -3
  125. rapidtide/workflows/showtc.py +159 -3
  126. rapidtide/workflows/showxcorrx.py +190 -10
  127. rapidtide/workflows/showxy.py +185 -15
  128. rapidtide/workflows/simdata.py +264 -38
  129. rapidtide/workflows/spatialfit.py +77 -2
  130. rapidtide/workflows/spatialmi.py +250 -27
  131. rapidtide/workflows/spectrogram.py +305 -32
  132. rapidtide/workflows/synthASL.py +154 -3
  133. rapidtide/workflows/tcfrom2col.py +76 -2
  134. rapidtide/workflows/tcfrom3col.py +74 -2
  135. rapidtide/workflows/tidepool.py +2971 -130
  136. rapidtide/workflows/utils.py +19 -14
  137. rapidtide/workflows/utils_doc.py +293 -0
  138. rapidtide/workflows/variabilityizer.py +116 -3
  139. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/METADATA +10 -8
  140. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/RECORD +144 -128
  141. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/entry_points.txt +1 -0
  142. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/WHEEL +0 -0
  143. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/licenses/LICENSE +0 -0
  144. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/top_level.txt +0 -0
@@ -18,8 +18,10 @@
18
18
  #
19
19
  import argparse
20
20
  import sys
21
+ from typing import Any
21
22
 
22
23
  import numpy as np
24
+ from numpy.typing import NDArray
23
25
  from statsmodels.robust import mad
24
26
 
25
27
  import rapidtide.io as tide_io
@@ -28,43 +30,35 @@ import rapidtide.stats as tide_stats
28
30
  import rapidtide.workflows.parser_funcs as pf
29
31
 
30
32
 
31
- def summarizevoxels(thevoxels, method="mean"):
32
- theshape = thevoxels.shape
33
- if len(theshape) > 1:
34
- numtimepoints = theshape[1]
35
- else:
36
- numtimepoints = 1
33
+ def _get_parser() -> Any:
34
+ """
35
+ Construct and return an argument parser for the atlasaverage command-line tool.
37
36
 
38
- if method == "CoV":
39
- if numtimepoints > 1:
40
- regionsummary = 100.0 * np.nan_to_num(
41
- np.std(thevoxels, axis=0) / np.mean(thevoxels, axis=0)
42
- )
43
- else:
44
- regionsummary = 100.0 * np.nan_to_num(np.std(thevoxels) / np.mean(thevoxels))
45
- else:
46
- if method == "mean":
47
- themethod = np.mean
48
- elif method == "sum":
49
- themethod = np.sum
50
- elif method == "median":
51
- themethod = np.median
52
- elif method == "std":
53
- themethod = np.std
54
- elif method == "MAD":
55
- themethod = mad
56
- else:
57
- print(f"illegal summary method {method} in summarizevoxels")
58
- sys.exit()
37
+ This function builds an `argparse.ArgumentParser` object configured with all
38
+ required and optional arguments needed to run the `atlasaverage` utility. It
39
+ handles input validation for file paths and defines various options for
40
+ normalizing, summarizing, and filtering data within atlas regions.
59
41
 
60
- if numtimepoints > 1:
61
- regionsummary = np.nan_to_num(themethod(thevoxels, axis=0))
62
- else:
63
- regionsummary = np.nan_to_num(themethod(thevoxels))
64
- return regionsummary
42
+ Returns
43
+ -------
44
+ argparse.ArgumentParser
45
+ Configured argument parser object for the atlasaverage tool.
65
46
 
47
+ Notes
48
+ -----
49
+ The parser is set up with:
50
+ - Two required positional arguments: `datafile` and `templatefile`.
51
+ - One required positional argument: `outputroot`.
52
+ - Several optional arguments controlling normalization, summarization,
53
+ masking, and output formatting.
66
54
 
67
- def _get_parser():
55
+ Examples
56
+ --------
57
+ >>> parser = _get_parser()
58
+ >>> args = parser.parse_args(['data.nii', 'atlas.nii', 'output'])
59
+ >>> print(args.datafile)
60
+ 'data.nii'
61
+ """
68
62
  # get the command line parameters
69
63
  parser = argparse.ArgumentParser(
70
64
  prog="atlasaverage",
@@ -203,7 +197,160 @@ def _get_parser():
203
197
  return parser
204
198
 
205
199
 
206
- def atlasaverage(args):
200
+ def summarizevoxels(thevoxels: NDArray, method: str = "mean") -> float:
201
+ """
202
+ Summarize voxel data using specified statistical method.
203
+
204
+ Parameters
205
+ ----------
206
+ thevoxels : ndarray
207
+ Input voxel data array. Can be 1D or 2D, where 2D arrays are interpreted
208
+ as time series with shape (voxels, timepoints).
209
+ method : str, default="mean"
210
+ Summary method to apply. Options are:
211
+ - "mean": Compute mean along axis 0
212
+ - "sum": Compute sum along axis 0
213
+ - "median": Compute median along axis 0
214
+ - "std": Compute standard deviation along axis 0
215
+ - "MAD": Compute median absolute deviation along axis 0
216
+ - "CoV": Compute coefficient of variation (std/mean) along axis 0
217
+
218
+ Returns
219
+ -------
220
+ float or ndarray
221
+ Summary statistic(s) of the voxel data. Returns a scalar for 1D input
222
+ or array of statistics for 2D input along axis 0.
223
+
224
+ Notes
225
+ -----
226
+ - NaN values are converted to zero using `np.nan_to_num` before computation
227
+ - For coefficient of variation ("CoV"), the result is multiplied by 100 to
228
+ express as percentage
229
+ - When input is 1D, time dimension is treated as single timepoint
230
+ - The function handles both 1D and 2D input arrays appropriately
231
+
232
+ Examples
233
+ --------
234
+ >>> import numpy as np
235
+ >>> voxels = np.array([[1, 2, 3], [4, 5, 6]])
236
+ >>> summarizevoxels(voxels, method="mean")
237
+ array([2.5, 3.5, 4.5])
238
+
239
+ >>> summarizevoxels(voxels, method="CoV")
240
+ array([40.82482905, 33.33333333, 25. ])
241
+ """
242
+ theshape = thevoxels.shape
243
+ if len(theshape) > 1:
244
+ numtimepoints = theshape[1]
245
+ else:
246
+ numtimepoints = 1
247
+
248
+ if method == "CoV":
249
+ if numtimepoints > 1:
250
+ regionsummary = 100.0 * np.nan_to_num(
251
+ np.std(thevoxels, axis=0) / np.mean(thevoxels, axis=0)
252
+ )
253
+ else:
254
+ regionsummary = 100.0 * np.nan_to_num(np.std(thevoxels) / np.mean(thevoxels))
255
+ else:
256
+ if method == "mean":
257
+ themethod = np.mean
258
+ elif method == "sum":
259
+ themethod = np.sum
260
+ elif method == "median":
261
+ themethod = np.median
262
+ elif method == "std":
263
+ themethod = np.std
264
+ elif method == "MAD":
265
+ themethod = mad
266
+ else:
267
+ print(f"illegal summary method {method} in summarizevoxels")
268
+ sys.exit()
269
+
270
+ if numtimepoints > 1:
271
+ regionsummary = np.nan_to_num(themethod(thevoxels, axis=0))
272
+ else:
273
+ regionsummary = np.nan_to_num(themethod(thevoxels))
274
+ return regionsummary
275
+
276
+
277
+ def atlasaverage(args: Any) -> None:
278
+ """
279
+ Compute average timecourses or summary statistics for regions defined by an atlas.
280
+
281
+ This function reads fMRI data and a template (atlas) file, extracts timecourses
282
+ or summary statistics for each region in the atlas, and saves the results to
283
+ output files. It supports multiple normalization methods and can process both
284
+ 3D and 4D input data.
285
+
286
+ Parameters
287
+ ----------
288
+ args : argparse.Namespace
289
+ Arguments parsed from command line. Expected attributes include:
290
+ - datafile : str
291
+ Path to the input fMRI NIfTI file.
292
+ - templatefile : str
293
+ Path to the template NIfTI file defining regions.
294
+ - normmethod : str
295
+ Normalization method for timecourses: 'none', 'pct', 'std', 'var', 'p2p'.
296
+ - outputroot : str
297
+ Root name for output files.
298
+ - debug : bool
299
+ If True, enable debug printing and save intermediate masks.
300
+ - includespec : str or None
301
+ Specification for including voxels in analysis.
302
+ - excludespec : str or None
303
+ Specification for excluding voxels from analysis.
304
+ - extramaskname : str or None
305
+ Path to an additional mask file.
306
+ - regionlabelfile : str or None
307
+ Path to a file containing region labels.
308
+ - regionlistfile : str or None
309
+ Path to a file listing regions to include.
310
+ - summarymethod : str
311
+ Method for summarizing voxel values (e.g., 'mean', 'median').
312
+ - datalabel : str or None
313
+ Label to prepend to output summary.
314
+ - ignorezeros : bool
315
+ If True, exclude zero voxels when computing summaries.
316
+ - numpercentiles : int
317
+ Number of percentiles to compute for each region.
318
+ - headerline : bool
319
+ If True, include a header line in the summary CSV.
320
+
321
+ Returns
322
+ -------
323
+ None
324
+ This function does not return a value but writes output files to disk.
325
+
326
+ Notes
327
+ -----
328
+ For 4D data, the function computes timecourses for each region and saves them
329
+ as a TSV file. For 3D data, it computes summary statistics and saves both
330
+ a labeled NIfTI file and a CSV/TSV summary.
331
+
332
+ Examples
333
+ --------
334
+ >>> import argparse
335
+ >>> args = argparse.Namespace(
336
+ ... datafile='fmri.nii.gz',
337
+ ... templatefile='atlas.nii.gz',
338
+ ... normmethod='std',
339
+ ... outputroot='output',
340
+ ... debug=False,
341
+ ... includespec=None,
342
+ ... excludespec=None,
343
+ ... extramaskname=None,
344
+ ... regionlabelfile=None,
345
+ ... regionlistfile=None,
346
+ ... summarymethod='mean',
347
+ ... datalabel=None,
348
+ ... ignorezeros=False,
349
+ ... numpercentiles=5,
350
+ ... headerline=True
351
+ ... )
352
+ >>> atlasaverage(args)
353
+ """
207
354
  if args.normmethod == "none":
208
355
  print("will not normalize timecourses")
209
356
  elif args.normmethod == "pct":
@@ -302,14 +449,21 @@ def atlasaverage(args):
302
449
  )
303
450
 
304
451
  # get the region names
452
+ numregions = np.max(templatevoxels)
305
453
  if args.regionlabelfile is None:
306
454
  regionlabels = []
307
- numregions = np.max(templatevoxels)
308
455
  numdigits = int(np.log10(numregions)) + 1
309
456
  for regnum in range(1, numregions + 1):
310
457
  regionlabels.append(f"region_{str(regnum).zfill(numdigits)}")
311
458
  else:
312
459
  regionlabels = tide_io.readlabels(args.regionlabelfile)
460
+ if len(regionlabels) != numregions:
461
+ print(
462
+ "Error: number of labels in label file does not match the number of regions in the template."
463
+ )
464
+ sys.exit()
465
+ if args.debug:
466
+ print(f"Region labels: {regionlabels}")
313
467
 
314
468
  # decide what regions we will summarize
315
469
  if args.regionlistfile is None:
@@ -322,6 +476,8 @@ def atlasaverage(args):
322
476
  for theregion in range(numregions):
323
477
  newlabels.append(regionlabels[theregion])
324
478
  regionlabels = newlabels
479
+ if args.debug:
480
+ print(f"Region labels to use: {regionlabels}")
325
481
 
326
482
  timecourses = np.zeros((numregions, numtimepoints), dtype="float")
327
483
  print(f"{numregions=}, {regionlist=}")
@@ -380,18 +536,21 @@ def atlasaverage(args):
380
536
  else:
381
537
  print("processing 3D input file")
382
538
  outputvoxels = inputvoxels * 0.0
383
- theregnums = []
539
+ thereglabels = []
384
540
  thevals = []
385
541
  thepercentiles = []
386
- thesizes = []
542
+ theregsizes = []
387
543
  thefracs = np.linspace(0.0, 1.0, args.numpercentiles + 2, endpoint=True).tolist()
388
544
  numsubregions = len(thefracs) - 1
389
545
  segmentedatlasvoxels = inputvoxels * 0.0
546
+ if args.debug:
547
+ print(f"{len(regionlist)=}, {regionlist=}")
548
+ print(f"{len(regionlabels)=}, {regionlabels=}")
390
549
  if args.datalabel is not None:
391
- theregnums.append("Region")
550
+ thereglabels.append("Region")
392
551
  thevals.append(args.datalabel)
393
552
  for theregion in regionlist:
394
- theregnums.append(str(theregion))
553
+ thereglabels.append(regionlabels[theregion - 1])
395
554
  theregionvoxels = inputvoxels[np.where(templatevoxels * themask == theregion)]
396
555
  initnum = theregionvoxels.shape[0]
397
556
  if args.ignorezeros:
@@ -404,13 +563,15 @@ def atlasaverage(args):
404
563
  if args.debug:
405
564
  print(
406
565
  f"extracting {theregionvoxels.shape[0]} "
407
- f"non-zero voxels from region {theregion} of {numregions}{extrabit}"
566
+ f"non-zero voxels from region {theregion} of {numregions}{extrabit} "
567
+ f"({thereglabels[-1]})"
408
568
  )
409
569
  else:
410
570
  if args.debug:
411
571
  print(
412
572
  f"extracting {theregionvoxels.shape[0]} "
413
- f"voxels from region {theregion} of {numregions}"
573
+ f"voxels from region {theregion} of {numregions} "
574
+ f"({thereglabels[-1]})"
414
575
  )
415
576
  if theregionvoxels.shape[0] > 0:
416
577
  regionval = summarizevoxels(theregionvoxels, method=args.summarymethod)
@@ -426,7 +587,7 @@ def atlasaverage(args):
426
587
  ]
427
588
  outputvoxels[np.where(templatevoxels == theregion)] = regionval
428
589
  thevals.append(str(regionval))
429
- thesizes.append(str(regionsizes))
590
+ theregsizes.append(str(regionsizes))
430
591
  thepercentiles.append(regionpercentiles)
431
592
  else:
432
593
  if args.debug:
@@ -462,21 +623,23 @@ def atlasaverage(args):
462
623
  )
463
624
  if args.headerline:
464
625
  tide_io.writevec(
465
- [",".join(theregnums), ",".join(thevals)],
626
+ np.array([",".join(thereglabels), ",".join(thevals)]),
466
627
  f"{args.outputroot}_regionsummaries.csv",
467
628
  )
468
629
  else:
469
630
  tide_io.writevec(
470
- [",".join(thevals)],
631
+ np.array([",".join(thevals)]),
471
632
  f"{args.outputroot}_regionsummaries.csv",
472
633
  )
473
634
 
474
635
  outlines = []
475
636
  pctstrings = [f"{num:.0f}" for num in (np.array(thefracs) * 100.0).tolist()]
476
637
  outlines.append("Region\tVoxels\t" + "pct-" + "\tpct-".join(pctstrings))
477
- for idx, region in enumerate(theregnums):
478
- outlines.append(region + "\t" + thesizes[idx] + "\t" + "\t".join(thepercentiles[idx]))
638
+ for idx, region in enumerate(thereglabels):
639
+ outlines.append(
640
+ region + "\t" + theregsizes[idx] + "\t" + "\t".join(thepercentiles[idx])
641
+ )
479
642
  tide_io.writevec(
480
- outlines,
643
+ np.array(outlines),
481
644
  f"{args.outputroot}_regionpercentiles.tsv",
482
645
  )
@@ -20,18 +20,42 @@ import argparse
20
20
  import os
21
21
  import subprocess
22
22
  import sys
23
+ from argparse import Namespace
23
24
  from glob import glob
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
 
27
30
  import rapidtide.externaltools as tide_exttools
28
31
  import rapidtide.io as tide_io
29
32
  import rapidtide.workflows.parser_funcs as pf
30
33
 
31
34
 
32
- def _get_parser():
35
+ def _get_parser() -> Any:
33
36
  """
34
- Argument parser for atlastool
37
+ Argument parser for atlastool.
38
+
39
+ This function constructs and returns an `argparse.ArgumentParser` object configured
40
+ with all the necessary arguments for the `atlastool` utility. It supports parsing
41
+ of NIfTI atlas files, with options for transforming, splitting, masking, and
42
+ reformatting atlas data.
43
+
44
+ Returns
45
+ -------
46
+ argparse.ArgumentParser
47
+ Configured argument parser for atlastool.
48
+
49
+ Notes
50
+ -----
51
+ The parser includes both required and optional arguments for handling NIfTI files,
52
+ including support for 3D and 4D output formats, splitting regions along the midline,
53
+ applying masks, and debugging options.
54
+
55
+ Examples
56
+ --------
57
+ >>> parser = _get_parser()
58
+ >>> args = parser.parse_args()
35
59
  """
36
60
  parser = argparse.ArgumentParser(
37
61
  prog="atlastool",
@@ -156,7 +180,80 @@ def _get_parser():
156
180
  return parser
157
181
 
158
182
 
159
- def atlastool(args):
183
+ def atlastool(args: Any) -> None:
184
+ """
185
+ Process and convert atlas templates for neuroimaging analysis.
186
+
187
+ This function reads a template NIfTI file, reshapes it into a 4D array, and optionally
188
+ splits left-right regions, resamples to a target resolution, applies a mask, and saves
189
+ the processed data as a new NIfTI file. It supports both 3D and 4D input templates,
190
+ and can handle label files for region mapping.
191
+
192
+ Parameters
193
+ ----------
194
+ args : Any
195
+ An object containing command-line arguments. Expected attributes include:
196
+ - inputtemplatename : str
197
+ Path to the input NIfTI template file.
198
+ - debug : bool
199
+ If True, print debug information.
200
+ - maxval : float, optional
201
+ Maximum value to truncate template data.
202
+ - labelfile : str, optional
203
+ Path to a text file containing region labels.
204
+ - dosplit : bool
205
+ If True, split regions into left and right hemispheres.
206
+ - LtoR : bool
207
+ If True, assign left hemisphere labels first.
208
+ - targetfile : str, optional
209
+ Path to a target NIfTI file for resampling.
210
+ - xfm : str, optional
211
+ Path to transformation file for resampling.
212
+ - maskfile : str, optional
213
+ Path to a mask NIfTI file.
214
+ - maskthresh : float
215
+ Threshold for generating mask from template if no maskfile is provided.
216
+ - removeemptyregions : bool
217
+ If True, remove regions with no voxels.
218
+ - volumeperregion : bool
219
+ If True, save each region as a separate volume; otherwise, save as a
220
+ single label map.
221
+ - outputtemplatename : str
222
+ Path for the output NIfTI file.
223
+
224
+ Returns
225
+ -------
226
+ None
227
+ This function does not return a value but saves processed data to disk.
228
+
229
+ Notes
230
+ -----
231
+ - The function supports both 3D and 4D input templates.
232
+ - If `targetfile` is provided, the template is resampled using FSL or ANTs.
233
+ - If `maskfile` is not provided, a mask is generated from the template using
234
+ `maskthresh`.
235
+ - Labels from `labelfile` are used in the output if provided.
236
+
237
+ Examples
238
+ --------
239
+ >>> import argparse
240
+ >>> args = argparse.Namespace(
241
+ ... inputtemplatename='template.nii.gz',
242
+ ... debug=False,
243
+ ... maxval=None,
244
+ ... labelfile='labels.txt',
245
+ ... dosplit=True,
246
+ ... LtoR=True,
247
+ ... targetfile='target.nii.gz',
248
+ ... xfm='transform.mat',
249
+ ... maskfile=None,
250
+ ... maskthresh=0.5,
251
+ ... removeemptyregions=True,
252
+ ... volumeperregion=False,
253
+ ... outputtemplatename='output.nii.gz'
254
+ ... )
255
+ >>> atlastool(args)
256
+ """
160
257
  if args.debug:
161
258
  print(args)
162
259