rapidtide 2.9.6__py3-none-any.whl → 3.1.3__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 (405) hide show
  1. cloud/gmscalc-HCPYA +1 -1
  2. cloud/mount-and-run +2 -0
  3. cloud/rapidtide-HCPYA +3 -3
  4. rapidtide/Colortables.py +538 -38
  5. rapidtide/OrthoImageItem.py +1094 -51
  6. rapidtide/RapidtideDataset.py +1709 -114
  7. rapidtide/__init__.py +0 -8
  8. rapidtide/_version.py +4 -4
  9. rapidtide/calccoherence.py +242 -97
  10. rapidtide/calcnullsimfunc.py +240 -140
  11. rapidtide/calcsimfunc.py +314 -129
  12. rapidtide/correlate.py +1211 -389
  13. rapidtide/data/examples/src/testLD +56 -0
  14. rapidtide/data/examples/src/test_findmaxlag.py +2 -2
  15. rapidtide/data/examples/src/test_mlregressallt.py +32 -17
  16. rapidtide/data/examples/src/testalign +1 -1
  17. rapidtide/data/examples/src/testatlasaverage +35 -7
  18. rapidtide/data/examples/src/testboth +21 -0
  19. rapidtide/data/examples/src/testcifti +11 -0
  20. rapidtide/data/examples/src/testdelayvar +13 -0
  21. rapidtide/data/examples/src/testdlfilt +25 -0
  22. rapidtide/data/examples/src/testfft +35 -0
  23. rapidtide/data/examples/src/testfileorfloat +37 -0
  24. rapidtide/data/examples/src/testfmri +92 -42
  25. rapidtide/data/examples/src/testfuncs +3 -3
  26. rapidtide/data/examples/src/testglmfilt +8 -6
  27. rapidtide/data/examples/src/testhappy +84 -51
  28. rapidtide/data/examples/src/testinitdelay +19 -0
  29. rapidtide/data/examples/src/testmodels +33 -0
  30. rapidtide/data/examples/src/testnewrefine +26 -0
  31. rapidtide/data/examples/src/testnoiseamp +2 -2
  32. rapidtide/data/examples/src/testppgproc +17 -0
  33. rapidtide/data/examples/src/testrefineonly +22 -0
  34. rapidtide/data/examples/src/testretro +26 -13
  35. rapidtide/data/examples/src/testretrolagtcs +16 -0
  36. rapidtide/data/examples/src/testrolloff +11 -0
  37. rapidtide/data/examples/src/testsimdata +45 -28
  38. rapidtide/data/models/model_cnn_pytorch/loss.png +0 -0
  39. rapidtide/data/models/model_cnn_pytorch/loss.txt +1 -0
  40. rapidtide/data/models/model_cnn_pytorch/model.pth +0 -0
  41. rapidtide/data/models/model_cnn_pytorch/model_meta.json +68 -0
  42. rapidtide/data/models/model_cnn_pytorch_fulldata/loss.png +0 -0
  43. rapidtide/data/models/model_cnn_pytorch_fulldata/loss.txt +1 -0
  44. rapidtide/data/models/model_cnn_pytorch_fulldata/model.pth +0 -0
  45. rapidtide/data/models/model_cnn_pytorch_fulldata/model_meta.json +80 -0
  46. rapidtide/data/models/model_cnnbp_pytorch_fullldata/loss.png +0 -0
  47. rapidtide/data/models/model_cnnbp_pytorch_fullldata/loss.txt +1 -0
  48. rapidtide/data/models/model_cnnbp_pytorch_fullldata/model.pth +0 -0
  49. rapidtide/data/models/model_cnnbp_pytorch_fullldata/model_meta.json +138 -0
  50. rapidtide/data/models/model_cnnfft_pytorch_fulldata/loss.png +0 -0
  51. rapidtide/data/models/model_cnnfft_pytorch_fulldata/loss.txt +1 -0
  52. rapidtide/data/models/model_cnnfft_pytorch_fulldata/model.pth +0 -0
  53. rapidtide/data/models/model_cnnfft_pytorch_fulldata/model_meta.json +128 -0
  54. rapidtide/data/models/model_ppgattention_pytorch_w128_fulldata/loss.png +0 -0
  55. rapidtide/data/models/model_ppgattention_pytorch_w128_fulldata/loss.txt +1 -0
  56. rapidtide/data/models/model_ppgattention_pytorch_w128_fulldata/model.pth +0 -0
  57. rapidtide/data/models/model_ppgattention_pytorch_w128_fulldata/model_meta.json +49 -0
  58. rapidtide/data/models/model_revised_tf2/model.keras +0 -0
  59. rapidtide/data/models/{model_serdar → model_revised_tf2}/model_meta.json +1 -1
  60. rapidtide/data/models/model_serdar2_tf2/model.keras +0 -0
  61. rapidtide/data/models/{model_serdar2 → model_serdar2_tf2}/model_meta.json +1 -1
  62. rapidtide/data/models/model_serdar_tf2/model.keras +0 -0
  63. rapidtide/data/models/{model_revised → model_serdar_tf2}/model_meta.json +1 -1
  64. rapidtide/data/reference/HCP1200v2_MTT_2mm.nii.gz +0 -0
  65. rapidtide/data/reference/HCP1200v2_binmask_2mm.nii.gz +0 -0
  66. rapidtide/data/reference/HCP1200v2_csf_2mm.nii.gz +0 -0
  67. rapidtide/data/reference/HCP1200v2_gray_2mm.nii.gz +0 -0
  68. rapidtide/data/reference/HCP1200v2_graylaghist.json +7 -0
  69. rapidtide/data/reference/HCP1200v2_graylaghist.tsv.gz +0 -0
  70. rapidtide/data/reference/HCP1200v2_laghist.json +7 -0
  71. rapidtide/data/reference/HCP1200v2_laghist.tsv.gz +0 -0
  72. rapidtide/data/reference/HCP1200v2_mask_2mm.nii.gz +0 -0
  73. rapidtide/data/reference/HCP1200v2_maxcorr_2mm.nii.gz +0 -0
  74. rapidtide/data/reference/HCP1200v2_maxtime_2mm.nii.gz +0 -0
  75. rapidtide/data/reference/HCP1200v2_maxwidth_2mm.nii.gz +0 -0
  76. rapidtide/data/reference/HCP1200v2_negmask_2mm.nii.gz +0 -0
  77. rapidtide/data/reference/HCP1200v2_timepercentile_2mm.nii.gz +0 -0
  78. rapidtide/data/reference/HCP1200v2_white_2mm.nii.gz +0 -0
  79. rapidtide/data/reference/HCP1200v2_whitelaghist.json +7 -0
  80. rapidtide/data/reference/HCP1200v2_whitelaghist.tsv.gz +0 -0
  81. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1-seg2.xml +131 -0
  82. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1-seg2_regions.txt +60 -0
  83. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1-seg2_space-MNI152NLin6Asym_2mm.nii.gz +0 -0
  84. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm.nii.gz +0 -0
  85. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm_mask.nii.gz +0 -0
  86. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin6Asym_2mm_mask.nii.gz +0 -0
  87. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL2_space-MNI152NLin6Asym_2mm_mask.nii.gz +0 -0
  88. rapidtide/data/reference/MNI152_T1_1mm_Brain_FAST_seg.nii.gz +0 -0
  89. rapidtide/data/reference/MNI152_T1_1mm_Brain_Mask.nii.gz +0 -0
  90. rapidtide/data/reference/MNI152_T1_2mm_Brain_FAST_seg.nii.gz +0 -0
  91. rapidtide/data/reference/MNI152_T1_2mm_Brain_Mask.nii.gz +0 -0
  92. rapidtide/decorators.py +91 -0
  93. rapidtide/dlfilter.py +2553 -414
  94. rapidtide/dlfiltertorch.py +5201 -0
  95. rapidtide/externaltools.py +328 -13
  96. rapidtide/fMRIData_class.py +108 -92
  97. rapidtide/ffttools.py +168 -0
  98. rapidtide/filter.py +2704 -1462
  99. rapidtide/fit.py +2361 -579
  100. rapidtide/genericmultiproc.py +197 -0
  101. rapidtide/happy_supportfuncs.py +3255 -548
  102. rapidtide/helper_classes.py +587 -1116
  103. rapidtide/io.py +2569 -468
  104. rapidtide/linfitfiltpass.py +784 -0
  105. rapidtide/makelaggedtcs.py +267 -97
  106. rapidtide/maskutil.py +555 -25
  107. rapidtide/miscmath.py +835 -144
  108. rapidtide/multiproc.py +217 -44
  109. rapidtide/patchmatch.py +752 -0
  110. rapidtide/peakeval.py +32 -32
  111. rapidtide/ppgproc.py +2205 -0
  112. rapidtide/qualitycheck.py +353 -40
  113. rapidtide/refinedelay.py +854 -0
  114. rapidtide/refineregressor.py +939 -0
  115. rapidtide/resample.py +725 -204
  116. rapidtide/scripts/__init__.py +1 -0
  117. rapidtide/scripts/{adjustoffset → adjustoffset.py} +7 -2
  118. rapidtide/scripts/{aligntcs → aligntcs.py} +7 -2
  119. rapidtide/scripts/{applydlfilter → applydlfilter.py} +7 -2
  120. rapidtide/scripts/applyppgproc.py +28 -0
  121. rapidtide/scripts/{atlasaverage → atlasaverage.py} +7 -2
  122. rapidtide/scripts/{atlastool → atlastool.py} +7 -2
  123. rapidtide/scripts/{calcicc → calcicc.py} +7 -2
  124. rapidtide/scripts/{calctexticc → calctexticc.py} +7 -2
  125. rapidtide/scripts/{calcttest → calcttest.py} +7 -2
  126. rapidtide/scripts/{ccorrica → ccorrica.py} +7 -2
  127. rapidtide/scripts/delayvar.py +28 -0
  128. rapidtide/scripts/{diffrois → diffrois.py} +7 -2
  129. rapidtide/scripts/{endtidalproc → endtidalproc.py} +7 -2
  130. rapidtide/scripts/{fdica → fdica.py} +7 -2
  131. rapidtide/scripts/{filtnifti → filtnifti.py} +7 -2
  132. rapidtide/scripts/{filttc → filttc.py} +7 -2
  133. rapidtide/scripts/{fingerprint → fingerprint.py} +20 -16
  134. rapidtide/scripts/{fixtr → fixtr.py} +7 -2
  135. rapidtide/scripts/{gmscalc → gmscalc.py} +7 -2
  136. rapidtide/scripts/{happy → happy.py} +7 -2
  137. rapidtide/scripts/{happy2std → happy2std.py} +7 -2
  138. rapidtide/scripts/{happywarp → happywarp.py} +8 -4
  139. rapidtide/scripts/{histnifti → histnifti.py} +7 -2
  140. rapidtide/scripts/{histtc → histtc.py} +7 -2
  141. rapidtide/scripts/{glmfilt → linfitfilt.py} +7 -4
  142. rapidtide/scripts/{localflow → localflow.py} +7 -2
  143. rapidtide/scripts/{mergequality → mergequality.py} +7 -2
  144. rapidtide/scripts/{pairproc → pairproc.py} +7 -2
  145. rapidtide/scripts/{pairwisemergenifti → pairwisemergenifti.py} +7 -2
  146. rapidtide/scripts/{physiofreq → physiofreq.py} +7 -2
  147. rapidtide/scripts/{pixelcomp → pixelcomp.py} +7 -2
  148. rapidtide/scripts/{plethquality → plethquality.py} +7 -2
  149. rapidtide/scripts/{polyfitim → polyfitim.py} +7 -2
  150. rapidtide/scripts/{proj2flow → proj2flow.py} +7 -2
  151. rapidtide/scripts/{rankimage → rankimage.py} +7 -2
  152. rapidtide/scripts/{rapidtide → rapidtide.py} +7 -2
  153. rapidtide/scripts/{rapidtide2std → rapidtide2std.py} +7 -2
  154. rapidtide/scripts/{resamplenifti → resamplenifti.py} +7 -2
  155. rapidtide/scripts/{resampletc → resampletc.py} +7 -2
  156. rapidtide/scripts/retrolagtcs.py +28 -0
  157. rapidtide/scripts/retroregress.py +28 -0
  158. rapidtide/scripts/{roisummarize → roisummarize.py} +7 -2
  159. rapidtide/scripts/{runqualitycheck → runqualitycheck.py} +7 -2
  160. rapidtide/scripts/{showarbcorr → showarbcorr.py} +7 -2
  161. rapidtide/scripts/{showhist → showhist.py} +7 -2
  162. rapidtide/scripts/{showstxcorr → showstxcorr.py} +7 -2
  163. rapidtide/scripts/{showtc → showtc.py} +7 -2
  164. rapidtide/scripts/{showxcorr_legacy → showxcorr_legacy.py} +8 -8
  165. rapidtide/scripts/{showxcorrx → showxcorrx.py} +7 -2
  166. rapidtide/scripts/{showxy → showxy.py} +7 -2
  167. rapidtide/scripts/{simdata → simdata.py} +7 -2
  168. rapidtide/scripts/{spatialdecomp → spatialdecomp.py} +7 -2
  169. rapidtide/scripts/{spatialfit → spatialfit.py} +7 -2
  170. rapidtide/scripts/{spatialmi → spatialmi.py} +7 -2
  171. rapidtide/scripts/{spectrogram → spectrogram.py} +7 -2
  172. rapidtide/scripts/stupidramtricks.py +238 -0
  173. rapidtide/scripts/{synthASL → synthASL.py} +7 -2
  174. rapidtide/scripts/{tcfrom2col → tcfrom2col.py} +7 -2
  175. rapidtide/scripts/{tcfrom3col → tcfrom3col.py} +7 -2
  176. rapidtide/scripts/{temporaldecomp → temporaldecomp.py} +7 -2
  177. rapidtide/scripts/{testhrv → testhrv.py} +1 -1
  178. rapidtide/scripts/{threeD → threeD.py} +7 -2
  179. rapidtide/scripts/{tidepool → tidepool.py} +7 -2
  180. rapidtide/scripts/{variabilityizer → variabilityizer.py} +7 -2
  181. rapidtide/simFuncClasses.py +2113 -0
  182. rapidtide/simfuncfit.py +312 -108
  183. rapidtide/stats.py +579 -247
  184. rapidtide/tests/.coveragerc +27 -6
  185. rapidtide-2.9.6.data/scripts/fdica → rapidtide/tests/cleanposttest +4 -6
  186. rapidtide/tests/happycomp +9 -0
  187. rapidtide/tests/resethappytargets +1 -1
  188. rapidtide/tests/resetrapidtidetargets +1 -1
  189. rapidtide/tests/resettargets +1 -1
  190. rapidtide/tests/runlocaltest +3 -3
  191. rapidtide/tests/showkernels +1 -1
  192. rapidtide/tests/test_aliasedcorrelate.py +4 -4
  193. rapidtide/tests/test_aligntcs.py +1 -1
  194. rapidtide/tests/test_calcicc.py +1 -1
  195. rapidtide/tests/test_cleanregressor.py +184 -0
  196. rapidtide/tests/test_congrid.py +70 -81
  197. rapidtide/tests/test_correlate.py +1 -1
  198. rapidtide/tests/test_corrpass.py +4 -4
  199. rapidtide/tests/test_delayestimation.py +54 -59
  200. rapidtide/tests/test_dlfiltertorch.py +437 -0
  201. rapidtide/tests/test_doresample.py +2 -2
  202. rapidtide/tests/test_externaltools.py +69 -0
  203. rapidtide/tests/test_fastresampler.py +9 -5
  204. rapidtide/tests/test_filter.py +96 -57
  205. rapidtide/tests/test_findmaxlag.py +50 -19
  206. rapidtide/tests/test_fullrunhappy_v1.py +15 -10
  207. rapidtide/tests/test_fullrunhappy_v2.py +19 -13
  208. rapidtide/tests/test_fullrunhappy_v3.py +28 -13
  209. rapidtide/tests/test_fullrunhappy_v4.py +30 -11
  210. rapidtide/tests/test_fullrunhappy_v5.py +62 -0
  211. rapidtide/tests/test_fullrunrapidtide_v1.py +61 -7
  212. rapidtide/tests/test_fullrunrapidtide_v2.py +26 -14
  213. rapidtide/tests/test_fullrunrapidtide_v3.py +28 -8
  214. rapidtide/tests/test_fullrunrapidtide_v4.py +16 -8
  215. rapidtide/tests/test_fullrunrapidtide_v5.py +15 -6
  216. rapidtide/tests/test_fullrunrapidtide_v6.py +142 -0
  217. rapidtide/tests/test_fullrunrapidtide_v7.py +114 -0
  218. rapidtide/tests/test_fullrunrapidtide_v8.py +66 -0
  219. rapidtide/tests/test_getparsers.py +158 -0
  220. rapidtide/tests/test_io.py +59 -18
  221. rapidtide/tests/{test_glmpass.py → test_linfitfiltpass.py} +10 -10
  222. rapidtide/tests/test_mi.py +1 -1
  223. rapidtide/tests/test_miscmath.py +1 -1
  224. rapidtide/tests/test_motionregress.py +5 -5
  225. rapidtide/tests/test_nullcorr.py +6 -9
  226. rapidtide/tests/test_padvec.py +216 -0
  227. rapidtide/tests/test_parserfuncs.py +101 -0
  228. rapidtide/tests/test_phaseanalysis.py +1 -1
  229. rapidtide/tests/test_rapidtideparser.py +59 -53
  230. rapidtide/tests/test_refinedelay.py +296 -0
  231. rapidtide/tests/test_runmisc.py +5 -5
  232. rapidtide/tests/test_sharedmem.py +60 -0
  233. rapidtide/tests/test_simroundtrip.py +132 -0
  234. rapidtide/tests/test_simulate.py +1 -1
  235. rapidtide/tests/test_stcorrelate.py +4 -2
  236. rapidtide/tests/test_timeshift.py +2 -2
  237. rapidtide/tests/test_valtoindex.py +1 -1
  238. rapidtide/tests/test_zRapidtideDataset.py +5 -3
  239. rapidtide/tests/utils.py +10 -9
  240. rapidtide/tidepoolTemplate.py +88 -70
  241. rapidtide/tidepoolTemplate.ui +60 -46
  242. rapidtide/tidepoolTemplate_alt.py +88 -53
  243. rapidtide/tidepoolTemplate_alt.ui +62 -52
  244. rapidtide/tidepoolTemplate_alt_qt6.py +921 -0
  245. rapidtide/tidepoolTemplate_big.py +1125 -0
  246. rapidtide/tidepoolTemplate_big.ui +2386 -0
  247. rapidtide/tidepoolTemplate_big_qt6.py +1129 -0
  248. rapidtide/tidepoolTemplate_qt6.py +793 -0
  249. rapidtide/util.py +1389 -148
  250. rapidtide/voxelData.py +1048 -0
  251. rapidtide/wiener.py +138 -25
  252. rapidtide/wiener2.py +114 -8
  253. rapidtide/workflows/adjustoffset.py +107 -5
  254. rapidtide/workflows/aligntcs.py +86 -3
  255. rapidtide/workflows/applydlfilter.py +231 -89
  256. rapidtide/workflows/applyppgproc.py +540 -0
  257. rapidtide/workflows/atlasaverage.py +309 -48
  258. rapidtide/workflows/atlastool.py +130 -9
  259. rapidtide/workflows/calcSimFuncMap.py +490 -0
  260. rapidtide/workflows/calctexticc.py +202 -10
  261. rapidtide/workflows/ccorrica.py +123 -15
  262. rapidtide/workflows/cleanregressor.py +415 -0
  263. rapidtide/workflows/delayvar.py +1268 -0
  264. rapidtide/workflows/diffrois.py +84 -6
  265. rapidtide/workflows/endtidalproc.py +149 -9
  266. rapidtide/workflows/fdica.py +197 -17
  267. rapidtide/workflows/filtnifti.py +71 -4
  268. rapidtide/workflows/filttc.py +76 -5
  269. rapidtide/workflows/fitSimFuncMap.py +578 -0
  270. rapidtide/workflows/fixtr.py +74 -4
  271. rapidtide/workflows/gmscalc.py +116 -6
  272. rapidtide/workflows/happy.py +1242 -480
  273. rapidtide/workflows/happy2std.py +145 -13
  274. rapidtide/workflows/happy_parser.py +277 -59
  275. rapidtide/workflows/histnifti.py +120 -4
  276. rapidtide/workflows/histtc.py +85 -4
  277. rapidtide/workflows/{glmfilt.py → linfitfilt.py} +128 -14
  278. rapidtide/workflows/localflow.py +329 -29
  279. rapidtide/workflows/mergequality.py +80 -4
  280. rapidtide/workflows/niftidecomp.py +323 -19
  281. rapidtide/workflows/niftistats.py +178 -8
  282. rapidtide/workflows/pairproc.py +99 -5
  283. rapidtide/workflows/pairwisemergenifti.py +86 -3
  284. rapidtide/workflows/parser_funcs.py +1488 -56
  285. rapidtide/workflows/physiofreq.py +139 -12
  286. rapidtide/workflows/pixelcomp.py +211 -9
  287. rapidtide/workflows/plethquality.py +105 -23
  288. rapidtide/workflows/polyfitim.py +159 -19
  289. rapidtide/workflows/proj2flow.py +76 -3
  290. rapidtide/workflows/rankimage.py +115 -8
  291. rapidtide/workflows/rapidtide.py +1785 -1858
  292. rapidtide/workflows/rapidtide2std.py +101 -3
  293. rapidtide/workflows/rapidtide_parser.py +590 -389
  294. rapidtide/workflows/refineDelayMap.py +249 -0
  295. rapidtide/workflows/refineRegressor.py +1215 -0
  296. rapidtide/workflows/regressfrommaps.py +308 -0
  297. rapidtide/workflows/resamplenifti.py +86 -4
  298. rapidtide/workflows/resampletc.py +92 -4
  299. rapidtide/workflows/retrolagtcs.py +442 -0
  300. rapidtide/workflows/retroregress.py +1501 -0
  301. rapidtide/workflows/roisummarize.py +176 -7
  302. rapidtide/workflows/runqualitycheck.py +72 -7
  303. rapidtide/workflows/showarbcorr.py +172 -16
  304. rapidtide/workflows/showhist.py +87 -3
  305. rapidtide/workflows/showstxcorr.py +161 -4
  306. rapidtide/workflows/showtc.py +172 -10
  307. rapidtide/workflows/showxcorrx.py +250 -62
  308. rapidtide/workflows/showxy.py +186 -16
  309. rapidtide/workflows/simdata.py +418 -112
  310. rapidtide/workflows/spatialfit.py +83 -8
  311. rapidtide/workflows/spatialmi.py +252 -29
  312. rapidtide/workflows/spectrogram.py +306 -33
  313. rapidtide/workflows/synthASL.py +157 -6
  314. rapidtide/workflows/tcfrom2col.py +77 -3
  315. rapidtide/workflows/tcfrom3col.py +75 -3
  316. rapidtide/workflows/tidepool.py +3829 -666
  317. rapidtide/workflows/utils.py +45 -19
  318. rapidtide/workflows/utils_doc.py +293 -0
  319. rapidtide/workflows/variabilityizer.py +118 -5
  320. {rapidtide-2.9.6.dist-info → rapidtide-3.1.3.dist-info}/METADATA +30 -223
  321. rapidtide-3.1.3.dist-info/RECORD +393 -0
  322. {rapidtide-2.9.6.dist-info → rapidtide-3.1.3.dist-info}/WHEEL +1 -1
  323. rapidtide-3.1.3.dist-info/entry_points.txt +65 -0
  324. rapidtide-3.1.3.dist-info/top_level.txt +2 -0
  325. rapidtide/calcandfitcorrpairs.py +0 -262
  326. rapidtide/data/examples/src/testoutputsize +0 -45
  327. rapidtide/data/models/model_revised/model.h5 +0 -0
  328. rapidtide/data/models/model_serdar/model.h5 +0 -0
  329. rapidtide/data/models/model_serdar2/model.h5 +0 -0
  330. rapidtide/data/reference/ASPECTS_nlin_asym_09c_2mm.nii.gz +0 -0
  331. rapidtide/data/reference/ASPECTS_nlin_asym_09c_2mm_mask.nii.gz +0 -0
  332. rapidtide/data/reference/ATTbasedFlowTerritories_split_nlin_asym_09c_2mm.nii.gz +0 -0
  333. rapidtide/data/reference/ATTbasedFlowTerritories_split_nlin_asym_09c_2mm_mask.nii.gz +0 -0
  334. rapidtide/data/reference/HCP1200_binmask_2mm_2009c_asym.nii.gz +0 -0
  335. rapidtide/data/reference/HCP1200_lag_2mm_2009c_asym.nii.gz +0 -0
  336. rapidtide/data/reference/HCP1200_mask_2mm_2009c_asym.nii.gz +0 -0
  337. rapidtide/data/reference/HCP1200_negmask_2mm_2009c_asym.nii.gz +0 -0
  338. rapidtide/data/reference/HCP1200_sigma_2mm_2009c_asym.nii.gz +0 -0
  339. rapidtide/data/reference/HCP1200_strength_2mm_2009c_asym.nii.gz +0 -0
  340. rapidtide/glmpass.py +0 -434
  341. rapidtide/refine_factored.py +0 -641
  342. rapidtide/scripts/retroglm +0 -23
  343. rapidtide/workflows/glmfrommaps.py +0 -202
  344. rapidtide/workflows/retroglm.py +0 -643
  345. rapidtide-2.9.6.data/scripts/adjustoffset +0 -23
  346. rapidtide-2.9.6.data/scripts/aligntcs +0 -23
  347. rapidtide-2.9.6.data/scripts/applydlfilter +0 -23
  348. rapidtide-2.9.6.data/scripts/atlasaverage +0 -23
  349. rapidtide-2.9.6.data/scripts/atlastool +0 -23
  350. rapidtide-2.9.6.data/scripts/calcicc +0 -22
  351. rapidtide-2.9.6.data/scripts/calctexticc +0 -23
  352. rapidtide-2.9.6.data/scripts/calcttest +0 -22
  353. rapidtide-2.9.6.data/scripts/ccorrica +0 -23
  354. rapidtide-2.9.6.data/scripts/diffrois +0 -23
  355. rapidtide-2.9.6.data/scripts/endtidalproc +0 -23
  356. rapidtide-2.9.6.data/scripts/filtnifti +0 -23
  357. rapidtide-2.9.6.data/scripts/filttc +0 -23
  358. rapidtide-2.9.6.data/scripts/fingerprint +0 -593
  359. rapidtide-2.9.6.data/scripts/fixtr +0 -23
  360. rapidtide-2.9.6.data/scripts/glmfilt +0 -24
  361. rapidtide-2.9.6.data/scripts/gmscalc +0 -22
  362. rapidtide-2.9.6.data/scripts/happy +0 -25
  363. rapidtide-2.9.6.data/scripts/happy2std +0 -23
  364. rapidtide-2.9.6.data/scripts/happywarp +0 -350
  365. rapidtide-2.9.6.data/scripts/histnifti +0 -23
  366. rapidtide-2.9.6.data/scripts/histtc +0 -23
  367. rapidtide-2.9.6.data/scripts/localflow +0 -23
  368. rapidtide-2.9.6.data/scripts/mergequality +0 -23
  369. rapidtide-2.9.6.data/scripts/pairproc +0 -23
  370. rapidtide-2.9.6.data/scripts/pairwisemergenifti +0 -23
  371. rapidtide-2.9.6.data/scripts/physiofreq +0 -23
  372. rapidtide-2.9.6.data/scripts/pixelcomp +0 -23
  373. rapidtide-2.9.6.data/scripts/plethquality +0 -23
  374. rapidtide-2.9.6.data/scripts/polyfitim +0 -23
  375. rapidtide-2.9.6.data/scripts/proj2flow +0 -23
  376. rapidtide-2.9.6.data/scripts/rankimage +0 -23
  377. rapidtide-2.9.6.data/scripts/rapidtide +0 -23
  378. rapidtide-2.9.6.data/scripts/rapidtide2std +0 -23
  379. rapidtide-2.9.6.data/scripts/resamplenifti +0 -23
  380. rapidtide-2.9.6.data/scripts/resampletc +0 -23
  381. rapidtide-2.9.6.data/scripts/retroglm +0 -23
  382. rapidtide-2.9.6.data/scripts/roisummarize +0 -23
  383. rapidtide-2.9.6.data/scripts/runqualitycheck +0 -23
  384. rapidtide-2.9.6.data/scripts/showarbcorr +0 -23
  385. rapidtide-2.9.6.data/scripts/showhist +0 -23
  386. rapidtide-2.9.6.data/scripts/showstxcorr +0 -23
  387. rapidtide-2.9.6.data/scripts/showtc +0 -23
  388. rapidtide-2.9.6.data/scripts/showxcorr_legacy +0 -536
  389. rapidtide-2.9.6.data/scripts/showxcorrx +0 -23
  390. rapidtide-2.9.6.data/scripts/showxy +0 -23
  391. rapidtide-2.9.6.data/scripts/simdata +0 -23
  392. rapidtide-2.9.6.data/scripts/spatialdecomp +0 -23
  393. rapidtide-2.9.6.data/scripts/spatialfit +0 -23
  394. rapidtide-2.9.6.data/scripts/spatialmi +0 -23
  395. rapidtide-2.9.6.data/scripts/spectrogram +0 -23
  396. rapidtide-2.9.6.data/scripts/synthASL +0 -23
  397. rapidtide-2.9.6.data/scripts/tcfrom2col +0 -23
  398. rapidtide-2.9.6.data/scripts/tcfrom3col +0 -23
  399. rapidtide-2.9.6.data/scripts/temporaldecomp +0 -23
  400. rapidtide-2.9.6.data/scripts/threeD +0 -236
  401. rapidtide-2.9.6.data/scripts/tidepool +0 -23
  402. rapidtide-2.9.6.data/scripts/variabilityizer +0 -23
  403. rapidtide-2.9.6.dist-info/RECORD +0 -359
  404. rapidtide-2.9.6.dist-info/top_level.txt +0 -86
  405. {rapidtide-2.9.6.dist-info → rapidtide-3.1.3.dist-info/licenses}/LICENSE +0 -0
