rapidtide 2.9.5__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 +94 -27
  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 +21 -0
  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 +178 -0
  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 +590 -1181
  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 +867 -137
  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.5.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 +27 -15
  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 +1833 -1919
  292. rapidtide/workflows/rapidtide2std.py +101 -3
  293. rapidtide/workflows/rapidtide_parser.py +607 -372
  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.5.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.5.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.5.data/scripts/adjustoffset +0 -23
  346. rapidtide-2.9.5.data/scripts/aligntcs +0 -23
  347. rapidtide-2.9.5.data/scripts/applydlfilter +0 -23
  348. rapidtide-2.9.5.data/scripts/atlasaverage +0 -23
  349. rapidtide-2.9.5.data/scripts/atlastool +0 -23
  350. rapidtide-2.9.5.data/scripts/calcicc +0 -22
  351. rapidtide-2.9.5.data/scripts/calctexticc +0 -23
  352. rapidtide-2.9.5.data/scripts/calcttest +0 -22
  353. rapidtide-2.9.5.data/scripts/ccorrica +0 -23
  354. rapidtide-2.9.5.data/scripts/diffrois +0 -23
  355. rapidtide-2.9.5.data/scripts/endtidalproc +0 -23
  356. rapidtide-2.9.5.data/scripts/filtnifti +0 -23
  357. rapidtide-2.9.5.data/scripts/filttc +0 -23
  358. rapidtide-2.9.5.data/scripts/fingerprint +0 -593
  359. rapidtide-2.9.5.data/scripts/fixtr +0 -23
  360. rapidtide-2.9.5.data/scripts/glmfilt +0 -24
  361. rapidtide-2.9.5.data/scripts/gmscalc +0 -22
  362. rapidtide-2.9.5.data/scripts/happy +0 -25
  363. rapidtide-2.9.5.data/scripts/happy2std +0 -23
  364. rapidtide-2.9.5.data/scripts/happywarp +0 -350
  365. rapidtide-2.9.5.data/scripts/histnifti +0 -23
  366. rapidtide-2.9.5.data/scripts/histtc +0 -23
  367. rapidtide-2.9.5.data/scripts/localflow +0 -23
  368. rapidtide-2.9.5.data/scripts/mergequality +0 -23
  369. rapidtide-2.9.5.data/scripts/pairproc +0 -23
  370. rapidtide-2.9.5.data/scripts/pairwisemergenifti +0 -23
  371. rapidtide-2.9.5.data/scripts/physiofreq +0 -23
  372. rapidtide-2.9.5.data/scripts/pixelcomp +0 -23
  373. rapidtide-2.9.5.data/scripts/plethquality +0 -23
  374. rapidtide-2.9.5.data/scripts/polyfitim +0 -23
  375. rapidtide-2.9.5.data/scripts/proj2flow +0 -23
  376. rapidtide-2.9.5.data/scripts/rankimage +0 -23
  377. rapidtide-2.9.5.data/scripts/rapidtide +0 -23
  378. rapidtide-2.9.5.data/scripts/rapidtide2std +0 -23
  379. rapidtide-2.9.5.data/scripts/resamplenifti +0 -23
  380. rapidtide-2.9.5.data/scripts/resampletc +0 -23
  381. rapidtide-2.9.5.data/scripts/retroglm +0 -23
  382. rapidtide-2.9.5.data/scripts/roisummarize +0 -23
  383. rapidtide-2.9.5.data/scripts/runqualitycheck +0 -23
  384. rapidtide-2.9.5.data/scripts/showarbcorr +0 -23
  385. rapidtide-2.9.5.data/scripts/showhist +0 -23
  386. rapidtide-2.9.5.data/scripts/showstxcorr +0 -23
  387. rapidtide-2.9.5.data/scripts/showtc +0 -23
  388. rapidtide-2.9.5.data/scripts/showxcorr_legacy +0 -536
  389. rapidtide-2.9.5.data/scripts/showxcorrx +0 -23
  390. rapidtide-2.9.5.data/scripts/showxy +0 -23
  391. rapidtide-2.9.5.data/scripts/simdata +0 -23
  392. rapidtide-2.9.5.data/scripts/spatialdecomp +0 -23
  393. rapidtide-2.9.5.data/scripts/spatialfit +0 -23
  394. rapidtide-2.9.5.data/scripts/spatialmi +0 -23
  395. rapidtide-2.9.5.data/scripts/spectrogram +0 -23
  396. rapidtide-2.9.5.data/scripts/synthASL +0 -23
  397. rapidtide-2.9.5.data/scripts/tcfrom2col +0 -23
  398. rapidtide-2.9.5.data/scripts/tcfrom3col +0 -23
  399. rapidtide-2.9.5.data/scripts/temporaldecomp +0 -23
  400. rapidtide-2.9.5.data/scripts/threeD +0 -236
  401. rapidtide-2.9.5.data/scripts/tidepool +0 -23
  402. rapidtide-2.9.5.data/scripts/variabilityizer +0 -23
  403. rapidtide-2.9.5.dist-info/RECORD +0 -357
  404. rapidtide-2.9.5.dist-info/top_level.txt +0 -86
  405. {rapidtide-2.9.5.dist-info → rapidtide-3.1.3.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,784 @@
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
+ from typing import Any
20
+
21
+ import numpy as np
22
+ from numpy.typing import NDArray
23
+ from scipy.special import factorial
24
+ from tqdm import tqdm
25
+
26
+ import rapidtide.filter as tide_filt
27
+ import rapidtide.fit as tide_fit
28
+ import rapidtide.miscmath as tide_math
29
+ import rapidtide.multiproc as tide_multiproc
30
+
31
+
32
+ def _procOneRegressionFitItem(
33
+ vox: int,
34
+ theevs: NDArray,
35
+ thedata: NDArray,
36
+ rt_floattype: np.dtype = np.float64,
37
+ ) -> tuple[int, float, float, float, float | NDArray, Any, NDArray, NDArray]:
38
+ """
39
+ Perform single regression fit on voxel data and return fit results.
40
+
41
+ This function fits a linear regression model to the provided evs and data,
42
+ handling both univariate and multivariate cases. It computes fit coefficients,
43
+ R-squared value, and residual data.
44
+
45
+ Parameters
46
+ ----------
47
+ vox : int
48
+ Voxel index.
49
+ theevs : NDArray
50
+ Experimental design matrix. If 2D, dimension 0 is number of points,
51
+ dimension 1 is number of evs.
52
+ thedata : NDArray
53
+ Dependent variable data corresponding to the evs.
54
+ rt_floattype : str, optional
55
+ String representation of the floating-point type, default is ``np.float64``.
56
+
57
+ Returns
58
+ -------
59
+ tuple[int, float, float, float, float, Any, NDArray, NDArray]
60
+ A tuple containing:
61
+ - voxel index (`int`)
62
+ - intercept term (`float`)
63
+ - signed square root of R-squared (`float`)
64
+ - R-squared value (`float`)
65
+ - fit coefficients (`float` or `NDArray`)
66
+ - normalized fit coefficients (`Any`)
67
+ - data removed by fitting (`NDArray`)
68
+ - residuals (`NDArray`)
69
+
70
+ Notes
71
+ -----
72
+ For multivariate regressions (2D `theevs`), the function computes the fit
73
+ using `tide_fit.mlregress`. If the fit fails, a zero matrix is returned.
74
+ For univariate regressions (1D `theevs`), the function directly computes
75
+ the fit and handles edge cases such as zero coefficients.
76
+
77
+ Examples
78
+ --------
79
+ >>> import numpy as np
80
+ >>> theevs = np.array([[1, 2], [3, 4], [5, 6]], dtype=np.float64)
81
+ >>> thedata = np.array([1, 2, 3], dtype=np.float64)
82
+ >>> result = _procOneRegressionFitItem(0, theevs, thedata)
83
+ >>> print(result[0]) # voxel index
84
+ 0
85
+ """
86
+ # NOTE: if theevs is 2D, dimension 0 is number of points, dimension 1 is number of evs
87
+ thefit, R2 = tide_fit.mlregress(theevs, thedata)
88
+ if theevs.ndim > 1:
89
+ if thefit is None:
90
+ thefit = np.matrix(np.zeros((1, theevs.shape[1] + 1), dtype=rt_floattype))
91
+ fitcoeffs = (thefit[0, 1:]).astype(rt_floattype)
92
+ if fitcoeffs[0, 0] < 0.0:
93
+ coeffsign = -1.0
94
+ else:
95
+ coeffsign = 1.0
96
+ datatoremove = np.zeros_like(theevs[:, 0])
97
+ for j in range(theevs.shape[1]):
98
+ datatoremove += (thefit[0, 1 + j] * theevs[:, j]).astype(rt_floattype)
99
+ if np.any(fitcoeffs) != 0.0:
100
+ pass
101
+ else:
102
+ R2 = 0.0
103
+ return (
104
+ vox,
105
+ thefit[0, 0],
106
+ coeffsign * np.sqrt(R2),
107
+ R2,
108
+ fitcoeffs,
109
+ (thefit[0, 1:] / thefit[0, 0]).astype(rt_floattype),
110
+ datatoremove,
111
+ (thedata - datatoremove).astype(rt_floattype),
112
+ )
113
+ else:
114
+ fitcoeff = (thefit[0, 1]).astype(rt_floattype)
115
+ datatoremove = (fitcoeff * theevs).astype(rt_floattype)
116
+ if fitcoeff < 0.0:
117
+ coeffsign = -1.0
118
+ else:
119
+ coeffsign = 1.0
120
+ if fitcoeff == 0.0:
121
+ R2 = 0.0
122
+ return (
123
+ vox,
124
+ thefit[0, 0],
125
+ coeffsign * np.sqrt(R2),
126
+ R2,
127
+ fitcoeff,
128
+ (thefit[0, 1] / thefit[0, 0]).astype(rt_floattype),
129
+ datatoremove,
130
+ (thedata - datatoremove).astype(rt_floattype),
131
+ )
132
+
133
+
134
+ def linfitfiltpass(
135
+ numprocitems: int,
136
+ fmri_data: NDArray,
137
+ threshval: float | None,
138
+ theevs: NDArray,
139
+ meanvalue: NDArray | None,
140
+ rvalue: NDArray | None,
141
+ r2value: NDArray,
142
+ fitcoeff: NDArray | None,
143
+ fitNorm: NDArray | None,
144
+ datatoremove: NDArray | None,
145
+ filtereddata: NDArray | None,
146
+ nprocs: int = 1,
147
+ alwaysmultiproc: bool = False,
148
+ constantevs: bool = False,
149
+ confoundregress: bool = False,
150
+ coefficientsonly: bool = False,
151
+ procbyvoxel: bool = True,
152
+ showprogressbar: bool = True,
153
+ chunksize: int = 1000,
154
+ rt_floattype: np.dtype = np.dtype(np.float64),
155
+ verbose: bool = True,
156
+ debug: bool = False,
157
+ ) -> int:
158
+ """
159
+ Perform linear regression fitting and filtering on fMRI data.
160
+
161
+ This function fits a linear model to fMRI data using specified experimental variables
162
+ and applies filtering to remove noise. It supports both voxel-wise and timepoint-wise
163
+ processing, with optional multiprocessing for performance.
164
+
165
+ Parameters
166
+ ----------
167
+ numprocitems : int
168
+ Number of items to process (voxels or timepoints depending on ``procbyvoxel``).
169
+ fmri_data : ndarray
170
+ Input fMRI data array with shape ``(n_voxels, n_timepoints)`` or ``(n_timepoints, n_voxels)``.
171
+ threshval : float, optional
172
+ Threshold value for masking. If ``None``, no masking is applied.
173
+ theevs : ndarray
174
+ Experimental variables (design matrix) with shape ``(n_voxels, n_timepoints)`` or ``(n_timepoints, n_voxels)``.
175
+ meanvalue : ndarray, optional
176
+ Array to store mean values of the data. Shape depends on ``procbyvoxel``.
177
+ rvalue : ndarray, optional
178
+ Array to store correlation coefficients. Shape depends on ``procbyvoxel``.
179
+ r2value : ndarray
180
+ Array to store R-squared values. Shape depends on ``procbyvoxel``.
181
+ fitcoeff : ndarray, optional
182
+ Array to store fit coefficients. Shape depends on ``procbyvoxel`` and ``constantevs``.
183
+ fitNorm : ndarray, optional
184
+ Array to store normalized fit coefficients. Shape depends on ``procbyvoxel``.
185
+ datatoremove : ndarray, optional
186
+ Array to store data to be removed after fitting. Shape depends on ``procbyvoxel``.
187
+ filtereddata : ndarray
188
+ Array to store filtered data after regression. Shape depends on ``procbyvoxel``.
189
+ nprocs : int, default: 1
190
+ Number of processes to use for multiprocessing. If 1 and ``alwaysmultiproc`` is False, uses single-threaded processing.
191
+ alwaysmultiproc : bool, default: False
192
+ If True, always use multiprocessing even if ``nprocs`` is 1.
193
+ constantevs : bool, default: False
194
+ If True, treat experimental variables as constant across voxels/timepoints.
195
+ confoundregress : bool, default: False
196
+ If True, perform confound regression only (no output of coefficients or residuals).
197
+ coefficientsonly : bool, default: False
198
+ If True, store only regression coefficients and R-squared values.
199
+ procbyvoxel : bool, default: True
200
+ If True, process data voxel-wise; otherwise, process by timepoint.
201
+ showprogressbar : bool, default: True
202
+ If True, display a progress bar during processing.
203
+ chunksize : int, default: 1000
204
+ Size of chunks for multiprocessing.
205
+ rt_floattype : str, default: np.float64
206
+ Data type for internal floating-point calculations.
207
+ verbose : bool, default: True
208
+ If True, print verbose output.
209
+ debug : bool, default: False
210
+ If True, enable debug printing.
211
+
212
+ Returns
213
+ -------
214
+ int
215
+ Total number of items processed.
216
+
217
+ Notes
218
+ -----
219
+ - The function modifies the output arrays in-place.
220
+ - For ``confoundregress=True``, only ``r2value`` and ``filtereddata`` are populated.
221
+ - When ``coefficientsonly=True``, only ``meanvalue``, ``rvalue``, ``r2value``, ``fitcoeff``, and ``fitNorm`` are populated.
222
+ - If ``threshval`` is provided, a mask is generated based on mean or standard deviation of the data.
223
+
224
+ Examples
225
+ --------
226
+ >>> import numpy as np
227
+ >>> fmri_data = np.random.rand(100, 200)
228
+ >>> theevs = np.random.rand(100, 200)
229
+ >>> r2value = np.zeros(100)
230
+ >>> filtereddata = np.zeros_like(fmri_data)
231
+ >>> numprocitems = 100
232
+ >>> items_processed = linfitfiltpass(
233
+ ... numprocitems=numprocitems,
234
+ ... fmri_data=fmri_data,
235
+ ... threshval=None,
236
+ ... theevs=theevs,
237
+ ... meanvalue=None,
238
+ ... rvalue=None,
239
+ ... r2value=r2value,
240
+ ... fitcoeff=None,
241
+ ... fitNorm=None,
242
+ ... datatoremove=None,
243
+ ... filtereddata=filtereddata,
244
+ ... nprocs=4,
245
+ ... procbyvoxel=True,
246
+ ... showprogressbar=True
247
+ ... )
248
+ >>> print(f"Processed {items_processed} items.")
249
+ """
250
+ inputshape = np.shape(fmri_data)
251
+ if debug:
252
+ print(f"{numprocitems=}")
253
+ print(f"{fmri_data.shape=}")
254
+ print(f"{threshval=}")
255
+ print(f"{theevs.shape=}, {np.min(theevs)=}, {np.max(theevs)=}")
256
+ print(f"{theevs=}")
257
+ if procbyvoxel:
258
+ indexaxis = 0
259
+ procunit = "voxels"
260
+ else:
261
+ indexaxis = 1
262
+ procunit = "timepoints"
263
+ if threshval is None:
264
+ themask = None
265
+ else:
266
+ if procbyvoxel:
267
+ meanim = np.mean(fmri_data, axis=1)
268
+ stdim = np.std(fmri_data, axis=1)
269
+ else:
270
+ meanim = np.mean(fmri_data, axis=0)
271
+ stdim = np.std(fmri_data, axis=0)
272
+ if np.mean(stdim) < np.mean(meanim):
273
+ themask = np.where(meanim > threshval, 1, 0)
274
+ else:
275
+ themask = np.where(stdim > threshval, 1, 0)
276
+ if (
277
+ nprocs > 1 or alwaysmultiproc
278
+ ): # temporary workaround until I figure out why nprocs > 1 is failing
279
+ # define the consumer function here so it inherits most of the arguments
280
+ def GLM_consumer(inQ, outQ):
281
+ while True:
282
+ try:
283
+ # get a new message
284
+ val = inQ.get()
285
+
286
+ # this is the 'TERM' signal
287
+ if val is None:
288
+ break
289
+
290
+ # process and send the data
291
+ if procbyvoxel:
292
+ if confoundregress or constantevs:
293
+ outQ.put(
294
+ _procOneRegressionFitItem(
295
+ val,
296
+ theevs,
297
+ fmri_data[val, :],
298
+ rt_floattype=rt_floattype,
299
+ )
300
+ )
301
+ else:
302
+ outQ.put(
303
+ _procOneRegressionFitItem(
304
+ val,
305
+ theevs[val, :],
306
+ fmri_data[val, :],
307
+ rt_floattype=rt_floattype,
308
+ )
309
+ )
310
+ else:
311
+ if confoundregress or constantevs:
312
+ outQ.put(
313
+ _procOneRegressionFitItem(
314
+ val,
315
+ theevs,
316
+ fmri_data[:, val],
317
+ rt_floattype=rt_floattype,
318
+ )
319
+ )
320
+ else:
321
+ outQ.put(
322
+ _procOneRegressionFitItem(
323
+ val,
324
+ theevs[:, val],
325
+ fmri_data[:, val],
326
+ rt_floattype=rt_floattype,
327
+ )
328
+ )
329
+
330
+ except Exception as e:
331
+ print("error!", e)
332
+ break
333
+
334
+ data_out = tide_multiproc.run_multiproc(
335
+ GLM_consumer,
336
+ inputshape,
337
+ themask,
338
+ verbose=verbose,
339
+ nprocs=nprocs,
340
+ indexaxis=indexaxis,
341
+ procunit=procunit,
342
+ showprogressbar=showprogressbar,
343
+ chunksize=chunksize,
344
+ )
345
+
346
+ # unpack the data
347
+ itemstotal = 0
348
+ if procbyvoxel:
349
+ if confoundregress:
350
+ for voxel in data_out:
351
+ r2value[voxel[0]] = voxel[3]
352
+ filtereddata[voxel[0], :] = voxel[7]
353
+ itemstotal += 1
354
+ elif coefficientsonly:
355
+ for voxel in data_out:
356
+ meanvalue[voxel[0]] = voxel[1]
357
+ rvalue[voxel[0]] = voxel[2]
358
+ r2value[voxel[0]] = voxel[3]
359
+ if fitcoeff.ndim > 1:
360
+ fitcoeff[voxel[0], :] = voxel[4]
361
+ fitNorm[voxel[0], :] = voxel[5]
362
+ else:
363
+ fitcoeff[voxel[0]] = voxel[4]
364
+ fitNorm[voxel[0]] = voxel[5]
365
+ itemstotal += 1
366
+ else:
367
+ for voxel in data_out:
368
+ meanvalue[voxel[0]] = voxel[1]
369
+ rvalue[voxel[0]] = voxel[2]
370
+ r2value[voxel[0]] = voxel[3]
371
+ if fitcoeff.ndim > 1:
372
+ fitcoeff[voxel[0], :] = voxel[4]
373
+ fitNorm[voxel[0], :] = voxel[5]
374
+ else:
375
+ fitcoeff[voxel[0]] = voxel[4]
376
+ fitNorm[voxel[0]] = voxel[5]
377
+ datatoremove[voxel[0], :] = voxel[6]
378
+ filtereddata[voxel[0], :] = voxel[7]
379
+ itemstotal += 1
380
+ else:
381
+ if confoundregress:
382
+ for timepoint in data_out:
383
+ r2value[timepoint[0]] = timepoint[3]
384
+ filtereddata[:, timepoint[0]] = timepoint[7]
385
+ itemstotal += 1
386
+ elif coefficientsonly:
387
+ for timepoint in data_out:
388
+ meanvalue[timepoint[0]] = timepoint[1]
389
+ rvalue[timepoint[0]] = timepoint[2]
390
+ r2value[timepoint[0]] = timepoint[3]
391
+ if fitcoeff.ndim > 1:
392
+ fitcoeff[:, timepoint[0]] = timepoint[4]
393
+ fitNorm[:, timepoint[0]] = timepoint[5]
394
+ else:
395
+ fitcoeff[timepoint[0]] = timepoint[4]
396
+ fitNorm[timepoint[0]] = timepoint[5]
397
+ itemstotal += 1
398
+ else:
399
+ for timepoint in data_out:
400
+ meanvalue[timepoint[0]] = timepoint[1]
401
+ rvalue[timepoint[0]] = timepoint[2]
402
+ r2value[timepoint[0]] = timepoint[3]
403
+ if fitcoeff.ndim > 1:
404
+ fitcoeff[:, timepoint[0]] = timepoint[4]
405
+ fitNorm[:, timepoint[0]] = timepoint[5]
406
+ else:
407
+ fitcoeff[timepoint[0]] = timepoint[4]
408
+ fitNorm[timepoint[0]] = timepoint[5]
409
+ datatoremove[:, timepoint[0]] = timepoint[6]
410
+ filtereddata[:, timepoint[0]] = timepoint[7]
411
+ itemstotal += 1
412
+
413
+ del data_out
414
+ else:
415
+ # this is the single proc path
416
+ itemstotal = 0
417
+ if procbyvoxel:
418
+ for vox in tqdm(
419
+ range(0, numprocitems),
420
+ desc="Voxel",
421
+ unit="voxels",
422
+ disable=(not showprogressbar),
423
+ ):
424
+ thedata = fmri_data[vox, :].copy()
425
+ if (themask is None) or (themask[vox] > 0):
426
+ if confoundregress:
427
+ (
428
+ dummy,
429
+ dummy,
430
+ dummy,
431
+ r2value[vox],
432
+ dummy,
433
+ dummy,
434
+ dummy,
435
+ filtereddata[vox, :],
436
+ ) = _procOneRegressionFitItem(
437
+ vox,
438
+ theevs,
439
+ thedata,
440
+ rt_floattype=rt_floattype,
441
+ )
442
+ elif coefficientsonly:
443
+ if not constantevs:
444
+ (
445
+ dummy,
446
+ meanvalue[vox],
447
+ rvalue[vox],
448
+ r2value[vox],
449
+ fitcoeff[vox],
450
+ fitNorm[vox],
451
+ dummy,
452
+ dummy,
453
+ ) = _procOneRegressionFitItem(
454
+ vox,
455
+ theevs[vox, :],
456
+ thedata,
457
+ rt_floattype=rt_floattype,
458
+ )
459
+ else:
460
+ (
461
+ dummy,
462
+ meanvalue[vox],
463
+ rvalue[vox],
464
+ r2value[vox],
465
+ fitcoeff[vox],
466
+ fitNorm[vox],
467
+ dummy,
468
+ dummy,
469
+ ) = _procOneRegressionFitItem(
470
+ vox,
471
+ theevs,
472
+ thedata,
473
+ rt_floattype=rt_floattype,
474
+ )
475
+ else:
476
+ (
477
+ dummy,
478
+ meanvalue[vox],
479
+ rvalue[vox],
480
+ r2value[vox],
481
+ fitcoeff[vox],
482
+ fitNorm[vox],
483
+ datatoremove[vox, :],
484
+ filtereddata[vox, :],
485
+ ) = _procOneRegressionFitItem(
486
+ vox,
487
+ theevs[vox, :],
488
+ thedata,
489
+ rt_floattype=rt_floattype,
490
+ )
491
+ itemstotal += 1
492
+ else:
493
+ for timepoint in tqdm(
494
+ range(0, numprocitems),
495
+ desc="Timepoint",
496
+ unit="timepoints",
497
+ disable=(not showprogressbar),
498
+ ):
499
+ thedata = fmri_data[:, timepoint].copy()
500
+ if (themask is None) or (themask[timepoint] > 0):
501
+ if confoundregress:
502
+ (
503
+ dummy,
504
+ dummy,
505
+ dummy,
506
+ r2value[timepoint],
507
+ dummy,
508
+ dummy,
509
+ dummy,
510
+ filtereddata[:, timepoint],
511
+ ) = _procOneRegressionFitItem(
512
+ timepoint,
513
+ theevs,
514
+ thedata,
515
+ rt_floattype=rt_floattype,
516
+ )
517
+ elif coefficientsonly:
518
+ if not constantevs:
519
+ (
520
+ dummy,
521
+ meanvalue[timepoint],
522
+ rvalue[timepoint],
523
+ r2value[timepoint],
524
+ fitcoeff[timepoint],
525
+ fitNorm[timepoint],
526
+ dummy,
527
+ dummy,
528
+ ) = _procOneRegressionFitItem(
529
+ timepoint,
530
+ theevs[:, timepoint],
531
+ thedata,
532
+ rt_floattype=rt_floattype,
533
+ )
534
+ else:
535
+ (
536
+ dummy,
537
+ meanvalue[timepoint],
538
+ rvalue[timepoint],
539
+ r2value[timepoint],
540
+ fitcoeff[timepoint],
541
+ fitNorm[timepoint],
542
+ dummy,
543
+ dummy,
544
+ ) = _procOneRegressionFitItem(
545
+ timepoint,
546
+ theevs,
547
+ thedata,
548
+ rt_floattype=rt_floattype,
549
+ )
550
+ else:
551
+ (
552
+ dummy,
553
+ meanvalue[timepoint],
554
+ rvalue[timepoint],
555
+ r2value[timepoint],
556
+ fitcoeff[timepoint],
557
+ fitNorm[timepoint],
558
+ datatoremove[:, timepoint],
559
+ filtereddata[:, timepoint],
560
+ ) = _procOneRegressionFitItem(
561
+ timepoint,
562
+ theevs[:, timepoint],
563
+ thedata,
564
+ rt_floattype=rt_floattype,
565
+ )
566
+
567
+ itemstotal += 1
568
+ if showprogressbar:
569
+ print()
570
+ return itemstotal
571
+
572
+
573
+ def makevoxelspecificderivs(theevs: NDArray, nderivs: int = 1, debug: bool = False) -> NDArray:
574
+ """
575
+ Perform multicomponent expansion on voxel-specific explanatory variables by computing
576
+ derivatives up to a specified order.
577
+
578
+ This function takes an array of voxel-specific timecourses and expands each one
579
+ into a set of components representing the original signal and its derivatives.
580
+ Each component corresponds to a higher-order derivative of the signal, scaled by
581
+ the inverse factorial of the derivative order (Taylor series coefficients).
582
+
583
+ Parameters
584
+ ----------
585
+ theevs : 2D numpy array
586
+ NxP array of voxel-specific explanatory variables, where N is the number of voxels
587
+ and P is the number of timepoints.
588
+ nderivs : int, optional
589
+ Number of derivative components to compute for each voxel. Default is 1.
590
+ If 0, the original `theevs` are returned without modification.
591
+ debug : bool, optional
592
+ If True, print debugging information including input and output shapes.
593
+ Default is False.
594
+
595
+ Returns
596
+ -------
597
+ 3D numpy array
598
+ Array of shape (N, P, nderivs + 1) containing the original signal and its
599
+ derivatives up to order `nderivs` for each voxel. The first component is the
600
+ original signal, followed by the first, second, ..., up to `nderivs`-th derivative.
601
+
602
+ Notes
603
+ -----
604
+ - The function uses `numpy.gradient` to compute numerical derivatives.
605
+ - Each derivative component is scaled by the inverse factorial of the derivative order
606
+ to align with Taylor series expansion coefficients.
607
+ - If `nderivs=0`, the function returns a copy of the input `theevs`.
608
+
609
+ Examples
610
+ --------
611
+ >>> import numpy as np
612
+ >>> theevs = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
613
+ >>> result = makevoxelspecificderivs(theevs, nderivs=2)
614
+ >>> print(result.shape)
615
+ (2, 4, 3)
616
+ """
617
+ if debug:
618
+ print(f"{theevs.shape=}")
619
+ if nderivs == 0:
620
+ thenewevs = theevs
621
+ else:
622
+ taylorcoffs = np.zeros((nderivs + 1), dtype=np.float64)
623
+ taylorcoffs[0] = 1.0
624
+ thenewevs = np.zeros((theevs.shape[0], theevs.shape[1], nderivs + 1), dtype=float)
625
+ for i in range(1, nderivs + 1):
626
+ taylorcoffs[i] = 1.0 / factorial(i)
627
+ for thevoxel in range(0, theevs.shape[0]):
628
+ thenewevs[thevoxel, :, 0] = theevs[thevoxel, :] * 1.0
629
+ for i in range(1, nderivs + 1):
630
+ thenewevs[thevoxel, :, i] = taylorcoffs[i] * np.gradient(
631
+ thenewevs[thevoxel, :, i - 1]
632
+ )
633
+ if debug:
634
+ print(f"{nderivs=}")
635
+ print(f"{thenewevs.shape=}")
636
+
637
+ return thenewevs
638
+
639
+
640
+ def confoundregress(
641
+ theregressors: NDArray,
642
+ theregressorlabels: list[str],
643
+ thedataarray: NDArray,
644
+ tr: float,
645
+ nprocs: int = 1,
646
+ orthogonalize: bool = True,
647
+ tcstart: int = 0,
648
+ tcend: int = -1,
649
+ tchp: float | None = None,
650
+ tclp: float | None = None,
651
+ showprogressbar: bool = True,
652
+ debug: bool = False,
653
+ ) -> tuple[NDArray, list[str], NDArray, NDArray]:
654
+ """
655
+ Perform confound regression on fMRI data using linear regression.
656
+
657
+ This function applies confound regression to remove noise from fMRI time series
658
+ by regressing out specified confounding variables (e.g., motion parameters,
659
+ physiological signals). It supports optional filtering, orthogonalization of
660
+ regressors, and parallel processing for performance.
661
+
662
+ Parameters
663
+ ----------
664
+ theregressors : ndarray
665
+ Array of confounding variables with shape (n_regressors, n_timepoints).
666
+ theregressorlabels : list of str
667
+ List of labels corresponding to each regressor.
668
+ thedataarray : ndarray
669
+ 3D or 4D array of fMRI data with shape (n_voxels, n_timepoints) or
670
+ (n_voxels, n_timepoints, n_volumes).
671
+ tr : float
672
+ Repetition time (TR) in seconds.
673
+ nprocs : int, optional
674
+ Number of processes to use for parallel processing. Default is 1.
675
+ orthogonalize : bool, optional
676
+ If True, orthogonalize the regressors to reduce multicollinearity.
677
+ Default is True.
678
+ tcstart : int, optional
679
+ Start timepoint index for regressor data. Default is 0.
680
+ tcend : int, optional
681
+ End timepoint index for regressor data. If -1, use all timepoints
682
+ from `tcstart`. Default is -1.
683
+ tchp : float, optional
684
+ High-pass cutoff frequency for filtering. If None, no high-pass filtering
685
+ is applied.
686
+ tclp : float, optional
687
+ Low-pass cutoff frequency for filtering. If None, no low-pass filtering
688
+ is applied.
689
+ showprogressbar : bool, optional
690
+ If True, display a progress bar during processing. Default is True.
691
+ debug : bool, optional
692
+ If True, enable debug output. Default is False.
693
+
694
+ Returns
695
+ -------
696
+ tuple of (NDArray, list of str, NDArray, NDArray)
697
+ - `theregressors`: Processed regressors (possibly orthogonalized).
698
+ - `theregressorlabels`: Updated labels for the regressors.
699
+ - `filtereddata`: Data with confounds removed.
700
+ - `r2value`: R-squared values for each voxel (or None if not computed).
701
+
702
+ Notes
703
+ -----
704
+ - The function applies standard deviation normalization to regressors for
705
+ numerical stability.
706
+ - If `orthogonalize` is True, Gram-Schmidt orthogonalization is applied to
707
+ the regressors.
708
+ - Filtering is applied using a trapezoidal filter if `tchp` or `tclp` are provided.
709
+ - The function uses `linfitfiltpass` internally for the actual regression.
710
+
711
+ Examples
712
+ --------
713
+ >>> regressors = np.random.rand(3, 100)
714
+ >>> labels = ['motion_x', 'motion_y', 'motion_z']
715
+ >>> data = np.random.rand(50, 100)
716
+ >>> tr = 2.0
717
+ >>> processed_regressors, labels, filtered_data, r2 = confoundregress(
718
+ ... regressors, labels, data, tr, nprocs=4
719
+ ... )
720
+ """
721
+ if tcend == -1:
722
+ theregressors = theregressors[:, tcstart:]
723
+ else:
724
+ theregressors = theregressors[:, tcstart:tcend]
725
+ if (tclp is not None) or (tchp is not None):
726
+ mothpfilt = tide_filt.NoncausalFilter(filtertype="arb", transferfunc="trapezoidal")
727
+ if tclp is None:
728
+ tclp = 0.5 / tr
729
+ else:
730
+ tclp = np.min([0.5 / tr, tclp])
731
+ if tchp is None:
732
+ tchp = 0.0
733
+ mothpfilt.setfreqs(0.9 * tchp, tchp, tclp, np.min([0.5 / tr, tclp * 1.1]))
734
+ for i in range(theregressors.shape[0]):
735
+ theregressors[i, :] = mothpfilt.apply(1.0 / tr, theregressors[i, :])
736
+
737
+ # stddev normalize the regressors. Not strictly necessary, but might help with stability.
738
+ for i in range(theregressors.shape[0]):
739
+ theregressors[i, :] = tide_math.normalize(theregressors[i, :], method="stddev")
740
+
741
+ if orthogonalize:
742
+ theregressors = tide_fit.gram_schmidt(theregressors)
743
+ initregressors = len(theregressorlabels)
744
+ theregressorlabels = []
745
+ for theregressor in range(theregressors.shape[0]):
746
+ theregressorlabels.append("orthogconfound_{:02d}".format(theregressor))
747
+ if len(theregressorlabels) == 0:
748
+ print("No regressors survived orthogonalization - skipping confound regression")
749
+ return theregressors, theregressorlabels, thedataarray, None
750
+ print(
751
+ f"After orthogonalization, {len(theregressorlabels)} of {initregressors} regressors remain."
752
+ )
753
+
754
+ # stddev normalize the regressors. Not strictly necessary, but might help with stability.
755
+ for i in range(theregressors.shape[0]):
756
+ theregressors[i, :] = tide_math.normalize(theregressors[i, :], method="stddev")
757
+
758
+ print("start confound filtering")
759
+
760
+ numprocitems = thedataarray.shape[0]
761
+ filtereddata = np.zeros_like(thedataarray)
762
+ r2value = np.zeros(numprocitems)
763
+ numfiltered = linfitfiltpass(
764
+ numprocitems,
765
+ thedataarray,
766
+ None,
767
+ np.transpose(theregressors),
768
+ None,
769
+ None,
770
+ r2value,
771
+ None,
772
+ None,
773
+ None,
774
+ filtereddata,
775
+ confoundregress=True,
776
+ nprocs=nprocs,
777
+ showprogressbar=showprogressbar,
778
+ procbyvoxel=True,
779
+ debug=debug,
780
+ )
781
+
782
+ print()
783
+ print(f"confound filtering on {numfiltered} voxels complete")
784
+ return theregressors, theregressorlabels, filtereddata, r2value