rapidtide/voxelData.py ADDED
@@ -0,0 +1,1048 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ #
4
+ # Copyright 2016-2025 Blaise Frederick
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ #
19
+ import copy
20
+ from typing import Any
21
+
22
+ import numpy as np
23
+ from numpy.typing import NDArray
24
+ from tqdm import tqdm
25
+
26
+ import rapidtide.filter as tide_filt
27
+ import rapidtide.io as tide_io
28
+ import rapidtide.util as tide_util
29
+
30
+
31
+ class dataVolume:
32
+ xsize = None
33
+ ysize = None
34
+ numslices = None
35
+ numspatiallocs = None
36
+ timepoints = None
37
+ dtype = None
38
+ dimensions = None
39
+ data = None
40
+ data_shm = None
41
+ thepid = None
42
+
43
+ def __init__(
44
+ self,
45
+ shape: tuple,
46
+ shared: bool = False,
47
+ dtype: type = np.float64,
48
+ thepid: int = 0,
49
+ ) -> None:
50
+ """
51
+ Initialize a data container with specified shape and properties.
52
+
53
+ Parameters
54
+ ----------
55
+ shape : tuple
56
+ The shape of the data array. Must be either 3D (x, y, z) or 4D (x, y, z, t).
57
+ shared : bool, optional
58
+ Whether to create a shared memory array, by default False
59
+ dtype : type, optional
60
+ Data type of the array, by default np.float64
61
+ thepid : int, optional
62
+ Process ID for naming shared memory, by default 0
63
+
64
+ Returns
65
+ -------
66
+ None
67
+ This method initializes the object in-place and does not return a value.
68
+
69
+ Notes
70
+ -----
71
+ The function automatically determines the number of dimensions based on the shape tuple length.
72
+ For 3D shapes, timepoints is set to 1. For 4D shapes, timepoints is set to the fourth dimension.
73
+ Invalid shapes will trigger a print statement with the error message.
74
+
75
+ Examples
76
+ --------
77
+ >>> data_container = DataContainer((64, 64, 32))
78
+ >>> data_container = DataContainer((64, 64, 32, 10), shared=True, dtype=np.float32)
79
+ """
80
+ if len(shape) == 3:
81
+ self.xsize = int(shape[0])
82
+ self.ysize = int(shape[1])
83
+ self.numslices = int(shape[2])
84
+ self.timepoints = 1
85
+ self.dimensions = 3
86
+ elif len(shape) == 4:
87
+ self.xsize = int(shape[0])
88
+ self.ysize = int(shape[1])
89
+ self.numslices = int(shape[2])
90
+ self.timepoints = int(shape[3])
91
+ self.dimensions = 4
92
+ else:
93
+ print(f"illegal shape: {shape}")
94
+ self.numspatiallocs = self.xsize * self.ysize * self.numslices
95
+ self.dtype = dtype
96
+ self.data, self.data_shm = tide_util.allocarray(
97
+ shape, self.dtype, shared=shared, name=f"filtereddata_{thepid}"
98
+ )
99
+
100
+ def byvol(self) -> NDArray:
101
+ """
102
+ Return the data array.
103
+
104
+ Returns
105
+ -------
106
+ NDArray
107
+ The underlying data array stored in the object.
108
+
109
+ Notes
110
+ -----
111
+ This method provides direct access to the internal data array.
112
+ The returned array is a view of the original data and modifications
113
+ to it will affect the original object.
114
+
115
+ Examples
116
+ --------
117
+ >>> obj = MyClass()
118
+ >>> data = obj.byvol()
119
+ >>> print(data.shape)
120
+ (100, 50)
121
+ """
122
+ return self.data
123
+
124
+ def byslice(self) -> NDArray:
125
+ """
126
+ Reshape data by slices for 2D processing.
127
+
128
+ Reshapes the internal data array to facilitate 2D processing operations
129
+ by combining the x and y dimensions while preserving slice information.
130
+
131
+ Parameters
132
+ ----------
133
+ self : object
134
+ The instance containing the data to be reshaped. Expected to have
135
+ attributes: dimensions (int), data (array-like), xsize (int),
136
+ ysize (int), and numslices (int).
137
+
138
+ Returns
139
+ -------
140
+ NDArray
141
+ Reshaped array with dimensions (xsize * ysize, -1). For 3D data,
142
+ the shape becomes (xsize * ysize, -1). For 4D data, the shape becomes
143
+ (xsize * ysize, numslices, -1).
144
+
145
+ Notes
146
+ -----
147
+ This function is useful for preparing data for 2D processing operations
148
+ where the spatial dimensions need to be flattened while maintaining
149
+ temporal or spectral slice information.
150
+
151
+ Examples
152
+ --------
153
+ >>> # For 3D data with shape (100, 100, 50)
154
+ >>> result = obj.byslice()
155
+ >>> # Result shape: (10000, 50)
156
+ >>>
157
+ >>> # For 4D data with shape (50, 50, 10, 20)
158
+ >>> result = obj.byslice()
159
+ >>> # Result shape: (2500, 10, 20)
160
+ """
161
+ if self.dimensions == 3:
162
+ return self.data.reshape(self.xsize * self.ysize, -1)
163
+ else:
164
+ return self.data.reshape(self.xsize * self.ysize, self.numslices, -1)
165
+
166
+ def byvoxel(self) -> NDArray:
167
+ """
168
+ Reshape data to voxel format based on dimensions.
169
+
170
+ Returns
171
+ -------
172
+ NDArray
173
+ Reshaped array where each row represents a voxel. For 3D data, returns
174
+ a 1D array of shape (numspatiallocs,). For non-3D data, returns a 2D array
175
+ of shape (numspatiallocs, -1).
176
+
177
+ Notes
178
+ -----
179
+ This method reshapes the internal ``data`` attribute to a voxel-based
180
+ structure. The ``numspatiallocs`` attribute determines the first dimension
181
+ of the output array, while the second dimension is determined by the
182
+ remaining data dimensions.
183
+
184
+ Examples
185
+ --------
186
+ >>> # For 3D data
187
+ >>> result = obj.byvoxel()
188
+ >>> print(result.shape)
189
+ (1000,) # where 1000 = numspatiallocs
190
+
191
+ >>> # For 2D data
192
+ >>> result = obj.byvoxel()
193
+ >>> print(result.shape)
194
+ (1000, 5) # where 1000 = numspatiallocs, 5 = remaining dimensions
195
+ """
196
+ if self.dimensions == 3:
197
+ return self.data.reshape(self.numspatiallocs)
198
+ else:
199
+ return self.data.reshape(self.numspatiallocs, -1)
200
+
201
+ def destroy(self) -> None:
202
+ """
203
+ Clean up and destroy the object's resources.
204
+
205
+ This method releases the internal data storage and performs cleanup of
206
+ shared memory resources if they exist.
207
+
208
+ Returns
209
+ -------
210
+ None
211
+ This method does not return any value.
212
+
213
+ Notes
214
+ -----
215
+ The method first deletes the internal `data` attribute, then checks if
216
+ `data_shm` (shared memory) exists and performs cleanup if it does.
217
+
218
+ Examples
219
+ --------
220
+ >>> obj = MyClass()
221
+ >>> obj.destroy()
222
+ >>> # Object resources have been cleaned up
223
+ """
224
+ del self.data
225
+ if self.data_shm is not None:
226
+ tide_util.cleanup_shm(self.data_shm)
227
+
228
+
229
+ class VoxelData:
230
+ nim = None
231
+ nim_data = None
232
+ nim_hdr = None
233
+ nim_affine = None
234
+ theshape = None
235
+ xsize = None
236
+ ysize = None
237
+ numslices = None
238
+ timepoints = None
239
+ dimensions = None
240
+ realtimepoints = None
241
+ xdim = None
242
+ ydim = None
243
+ slicethickness = None
244
+ timestep = None
245
+ thesizes = None
246
+ thedims = None
247
+ numslicelocs = None
248
+ numspatiallocs = None
249
+ nativespaceshape = None
250
+ nativefmrishape = None
251
+ validvoxels = None
252
+ cifti_hdr = None
253
+ filetype = None
254
+ resident = False
255
+
256
+ def __init__(
257
+ self,
258
+ filename: str,
259
+ timestep: float = 0.0,
260
+ validstart: int | None = None,
261
+ validend: int | None = None,
262
+ ) -> None:
263
+ """
264
+ Initialize the object with filename and optional data reading parameters.
265
+
266
+ Parameters
267
+ ----------
268
+ filename : str
269
+ Path to the data file to be read.
270
+ timestep : float, optional
271
+ Time step for data processing, default is 0.0.
272
+ validstart : int, optional
273
+ Starting index for valid data range, default is None (all data).
274
+ validend : int, optional
275
+ Ending index for valid data range, default is None (all data).
276
+
277
+ Returns
278
+ -------
279
+ None
280
+ This method initializes the object and reads data but does not return any value.
281
+
282
+ Notes
283
+ -----
284
+ This method calls `readdata()` internally with the provided parameters to load
285
+ and process the data from the specified file.
286
+
287
+ Examples
288
+ --------
289
+ >>> obj = MyClass("data.txt")
290
+ >>> obj = MyClass("data.txt", timestep=0.1, validstart=10, validend=100)
291
+ """
292
+
293
+ self.filename = filename
294
+ self.readdata(timestep, validstart, validend)
295
+
296
+ def readdata(self, timestep: float, validstart: int | None, validend: int | None) -> None:
297
+ """
298
+ Load and process data from a file based on its type (NIfTI, CIFTI, or text).
299
+
300
+ This function loads data using `self.load()` and determines the file type
301
+ (NIfTI, CIFTI, or text) to set appropriate attributes such as dimensions,
302
+ timepoints, and spatial locations. It also handles time-related parameters
303
+ like `timestep` and `toffset`, and sets valid time ranges.
304
+
305
+ Parameters
306
+ ----------
307
+ timestep : float
308
+ The time step size (in seconds) for the data. If <= 0.0, the function
309
+ will attempt to infer it from the file metadata (except for text files,
310
+ which require this to be explicitly set).
311
+ validstart : int, optional
312
+ The starting index of the valid time range. If None, defaults to the
313
+ beginning of the data.
314
+ validend : int, optional
315
+ The ending index of the valid time range. If None, defaults to the end
316
+ of the data.
317
+
318
+ Returns
319
+ -------
320
+ None
321
+ This function does not return a value but updates the instance attributes
322
+ of `self` based on the loaded data and parameters.
323
+
324
+ Notes
325
+ -----
326
+ - For text files, `timestep` must be provided explicitly; otherwise, a
327
+ `ValueError` is raised.
328
+ - For CIFTI files, the `timestep` is hardcoded to 0.72 seconds as a temporary
329
+ workaround until full XML parsing is implemented.
330
+ - The function sets various internal attributes such as `xsize`, `ysize`,
331
+ `numslices`, `timepoints`, `numspatiallocs`, and `nativespaceshape`
332
+ depending on the file type.
333
+
334
+ Examples
335
+ --------
336
+ >>> readdata(timestep=1.0, validstart=0, validend=100)
337
+ # Loads data with a 1-second timestep and valid time range from 0 to 100.
338
+
339
+ >>> readdata(timestep=0.0, validstart=None, validend=None)
340
+ # Loads data and infers timestep from file metadata (if not text).
341
+ """
342
+ # load the data
343
+ self.load()
344
+
345
+ if tide_io.checkiftext(self.filename):
346
+ self.filetype = "text"
347
+ self.nim_hdr = None
348
+ self.nim_affine = None
349
+ self.theshape = np.shape(self.nim_data)
350
+ self.xsize = self.theshape[0]
351
+ self.ysize = 1
352
+ self.numslices = 1
353
+ self.numslicelocs = None
354
+ self.timepoints = int(self.theshape[1])
355
+ self.thesizes = [0, int(self.xsize), 1, 1, int(self.timepoints)]
356
+ self.toffset = 0.0
357
+ self.numspatiallocs = int(self.xsize)
358
+ self.nativespaceshape = self.xsize
359
+ self.cifti_hdr = None
360
+ else:
361
+ if tide_io.checkifcifti(self.filename):
362
+ self.filetype = "cifti"
363
+ self.nim_affine = None
364
+ self.numslicelocs = None
365
+ self.timepoints = int(self.nim_data.shape[1])
366
+ self.numspatiallocs = self.nim_data.shape[0]
367
+ self.nativespaceshape = (1, 1, 1, 1, self.numspatiallocs)
368
+ else:
369
+ self.filetype = "nifti"
370
+ self.nim_affine = self.nim.affine
371
+ self.xsize, self.ysize, self.numslices, self.timepoints = tide_io.parseniftidims(
372
+ self.thedims
373
+ )
374
+ if self.timepoints == 1:
375
+ self.dimensions = 3
376
+ else:
377
+ self.dimensions = 4
378
+ self.numslicelocs = int(self.xsize) * int(self.ysize)
379
+ self.numspatiallocs = int(self.xsize) * int(self.ysize) * int(self.numslices)
380
+ self.cifti_hdr = None
381
+ self.nativespaceshape = (self.xsize, self.ysize, self.numslices)
382
+ self.xdim, self.ydim, self.slicethickness, dummy = tide_io.parseniftisizes(
383
+ self.thesizes
384
+ )
385
+
386
+ # correct some fields if necessary
387
+ if self.filetype == "cifti":
388
+ self.timestep = 0.72 # this is wrong and is a hack until I can parse CIFTI XML
389
+ self.toffset = 0.0
390
+ else:
391
+ if self.filetype == "text":
392
+ if timestep <= 0.0:
393
+ raise ValueError(
394
+ "for text file data input, you must use the -t option to set the timestep"
395
+ )
396
+ else:
397
+ if self.nim_hdr.get_xyzt_units()[1] == "msec":
398
+ self.timestep = self.thesizes[4] / 1000.0
399
+ self.toffset = self.nim_hdr["toffset"] / 1000.0
400
+ else:
401
+ self.timestep = self.thesizes[4]
402
+ self.toffset = self.nim_hdr["toffset"]
403
+ if timestep > 0.0:
404
+ self.timestep = timestep
405
+
406
+ self.setvalidtimes(validstart, validend)
407
+ self.resident = True
408
+
409
+ def copyheader(
410
+ self,
411
+ numtimepoints: int | None = None,
412
+ tr: float | None = None,
413
+ toffset: float | None = None,
414
+ ) -> Any | None:
415
+ """
416
+ Copy and modify header information for neuroimaging files.
417
+
418
+ This method creates a deep copy of the current header and modifies specific
419
+ dimensions and parameters based on the file type (CIFTI or other formats).
420
+ For text files, returns None immediately. For CIFTI files, modifies time and
421
+ space dimensions. For other file types, updates time dimensions and related
422
+ parameters.
423
+
424
+ Parameters
425
+ ----------
426
+ numtimepoints : int, optional
427
+ Number of time points to set in the header. If None, time dimension
428
+ remains unchanged for non-CIFTI files.
429
+ tr : float, optional
430
+ Repetition time (TR) to set in the header. If None, TR remains unchanged.
431
+ toffset : float, optional
432
+ Time offset to set in the header. If None, time offset remains unchanged.
433
+
434
+ Returns
435
+ -------
436
+ dict or None
437
+ Modified header dictionary for non-text files, or None for text files.
438
+ Returns None if the file type is "text".
439
+
440
+ Notes
441
+ -----
442
+ For CIFTI files:
443
+ - Time dimension is updated to numtimepoints
444
+ - Space dimension is set to self.numspatiallocs
445
+ For other file types:
446
+ - Time dimension is updated to numtimepoints (index 4)
447
+ - Dimension index 0 is updated based on numtimepoints (4 for >1, 3 for 1)
448
+ - TR is set in pixdim[4] if provided
449
+ - Time offset is set in toffset if provided
450
+
451
+ Examples
452
+ --------
453
+ >>> header = obj.copyheader(numtimepoints=100, tr=2.0)
454
+ >>> header = obj.copyheader(toffset=-5.0)
455
+ >>> header = obj.copyheader()
456
+ """
457
+ if self.filetype == "text":
458
+ return None
459
+ else:
460
+ thisheader = copy.deepcopy(self.nim_hdr)
461
+ if self.filetype == "cifti":
462
+ timeindex = thisheader["dim"][0] - 1
463
+ spaceindex = thisheader["dim"][0]
464
+ thisheader["dim"][timeindex] = numtimepoints
465
+ thisheader["dim"][spaceindex] = self.numspatiallocs
466
+ else:
467
+ if numtimepoints is not None:
468
+ thisheader["dim"][4] = numtimepoints
469
+ if numtimepoints > 1:
470
+ thisheader["dim"][0] = 4
471
+ else:
472
+ thisheader["dim"][0] = 3
473
+ thisheader["pixdim"][4] = 1.0
474
+ if toffset is not None:
475
+ thisheader["toffset"] = toffset
476
+ if tr is not None:
477
+ thisheader["pixdim"][4] = tr
478
+ return thisheader
479
+
480
+ def getsizes(self) -> tuple[float, float, float, float]:
481
+ """
482
+ Return the dimensions and spacing parameters of the data structure.
483
+
484
+ Returns
485
+ -------
486
+ tuple[float, float, float, float]
487
+ A tuple containing four float values in order:
488
+ - xdim: x-dimension size
489
+ - ydim: y-dimension size
490
+ - slicethickness: thickness of each slice
491
+ - timestep: time step between measurements
492
+
493
+ Notes
494
+ -----
495
+ This method provides access to the fundamental spatial and temporal
496
+ parameters of the data structure. The returned values represent the
497
+ physical dimensions and spacing characteristics that define the
498
+ coordinate system of the data.
499
+
500
+ Examples
501
+ --------
502
+ >>> sizes = obj.getsizes()
503
+ >>> print(sizes)
504
+ (100.0, 100.0, 1.0, 0.1)
505
+ >>> x_size, y_size, slice_thick, time_step = obj.getsizes()
506
+ """
507
+ return self.xdim, self.ydim, self.slicethickness, self.timestep
508
+
509
+ def getdims(self) -> tuple[int, int, int, int]:
510
+ """
511
+ Return the dimensions of the data structure.
512
+
513
+ Returns
514
+ -------
515
+ tuple[int, int, int, int]
516
+ A tuple containing four integers representing:
517
+ - xsize: width dimension
518
+ - ysize: height dimension
519
+ - numslices: number of slices
520
+ - timepoints: number of time points
521
+
522
+ Notes
523
+ -----
524
+ This method provides access to the fundamental spatial and temporal dimensions
525
+ of the data structure. The returned tuple follows the order (x, y, slices, time).
526
+
527
+ Examples
528
+ --------
529
+ >>> dims = obj.getdims()
530
+ >>> print(dims)
531
+ (640, 480, 32, 100)
532
+ >>> x, y, slices, time = obj.getdims()
533
+ >>> print(f"Data shape: {x} x {y} x {slices} x {time}")
534
+ Data shape: 640 x 480 x 32 x 100
535
+ """
536
+ return self.xsize, self.ysize, self.numslices, self.timepoints
537
+
538
+ def unload(self) -> None:
539
+ """
540
+ Unload Nim data and clean up resources.
541
+
542
+ This method removes the Nim data and Nim object references from the instance
543
+ and marks the instance as not resident in memory.
544
+
545
+ Notes
546
+ -----
547
+ This method should be called to properly clean up resources when the Nim
548
+ data is no longer needed. The method deletes the internal references to
549
+ ``nim_data`` and ``nim`` objects and sets the ``resident`` flag to ``False``.
550
+
551
+ Examples
552
+ --------
553
+ >>> instance = MyClass()
554
+ >>> instance.load() # Load some data
555
+ >>> instance.unload() # Clean up resources
556
+ >>> instance.resident
557
+ False
558
+ """
559
+ del self.nim_data
560
+ del self.nim
561
+ self.resident = False
562
+
563
+ def load(self) -> None:
564
+ """
565
+ Load data from file based on file type detection.
566
+
567
+ This method loads data from the specified filename, automatically detecting
568
+ whether the file is text, CIFTI, or NIFTI format. The loaded data is stored
569
+ in instance variables for subsequent processing.
570
+
571
+ Parameters
572
+ ----------
573
+ self : object
574
+ The instance of the class containing this method. Expected to have
575
+ attributes: filename (str), filetype (str or None), and various data
576
+ storage attributes (nim_data, nim, cifti_hdr, nim_hdr, thedims, thesizes).
577
+
578
+ Returns
579
+ -------
580
+ None
581
+ This method does not return any value but updates instance attributes
582
+ with loaded data.
583
+
584
+ Notes
585
+ -----
586
+ - If filetype is not None, the method prints "reloading non-resident data"
587
+ - For text files, data is read using tide_io.readvecs()
588
+ - For CIFTI files, data is read using tide_io.readfromcifti() and stored
589
+ in multiple attributes including cifti_hdr and nim_hdr
590
+ - For NIFTI files, data is read using tide_io.readfromnifti() and stored
591
+ in nim, nim_data, nim_hdr, thedims, and thesizes attributes
592
+ - The method sets self.resident = True upon successful completion
593
+
594
+ Examples
595
+ --------
596
+ >>> loader = DataContainer()
597
+ >>> loader.filename = "data.nii.gz"
598
+ >>> loader.load()
599
+ loading data from data.nii.gz
600
+ """
601
+ if self.filetype is not None:
602
+ print("reloading non-resident data")
603
+ else:
604
+ print(f"loading data from {self.filename}")
605
+ if tide_io.checkiftext(self.filename):
606
+ self.nim_data = tide_io.readvecs(self.filename)
607
+ self.nim = None
608
+ else:
609
+ if tide_io.checkifcifti(self.filename):
610
+ self.filetype = "cifti"
611
+ (
612
+ dummy,
613
+ self.cifti_hdr,
614
+ self.nim_data,
615
+ self.nim_hdr,
616
+ self.thedims,
617
+ self.thesizes,
618
+ dummy,
619
+ ) = tide_io.readfromcifti(self.filename)
620
+ self.nim = None
621
+ else:
622
+ self.nim, self.nim_data, self.nim_hdr, self.thedims, self.thesizes = (
623
+ tide_io.readfromnifti(self.filename)
624
+ )
625
+ self.resident = True
626
+
627
+ def setvalidtimes(self, validstart: int | None, validend: int | None) -> None:
628
+ """
629
+ Set valid time points for the object based on start and end indices.
630
+
631
+ This method configures the valid time range for the object by setting
632
+ `validstart` and `validend` attributes. It also calculates the number of
633
+ real time points and updates the native fMRI shape based on the file type.
634
+
635
+ Parameters
636
+ ----------
637
+ validstart : int, optional
638
+ The starting index of valid time points. If None, defaults to 0.
639
+ validend : int, optional
640
+ The ending index of valid time points. If None, defaults to
641
+ `self.timepoints - 1`.
642
+
643
+ Returns
644
+ -------
645
+ None
646
+ This method modifies the object's attributes in-place and does not return anything.
647
+
648
+ Notes
649
+ -----
650
+ The method calculates `realtimepoints` as `validend - validstart + 1`.
651
+ The `nativefmrishape` is updated based on the `filetype` attribute:
652
+ - "nifti": (xsize, ysize, numslices, realtimepoints)
653
+ - "cifti": (1, 1, 1, realtimepoints, numspatiallocs)
654
+ - else: (xsize, realtimepoints)
655
+
656
+ Examples
657
+ --------
658
+ >>> obj.setvalidtimes(5, 15)
659
+ >>> obj.setvalidtimes(None, 10)
660
+ >>> obj.setvalidtimes(0, None)
661
+ """
662
+ if validstart is None:
663
+ self.validstart = 0
664
+ else:
665
+ self.validstart = validstart
666
+ if validend is None:
667
+ self.validend = self.timepoints - 1
668
+ else:
669
+ self.validend = validend
670
+ self.realtimepoints = self.validend - self.validstart + 1
671
+ if self.filetype == "nifti":
672
+ self.nativefmrishape = (self.xsize, self.ysize, self.numslices, self.realtimepoints)
673
+ elif self.filetype == "cifti":
674
+ self.nativefmrishape = (1, 1, 1, self.realtimepoints, self.numspatiallocs)
675
+ else:
676
+ self.nativefmrishape = (self.xsize, self.realtimepoints)
677
+
678
+ def setvalidvoxels(self, validvoxels: NDArray) -> None:
679
+ """
680
+ Set the valid voxels for the object.
681
+
682
+ Parameters
683
+ ----------
684
+ validvoxels : NDArray
685
+ Array containing the valid voxel coordinates. The first dimension
686
+ represents the number of valid spatial locations.
687
+
688
+ Returns
689
+ -------
690
+ None
691
+ This method does not return any value.
692
+
693
+ Notes
694
+ -----
695
+ This method updates two attributes:
696
+ - `self.validvoxels`: Stores the provided valid voxel array
697
+ - `self.numvalidspatiallocs`: Stores the number of valid spatial locations
698
+ (derived from the shape of the validvoxels array)
699
+
700
+ Examples
701
+ --------
702
+ >>> obj = MyClass()
703
+ >>> voxels = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]])
704
+ >>> obj.setvalidvoxels(voxels)
705
+ >>> print(obj.numvalidspatiallocs)
706
+ 3
707
+ """
708
+ self.validvoxels = validvoxels
709
+ self.numvalidspatiallocs = np.shape(self.validvoxels)[0]
710
+
711
+ def byvol(self) -> NDArray:
712
+ """
713
+ Return the nim_data array from the object.
714
+
715
+ If the object is not resident, it will be loaded first.
716
+
717
+ Returns
718
+ -------
719
+ NDArray
720
+ The nim_data array stored in the object.
721
+
722
+ Notes
723
+ -----
724
+ This method checks if the object is resident and loads it if necessary
725
+ before returning the nim_data array.
726
+
727
+ Examples
728
+ --------
729
+ >>> obj = MyClass()
730
+ >>> data = obj.byvol()
731
+ >>> print(data.shape)
732
+ (100, 100)
733
+ """
734
+ if not self.resident:
735
+ self.load()
736
+ return self.nim_data
737
+
738
+ def byvoltrimmed(self) -> NDArray:
739
+ """
740
+ Return data with volume trimming applied based on valid time range.
741
+
742
+ This method returns the neuroimaging data with temporal dimensions trimmed
743
+ according to the valid start and end indices. The behavior varies depending
744
+ on the file type and dimensions of the data.
745
+
746
+ Returns
747
+ -------
748
+ NDArray
749
+ Trimmed neuroimaging data array. For NIfTI files with 4D data or
750
+ CIFTI/text files, returns data with shape (X, Y, Z, T) where T is
751
+ the trimmed temporal dimension. For other file types, returns data
752
+ with shape (X, Y, Z) or (X, T) depending on the data structure.
753
+
754
+ Notes
755
+ -----
756
+ - If the data is not resident in memory, it will be loaded automatically
757
+ - For NIfTI files with 4D data, CIFTI files, or text files, the temporal
758
+ dimension is trimmed using self.validstart and self.validend
759
+ - For other file types, only the temporal dimension is trimmed
760
+ - The validend index is inclusive in the returned data
761
+
762
+ Examples
763
+ --------
764
+ >>> data = obj.byvoltrimmed()
765
+ >>> print(data.shape)
766
+ (64, 64, 32, 100) # For 4D NIfTI data with 100 valid time points
767
+ """
768
+ if not self.resident:
769
+ self.load()
770
+ if self.filetype == "nifti":
771
+ if self.dimensions == 4 or self.filetype == "cifti" or self.filetype == "text":
772
+ return self.nim_data[:, :, :, self.validstart : self.validend + 1]
773
+ else:
774
+ return self.nim_data[:, :, :]
775
+ else:
776
+ return self.nim_data[:, self.validstart : self.validend + 1]
777
+
778
+ def byvoxel(self) -> NDArray:
779
+ """
780
+ Reshape data by voxel across spatial locations.
781
+
782
+ This method reshapes the trimmed volume data to organize it by voxel
783
+ across all spatial locations. The output format depends on the
784
+ file type and dimensions of the data.
785
+
786
+ Returns
787
+ -------
788
+ NDArray
789
+ Reshaped array where each row represents a voxel and columns
790
+ represent time points or other dimensions. For 4D data or
791
+ CIFTI/text files, the shape is (numspatiallocs, -1), otherwise
792
+ (numspatiallocs,).
793
+
794
+ Notes
795
+ -----
796
+ - For 4D data, CIFTI files, or text files, the result is reshaped to
797
+ have an additional dimension for time points or other temporal
798
+ dimensions
799
+ - For other file types, the result is reshaped to a 2D array with
800
+ shape (numspatiallocs,)
801
+
802
+ Examples
803
+ --------
804
+ >>> data = MyDataClass()
805
+ >>> voxel_data = data.byvoxel()
806
+ >>> print(voxel_data.shape)
807
+ (numspatiallocs, num_timepoints)
808
+ """
809
+ if self.dimensions == 4 or self.filetype == "cifti" or self.filetype == "text":
810
+ return self.byvoltrimmed().reshape(self.numspatiallocs, -1)
811
+ else:
812
+ return self.byvoltrimmed().reshape(self.numspatiallocs)
813
+
814
+ def byslice(self) -> NDArray:
815
+ """
816
+ Reshape data by slice dimensions.
817
+
818
+ Reshapes the data returned by `byvoltrimmed()` to organize data by slice
819
+ locations and slices. The output format depends on the file type and
820
+ dimensions of the data.
821
+
822
+ Returns
823
+ -------
824
+ NDArray
825
+ Reshaped array with dimensions (numslicelocs, numslices, -1) for
826
+ CIFTI or text files, or (numslicelocs, numslices) for other file types.
827
+
828
+ Notes
829
+ -----
830
+ This method is particularly useful for organizing volumetric data by
831
+ slice locations and slices. For CIFTI and text file types, the last
832
+ dimension is automatically expanded to accommodate additional data
833
+ dimensions.
834
+
835
+ Examples
836
+ --------
837
+ >>> data = MyClass()
838
+ >>> result = data.byslice()
839
+ >>> print(result.shape)
840
+ (10, 20, 100) # for CIFTI/text files
841
+ >>> print(result.shape)
842
+ (10, 20) # for other file types
843
+ """
844
+ if self.dimensions == 4 or self.filetype == "cifti" or self.filetype == "text":
845
+ return self.byvoltrimmed().reshape(self.numslicelocs, self.numslices, -1)
846
+ else:
847
+ return self.byvoltrimmed().reshape(self.numslicelocs, self.numslices)
848
+
849
+ def validdata(self) -> NDArray:
850
+ """
851
+ Return valid voxel data based on validvoxels mask.
852
+
853
+ If validvoxels is None, returns all voxel data. Otherwise, returns
854
+ only the subset of voxel data indicated by the validvoxels mask.
855
+
856
+ Returns
857
+ -------
858
+ NDArray
859
+ Array containing voxel data. If validvoxels is None, returns
860
+ all voxel data from byvoxel() method. If validvoxels is not None,
861
+ returns subset of voxel data filtered by validvoxels mask.
862
+
863
+ Notes
864
+ -----
865
+ This method relies on the byvoxel() method to generate the base
866
+ voxel data array and applies filtering based on the validvoxels
867
+ attribute if it exists.
868
+
869
+ Examples
870
+ --------
871
+ >>> # Get all voxel data
872
+ >>> data = obj.validdata()
873
+ >>>
874
+ >>> # Get filtered voxel data
875
+ >>> obj.validvoxels = [0, 1, 2, 5, 10]
876
+ >>> data = obj.validdata()
877
+ """
878
+ if self.validvoxels is None:
879
+ return self.byvoxel()
880
+ else:
881
+ return self.byvoxel()[self.validvoxels, :]
882
+
883
+ # def validdatabyslice(self):
884
+ # if self.validvoxels is None:
885
+ # return self.byslice()
886
+ # else:
887
+ # return self.byvoxel()[self.validvoxels, :].reshape(self.numslicelocs, self.numslices, -1)
888
+
889
+ def smooth(
890
+ self,
891
+ gausssigma: float,
892
+ brainmask: NDArray | None = None,
893
+ graymask: NDArray | None = None,
894
+ whitemask: NDArray | None = None,
895
+ premask: bool = False,
896
+ premasktissueonly: bool = False,
897
+ showprogressbar: bool = False,
898
+ ) -> float:
899
+ """
900
+ Apply Gaussian spatial smoothing to the data.
901
+
902
+ This function applies a Gaussian spatial filter to the data, with optional
903
+ pre-masking of brain or tissue regions. For CIFTI and text file types, the
904
+ smoothing is skipped by setting `gausssigma` to 0.0. If `gausssigma` is less
905
+ than 0.0, it is automatically set to the mean of the image dimensions divided
906
+ by 2.0.
907
+
908
+ Parameters
909
+ ----------
910
+ gausssigma : float
911
+ Standard deviation for the Gaussian kernel. If less than 0.0, it is
912
+ automatically calculated as the mean of image dimensions divided by 2.0.
913
+ brainmask : NDArray | None, optional
914
+ Binary mask for the brain region. Required if `premask` is True and
915
+ `premasktissueonly` is False.
916
+ graymask : NDArray | None, optional
917
+ Binary mask for gray matter. Required if `premask` is True and
918
+ `premasktissueonly` is True.
919
+ whitemask : NDArray | None, optional
920
+ Binary mask for white matter. Required if `premask` is True and
921
+ `premasktissueonly` is True.
922
+ premask : bool, optional
923
+ If True, applies the mask before smoothing. Default is False.
924
+ premasktissueonly : bool, optional
925
+ If True, applies the mask only to gray and white matter. Requires
926
+ `graymask` and `whitemask` to be provided. Default is False.
927
+ showprogressbar : bool, optional
928
+ If True, displays a progress bar during processing. Default is False.
929
+
930
+ Returns
931
+ -------
932
+ float
933
+ The actual `gausssigma` value used for smoothing.
934
+
935
+ Notes
936
+ -----
937
+ - For CIFTI and text file types, smoothing is skipped.
938
+ - The function modifies `self.nim_data` in-place.
939
+ - If `premask` is True, the mask is applied to the timepoints specified by
940
+ `self.validstart` to `self.validend`.
941
+
942
+ Examples
943
+ --------
944
+ >>> # Apply smoothing with automatic sigma
945
+ >>> smooth(-1.0)
946
+ 1.5
947
+
948
+ >>> # Apply smoothing with a custom sigma and pre-mask
949
+ >>> smooth(2.0, brainmask=mask, premask=True)
950
+ 2.0
951
+ """
952
+ # do spatial filtering if requested
953
+ if self.filetype == "cifti" or self.filetype == "text":
954
+ gausssigma = 0.0
955
+ if gausssigma < 0.0:
956
+ # set gausssigma automatically
957
+ gausssigma = np.mean([self.xdim, self.ydim, self.slicethickness]) / 2.0
958
+ if gausssigma > 0.0:
959
+ # premask data if requested
960
+ if premask:
961
+ if premasktissueonly:
962
+ if (graymask is not None) and (whitemask is not None):
963
+ multmask = graymask + whitemask
964
+ else:
965
+ raise ValueError(
966
+ "ERROR: graymask and whitemask must be defined to use premasktissueonly - exiting"
967
+ )
968
+ else:
969
+ if brainmask is not None:
970
+ multmask = brainmask
971
+ else:
972
+ raise ValueError(
973
+ "ERROR: brainmask must be defined to use premask - exiting"
974
+ )
975
+ print(f"premasking timepoints {self.validstart} to {self.validend}")
976
+ for i in tqdm(
977
+ range(self.validstart, self.validend + 1),
978
+ desc="Timepoint",
979
+ unit="timepoints",
980
+ disable=(not showprogressbar),
981
+ ):
982
+ self.nim_data[:, :, :, i] *= multmask
983
+
984
+ # now apply the filter
985
+ print(
986
+ f"applying gaussian spatial filter to timepoints {self.validstart} "
987
+ f"to {self.validend} with sigma={gausssigma}"
988
+ )
989
+ sourcedata = self.byvol()
990
+ for i in tqdm(
991
+ range(self.validstart, self.validend + 1),
992
+ desc="Timepoint",
993
+ unit="timepoints",
994
+ disable=(not showprogressbar),
995
+ ):
996
+ self.nim_data[:, :, :, i] = tide_filt.ssmooth(
997
+ self.xdim,
998
+ self.ydim,
999
+ self.slicethickness,
1000
+ gausssigma,
1001
+ sourcedata[:, :, :, i],
1002
+ )
1003
+ return gausssigma
1004
+
1005
+ def summarize(self) -> None:
1006
+ """
1007
+ Print a comprehensive summary of voxel data properties.
1008
+
1009
+ This method outputs detailed information about the voxel data structure,
1010
+ including image dimensions, spatial properties, temporal characteristics,
1011
+ and file metadata. The summary includes both geometric and temporal
1012
+ parameters that define the voxel space and data organization.
1013
+
1014
+ Notes
1015
+ -----
1016
+ The method prints to standard output and does not return any value.
1017
+ All attributes are accessed from the instance and displayed in a
1018
+ formatted manner for easy inspection of the data structure.
1019
+
1020
+ Examples
1021
+ --------
1022
+ >>> obj.summarize()
1023
+ Voxel data summary:
1024
+ self.nim=...
1025
+ self.nim_data.shape=...
1026
+ self.nim_hdr=...
1027
+ self.nim_affine=...
1028
+ ...
1029
+ """
1030
+ print("Voxel data summary:")
1031
+ print(f"\t{self.nim=}")
1032
+ print(f"\t{self.nim_data.shape=}")
1033
+ print(f"\t{self.nim_hdr=}")
1034
+ print(f"\t{self.nim_affine=}")
1035
+ print(f"\t{self.theshape=}")
1036
+ print(f"\t{self.xsize=}")
1037
+ print(f"\t{self.ysize=}")
1038
+ print(f"\t{self.numslices=}")
1039
+ print(f"\t{self.timepoints=}")
1040
+ print(f"\t{self.timestep=}")
1041
+ print(f"\t{self.thesizes=}")
1042
+ print(f"\t{self.thedims=}")
1043
+ print(f"\t{self.numslicelocs=}")
1044
+ print(f"\t{self.numspatiallocs=}")
1045
+ print(f"\t{self.nativespaceshape=}")
1046
+ print(f"\t{self.cifti_hdr=}")
1047
+ print(f"\t{self.filetype=}")
1048
+ print(f"\t{self.resident=}")