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/maskutil.py CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python
2
2
  # -*- coding: utf-8 -*-
3
3
  #
4
- # Copyright 2016-2024 Blaise Frederick
4
+ # Copyright 2016-2025 Blaise Frederick
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -18,26 +18,135 @@
18
18
  #
19
19
  import bisect
20
20
  import logging
21
+ from typing import Any, Callable, Optional, Tuple, Union
21
22
 
22
23
  import numpy as np
23
24
  from nilearn import masking
25
+ from numpy.typing import ArrayLike, NDArray
26
+ from sklearn.decomposition import PCA
24
27
 
25
28
  import rapidtide.io as tide_io
29
+ import rapidtide.miscmath as tide_math
26
30
  import rapidtide.stats as tide_stats
27
31
 
28
32
  LGR = logging.getLogger("GENERAL")
29
33
 
30
34
 
31
- def resampmask(themask, thetargetres):
35
+ def resampmask(themask: ArrayLike, thetargetres: float) -> NDArray:
36
+ """Resample a mask to a target resolution.
37
+
38
+ Parameters
39
+ ----------
40
+ themask : array_like
41
+ Input mask array to be resampled.
42
+ thetargetres : float
43
+ Target resolution for the resampled mask.
44
+
45
+ Returns
46
+ -------
47
+ NDArray
48
+ Resampled mask array with the specified target resolution.
49
+
50
+ Notes
51
+ -----
52
+ This function currently returns the input mask unchanged. A full implementation
53
+ would perform actual resampling operations to adjust the mask to the target
54
+ resolution.
55
+
56
+ Examples
57
+ --------
58
+ >>> import numpy as np
59
+ >>> mask = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]])
60
+ >>> resampled = resampmask(mask, 0.5)
61
+ >>> print(resampled)
62
+ [[0 1 0]
63
+ [1 1 1]
64
+ [0 1 0]]
65
+ """
32
66
  resampmask = themask
33
67
  return themask
34
68
 
35
69
 
36
- def makeepimask(nim):
70
+ def makeepimask(nim: Any) -> Any:
71
+ """Compute EPI mask from neuroimaging data.
72
+
73
+ This function computes an EPI (Echo Planar Imaging) mask from neuroimaging data
74
+ using the masking.compute_epi_mask function from nilearn.
75
+
76
+ Parameters
77
+ ----------
78
+ nim : Any
79
+ Neuroimaging data object (typically Nifti1Image or similar) from which
80
+ to compute the EPI mask. This can be a nibabel image object or array-like
81
+ data representing neuroimaging volumes.
82
+
83
+ Returns
84
+ -------
85
+ Any
86
+ EPI mask computed from the input neuroimaging data. The return type
87
+ depends on the underlying masking.compute_epi_mask implementation and
88
+ typically represents a binary mask image.
89
+
90
+ Notes
91
+ -----
92
+ This function is a wrapper around nilearn's masking.compute_epi_mask function
93
+ and is commonly used in neuroimaging preprocessing pipelines to automatically
94
+ generate brain masks from EPI functional MRI data.
95
+
96
+ Examples
97
+ --------
98
+ >>> import nibabel as nib
99
+ >>> from nilearn.masking import compute_epi_mask
100
+ >>> # Assuming 'img' is a nibabel image object
101
+ >>> mask = makeepimask(img)
102
+ >>> print(mask.shape)
103
+ """
37
104
  return masking.compute_epi_mask(nim)
38
105
 
39
106
 
40
- def maketmask(filename, timeaxis, maskvector, debug=False):
107
+ def maketmask(
108
+ filename: str, timeaxis: ArrayLike, maskvector: NDArray, debug: bool = False
109
+ ) -> NDArray:
110
+ """Create a temporal mask from time interval data.
111
+
112
+ This function reads time interval data from a file and generates a binary mask
113
+ vector indicating which time points should be included in analysis. The mask
114
+ can be generated from either a simple vector of nonzero values or from time
115
+ intervals specified by start and duration values.
116
+
117
+ Parameters
118
+ ----------
119
+ filename : str
120
+ Path to the file containing time interval data. The file should contain
121
+ either a single vector of values or two rows of data (start times and durations).
122
+ timeaxis : ArrayLike
123
+ Array of time points corresponding to the fMRI time series. Used to map
124
+ time intervals to specific time indices.
125
+ maskvector : NDArray
126
+ Pre-allocated array to store the resulting temporal mask. Should be the
127
+ same length as the fMRI time series.
128
+ debug : bool, optional
129
+ If True, enables debug logging output. Default is False.
130
+
131
+ Returns
132
+ -------
133
+ NDArray
134
+ Binary mask vector where 1.0 indicates time points to include and 0.0
135
+ indicates time points to exclude.
136
+
137
+ Notes
138
+ -----
139
+ The function handles two input formats:
140
+ 1. Single row: Each nonzero value indicates inclusion of the corresponding time point
141
+ 2. Two rows: First row contains start times, second row contains durations
142
+
143
+ Examples
144
+ --------
145
+ >>> import numpy as np
146
+ >>> timeaxis = np.arange(0, 100, 2) # 50 time points
147
+ >>> maskvector = np.zeros(50)
148
+ >>> mask = maketmask('time_intervals.txt', timeaxis, maskvector)
149
+ """
41
150
  inputdata = tide_io.readvecs(filename)
42
151
  theshape = np.shape(inputdata)
43
152
  if theshape[0] == 1:
@@ -59,16 +168,83 @@ def maketmask(filename, timeaxis, maskvector, debug=False):
59
168
 
60
169
 
61
170
  def readamask(
62
- maskfilename,
63
- nim_hdr,
64
- xsize,
65
- istext=False,
66
- valslist=None,
67
- thresh=None,
68
- maskname="the",
69
- tolerance=1.0e-3,
70
- ):
171
+ maskfilename: str,
172
+ nim_hdr: Any,
173
+ xsize: int,
174
+ istext: bool = False,
175
+ valslist: Optional[list] = None,
176
+ thresh: Optional[float] = None,
177
+ maskname: str = "the",
178
+ tolerance: float = 1.0e-3,
179
+ debug: bool = False,
180
+ ) -> NDArray:
181
+ """
182
+ Read and process a mask file, returning a binary mask array.
183
+
184
+ This function reads a mask from either a text file or NIfTI format, applies
185
+ optional thresholding or value selection, and returns a binary mask array
186
+ compatible with the input data dimensions.
187
+
188
+ Parameters
189
+ ----------
190
+ maskfilename : str
191
+ Path to the mask file. Can be in text format (if `istext=True`) or NIfTI format.
192
+ nim_hdr : Any
193
+ Header information from the NIfTI file of the input data. Used for spatial
194
+ dimension matching.
195
+ xsize : int
196
+ Expected size of the first dimension of the mask array.
197
+ istext : bool, optional
198
+ If True, the mask is read as a text file. Default is False.
199
+ valslist : list of int, optional
200
+ List of values to include in the mask. If provided, only voxels matching
201
+ these values are set to 1. Default is None.
202
+ thresh : float, optional
203
+ Threshold value for binarizing the mask. If provided, voxels greater than
204
+ `thresh` are set to 1, others to 0. Default is None.
205
+ maskname : str, optional
206
+ Name of the mask for logging and error messages. Default is "the".
207
+ tolerance : float, optional
208
+ Tolerance for spatial dimension matching between the mask and input data.
209
+ Default is 1e-3.
210
+ debug : bool, optional
211
+ If True, print debug information. Default is False.
212
+
213
+ Returns
214
+ -------
215
+ NDArray
216
+ A binary mask array of type `uint16`, where 1 indicates included voxels
217
+ and 0 indicates excluded voxels.
218
+
219
+ Notes
220
+ -----
221
+ - If `istext=True`, the mask file is expected to contain numeric values
222
+ arranged in a single column or row.
223
+ - If `thresh` is provided, the mask is binarized based on the threshold.
224
+ - If `valslist` is provided, only voxels matching values in the list are set to 1.
225
+ - The function raises a `ValueError` if spatial dimensions of the mask and
226
+ input data do not match within the specified tolerance.
227
+
228
+ Examples
229
+ --------
230
+ >>> mask = readamask(
231
+ ... maskfilename="mask.nii.gz",
232
+ ... nim_hdr=hdr,
233
+ ... xsize=64,
234
+ ... thresh=0.5,
235
+ ... maskname="brain"
236
+ ... )
237
+ >>> print(mask.shape)
238
+ (64, 64, 64)
239
+ """
71
240
  LGR.debug(f"readamask called with filename: {maskfilename} vals: {valslist}")
241
+ if debug:
242
+ print("getmaskset:")
243
+ print(f"{maskname=}")
244
+ print(f"\tincludefilename={maskfilename}")
245
+ print(f"\tincludevals={valslist}")
246
+ print(f"\t{istext=}")
247
+ print(f"\t{tolerance=}")
72
248
  if istext:
73
249
  maskarray = tide_io.readvecs(maskfilename).astype("uint16")
74
250
  theshape = np.shape(maskarray)
@@ -98,22 +274,102 @@ def readamask(
98
274
 
99
275
 
100
276
  def getmaskset(
101
- maskname,
102
- includename,
103
- includevals,
104
- excludename,
105
- excludevals,
106
- datahdr,
107
- numspatiallocs,
108
- extramask=None,
109
- extramaskthresh=0.1,
110
- istext=False,
111
- tolerance=1.0e-3,
112
- ):
277
+ maskname: str,
278
+ includename: Optional[str],
279
+ includevals: Optional[list],
280
+ excludename: Optional[str],
281
+ excludevals: Optional[list],
282
+ datahdr: Any,
283
+ numspatiallocs: int,
284
+ extramask: Optional[str] = None,
285
+ extramaskthresh: float = 0.1,
286
+ istext: bool = False,
287
+ tolerance: float = 1.0e-3,
288
+ debug: bool = False,
289
+ ) -> Tuple[Optional[NDArray], Optional[NDArray], Optional[NDArray]]:
290
+ """
291
+ Construct and return masks for inclusion, exclusion, and an additional mask.
292
+
293
+ This function builds masks based on provided parameters, including optional
294
+ inclusion and exclusion criteria, as well as an extra mask. It performs
295
+ validation to ensure that the resulting masks are not empty or overly restrictive.
296
+
297
+ Parameters
298
+ ----------
299
+ maskname : str
300
+ Name of the mask being constructed, used for logging and labeling.
301
+ includename : str, optional
302
+ File name or identifier for the mask to be used for inclusion.
303
+ includevals : list of float, optional
304
+ List of values to include in the inclusion mask. If ``None``, all values
305
+ are included.
306
+ excludename : str, optional
307
+ File name or identifier for the mask to be used for exclusion.
308
+ excludevals : list of float, optional
309
+ List of values to exclude from the exclusion mask. If ``None``, no values
310
+ are excluded.
311
+ datahdr : Any
312
+ Header information for the data, passed to mask reading functions.
313
+ numspatiallocs : int
314
+ Number of spatial locations in the data.
315
+ extramask : str, optional
316
+ File name or identifier for an additional mask to be applied.
317
+ extramaskthresh : float, default=0.1
318
+ Threshold value for the extra mask, used when reading the mask.
319
+ istext : bool, default=False
320
+ If ``True``, treat input files as text-based.
321
+ tolerance : float, default=1e-03
322
+ Tolerance for floating-point comparisons when reading masks.
323
+ debug : bool, default=False
324
+ If ``True``, print debug information during execution.
325
+
326
+ Returns
327
+ -------
328
+ tuple of (Optional[NDArray], Optional[NDArray], Optional[NDArray])
329
+ A tuple containing:
330
+ - ``internalincludemask``: The inclusion mask, reshaped to ``numspatiallocs``.
331
+ - ``internalexcludemask``: The exclusion mask, reshaped to ``numspatiallocs``.
332
+ - ``internalextramask``: The extra mask, reshaped to ``numspatiallocs``.
333
+
334
+ Notes
335
+ -----
336
+ - If both inclusion and exclusion masks are specified, the function ensures
337
+ that at least one voxel remains after applying both masks.
338
+ - If an extra mask is specified, it is applied in combination with the inclusion
339
+ and exclusion masks.
340
+ - The function raises a ``ValueError`` if any of the resulting masks are invalid:
341
+ e.g., empty inclusion mask, or masks that leave no voxels.
342
+
343
+ Examples
344
+ --------
345
+ >>> maskname = "brain"
346
+ >>> includename = "brain_include.nii"
347
+ >>> includevals = [1]
348
+ >>> excludename = "ventricles.nii"
349
+ >>> excludevals = [1]
350
+ >>> datahdr = header
351
+ >>> numspatiallocs = 10000
352
+ >>> includemask, excludemask, extramask = getmaskset(
353
+ ... maskname, includename, includevals, excludename, excludevals,
354
+ ... datahdr, numspatiallocs
355
+ ... )
356
+ """
113
357
  internalincludemask = None
114
358
  internalexcludemask = None
115
359
  internalextramask = None
116
360
 
361
+ if debug:
362
+ print("getmaskset:")
363
+ print(f"{maskname=}")
364
+ print(f"\t{includename=}")
365
+ print(f"\t{includevals=}")
366
+ print(f"\t{excludename=}")
367
+ print(f"\t{excludevals=}")
368
+ print(f"\t{istext=}")
369
+ print(f"\t{tolerance=}")
370
+ print(f"\t{extramask=}")
371
+ print(f"\t{extramaskthresh=}")
372
+
117
373
  if includename is not None:
118
374
  LGR.info(f"constructing {maskname} include mask")
119
375
  theincludemask = readamask(
@@ -178,3 +434,277 @@ def getmaskset(
178
434
  )
179
435
 
180
436
  return internalincludemask, internalexcludemask, internalextramask
437
+
438
+
439
+ def getregionsignal(
440
+ indata: NDArray,
441
+ filter: Optional[Any] = None,
442
+ Fs: float = 1.0,
443
+ includemask: Optional[NDArray] = None,
444
+ excludemask: Optional[NDArray] = None,
445
+ signalgenmethod: str = "sum",
446
+ pcacomponents: Union[float, str] = 0.8,
447
+ signame: str = "global mean",
448
+ rt_floattype: type = np.float64,
449
+ debug: bool = False,
450
+ ) -> Tuple[NDArray, NDArray]:
451
+ """
452
+ Compute a global signal from a 2D array of voxel data using specified methods.
453
+
454
+ This function computes a global signal from input data by applying optional masking,
455
+ and then combining voxel signals using one of several methods: sum, meanscale, PCA,
456
+ or random. The resulting signal can be filtered and normalized.
457
+
458
+ Parameters
459
+ ----------
460
+ indata : ndarray
461
+ Input 2D array of shape (n_voxels, n_timepoints) containing voxel time series.
462
+ filter : optional
463
+ A filter object with an `apply` method to apply to the computed signal.
464
+ Default is None.
465
+ Fs : float, optional
466
+ Sampling frequency (Hz) used for filtering. Default is 1.0.
467
+ includemask : ndarray, optional
468
+ Binary mask to include specific voxels. Voxels not included will be ignored.
469
+ Default is None.
470
+ excludemask : ndarray, optional
471
+ Binary mask to exclude specific voxels. Voxels marked as 1 will be excluded.
472
+ Default is None.
473
+ signalgenmethod : str, optional
474
+ Method used to generate the global signal. Options are:
475
+ - "sum": Mean of selected voxels (default).
476
+ - "meanscale": Scale each voxel by its mean before averaging.
477
+ - "pca": Use PCA to reduce dimensionality and compute signal.
478
+ - "random": Generate a random signal.
479
+ Default is "sum".
480
+ pcacomponents : float or str, optional
481
+ Number of PCA components to use. If float, specifies number of components;
482
+ if "mle", uses maximum likelihood estimation. Default is 0.8.
483
+ signame : str, optional
484
+ Name of the signal for logging purposes. Default is "global mean".
485
+ rt_floattype : type, optional
486
+ Data type for internal computations. Default is np.float64.
487
+ debug : bool, optional
488
+ If True, print debugging information. Default is False.
489
+
490
+ Returns
491
+ -------
492
+ tuple of ndarray
493
+ A tuple containing:
494
+ - normalized_global_signal : ndarray
495
+ The normalized global signal of shape (n_timepoints,).
496
+ - final_mask : ndarray
497
+ The final voxel mask used in computation, shape (n_voxels,).
498
+
499
+ Notes
500
+ -----
501
+ - The function applies `includemask` and `excludemask` sequentially to define
502
+ which voxels are used in signal computation.
503
+ - For "pca" method, PCA is applied to the transposed scaled voxel data.
504
+ - If filtering is applied, the signal is filtered in-place using the provided filter.
505
+
506
+ Examples
507
+ --------
508
+ >>> import numpy as np
509
+ >>> from sklearn.decomposition import PCA
510
+ >>> indata = np.random.rand(100, 50)
511
+ >>> signal, mask = getregionsignal(indata, signalgenmethod="sum")
512
+ >>> print(signal.shape)
513
+ (50,)
514
+ """
515
+ # Start with all voxels
516
+ themask = np.ones_like(indata[:, 0])
517
+
518
+ # modify the mask if needed
519
+ if includemask is not None:
520
+ themask = themask * includemask
521
+ if excludemask is not None:
522
+ themask = themask * (1 - excludemask)
523
+
524
+ # combine all the voxels using one of the three methods
525
+ globalmean = (indata[0, :]).astype(rt_floattype)
526
+ thesize = np.shape(themask)
527
+ numvoxelsused = int(np.sum(np.where(themask > 0.0, 1, 0)))
528
+ selectedvoxels = indata[np.where(themask > 0.0), :][0]
529
+ if debug:
530
+ print(f"getregionsignal: {selectedvoxels.shape=}")
531
+ LGR.info(f"constructing global mean signal using {signalgenmethod}")
532
+ if signalgenmethod == "sum":
533
+ globalmean = np.mean(selectedvoxels, axis=0)
534
+ globalmean -= np.mean(globalmean)
535
+ if debug:
536
+ print("Sum method")
537
+ print(f"getregionsignal: {globalmean.shape=}")
538
+ elif signalgenmethod == "meanscale":
539
+ themean = np.mean(indata, axis=1)
540
+ for vox in range(0, thesize[0]):
541
+ if themask[vox] > 0.0:
542
+ if themean[vox] != 0.0:
543
+ globalmean += indata[vox, :] / themean[vox] - 1.0
544
+ if debug:
545
+ print("Meanscale method")
546
+ print(f"getregionsignal: {globalmean.shape=}")
547
+ elif signalgenmethod == "pca":
548
+ themean = np.mean(indata, axis=1)
549
+ thevar = np.var(indata, axis=1)
550
+ scaledvoxels = np.zeros_like(selectedvoxels)
551
+ for vox in range(0, selectedvoxels.shape[0]):
552
+ scaledvoxels[vox, :] = selectedvoxels[vox, :] - themean[vox]
553
+ if thevar[vox] > 0.0:
554
+ scaledvoxels[vox, :] = selectedvoxels[vox, :] / thevar[vox]
555
+ try:
556
+ thefit = PCA(n_components=pcacomponents).fit(scaledvoxels)
557
+ except ValueError:
558
+ if pcacomponents == "mle":
559
+ LGR.warning("mle estimation failed - falling back to pcacomponents=0.8")
560
+ thefit = PCA(n_components=0.8).fit(scaledvoxels)
561
+ else:
562
+ raise ValueError("unhandled math exception in PCA refinement - exiting")
563
+
564
+ varex = 100.0 * np.cumsum(thefit.explained_variance_ratio_)[len(thefit.components_) - 1]
565
+ # thetransform = thefit.transform(np.transpose(scaledvoxels))
566
+ thetransform = thefit.transform(scaledvoxels)
567
+ cleanedvoxels = thefit.inverse_transform(thetransform) * thevar[:, None]
568
+ globalmean = np.mean(cleanedvoxels, axis=0)
569
+ globalmean -= np.mean(globalmean)
570
+ if debug:
571
+ print("PCA method")
572
+ print(
573
+ f"getregionsignal: {cleanedvoxels.shape=}, {thetransform.shape=}, {scaledvoxels.shape=}, {globalmean.shape=}"
574
+ )
575
+ print(
576
+ f"getregionsignal: {(thefit.components_).shape=}, {thefit.n_samples_=}, {thefit.n_features_in_=}"
577
+ )
578
+ print(f"getregionsignal: {varex=}")
579
+ LGR.info(
580
+ f"Using {len(thefit.components_)} component(s), accounting for "
581
+ f"{varex:.2f}% of the variance"
582
+ )
583
+ elif signalgenmethod == "random":
584
+ globalmean = np.random.standard_normal(size=len(globalmean))
585
+ if debug:
586
+ print("Random method")
587
+ print(f"getregionsignal: {globalmean.shape=}")
588
+ else:
589
+ raise ValueError(f"illegal signal generation method: {signalgenmethod}")
590
+ LGR.info(f"used {numvoxelsused} voxels to calculate {signame} signal")
591
+ if filter is not None:
592
+ globalmean = filter.apply(Fs, globalmean)
593
+ if debug:
594
+ print(f"getregionsignal: {globalmean=}")
595
+ return tide_math.stdnormalize(globalmean), themask
596
+
597
+
598
+ def saveregionaltimeseries(
599
+ tcdesc: str,
600
+ tcname: str,
601
+ fmridata: NDArray,
602
+ includemask: NDArray,
603
+ fmrifreq: float,
604
+ outputname: str,
605
+ filter: Optional[Any] = None,
606
+ initfile: bool = False,
607
+ excludemask: Optional[NDArray] = None,
608
+ filedesc: str = "regional",
609
+ suffix: str = "",
610
+ signalgenmethod: str = "sum",
611
+ pcacomponents: Union[float, str] = 0.8,
612
+ rt_floattype: type = np.float64,
613
+ debug: bool = False,
614
+ ) -> Tuple[NDArray, NDArray]:
615
+ """
616
+ Save regional time series data from fMRI data to a BIDS-compatible TSV file.
617
+
618
+ This function extracts regional signal time courses from fMRI data using the
619
+ specified masking and filtering parameters, then writes the results to a
620
+ BIDS-style TSV file. The function supports various signal generation methods
621
+ and can handle both inclusive and exclusive masking.
622
+
623
+ Parameters
624
+ ----------
625
+ tcdesc : str
626
+ Description of the time course for the output file header
627
+ tcname : str
628
+ Name of the time course to be used in the output file column header
629
+ fmridata : NDArray
630
+ 4D fMRI data array (time x x x y z)
631
+ includemask : NDArray
632
+ Binary mask defining regions to include in the analysis
633
+ fmrifreq : float
634
+ Sampling frequency of the fMRI data (Hz)
635
+ outputname : str
636
+ Base name for the output file (without extension)
637
+ filter : Optional[Any], default=None
638
+ Filter to apply to the time series data
639
+ initfile : bool, default=False
640
+ If True, initializes a new file; if False, appends to existing file
641
+ excludemask : Optional[NDArray], default=None
642
+ Binary mask defining regions to exclude from the analysis
643
+ filedesc : str, default="regional"
644
+ Description string for the output file name
645
+ suffix : str, default=""
646
+ Suffix to append to the column name in the output file
647
+ signalgenmethod : str, default="sum"
648
+ Method for generating the signal ('sum', 'mean', 'pca', etc.)
649
+ pcacomponents : Union[float, str], default=0.8
650
+ Number of PCA components to use (or fraction of variance explained)
651
+ rt_floattype : np.dtype, default=np.float64
652
+ Data type for floating point operations
653
+ debug : bool, default=False
654
+ If True, enables debug mode for additional logging
655
+
656
+ Returns
657
+ -------
658
+ Tuple[NDArray, NDArray]
659
+ Tuple containing:
660
+ - thetimecourse : NDArray
661
+ The extracted time course data
662
+ - themask : NDArray
663
+ The mask used for extraction
664
+
665
+ Notes
666
+ -----
667
+ The function uses `getregionsignal` to compute the regional signal and
668
+ `tide_io.writebidstsv` to write the output file in BIDS TSV format.
669
+ The output file name follows the pattern:
670
+ {outputname}_desc-{filedesc}_timeseries.tsv
671
+
672
+ Examples
673
+ --------
674
+ >>> import numpy as np
675
+ >>> fmri_data = np.random.rand(100, 10, 10, 10)
676
+ >>> mask = np.ones((10, 10, 10))
677
+ >>> timecourse, mask_used = saveregionaltimeseries(
678
+ ... tcdesc="mean_signal",
679
+ ... tcname="signal",
680
+ ... fmridata=fmri_data,
681
+ ... includemask=mask,
682
+ ... fmrifreq=2.0,
683
+ ... outputname="sub-01_task-rest",
684
+ ... filter=None,
685
+ ... initfile=True
686
+ ... )
687
+ """
688
+ thetimecourse, themask = getregionsignal(
689
+ fmridata,
690
+ filter=filter,
691
+ Fs=fmrifreq,
692
+ includemask=includemask,
693
+ excludemask=excludemask,
694
+ signalgenmethod=signalgenmethod,
695
+ pcacomponents=pcacomponents,
696
+ signame=tcdesc,
697
+ rt_floattype=rt_floattype,
698
+ debug=debug,
699
+ )
700
+ tide_io.writebidstsv(
701
+ f"{outputname}_desc-{filedesc}_timeseries",
702
+ thetimecourse,
703
+ fmrifreq,
704
+ columns=[f"{tcname}{suffix}"],
705
+ extraheaderinfo={
706
+ "Description": "Regional timecourse averages",
707
+ },
708
+ append=(not initfile),
709
+ )
710
+ return thetimecourse, themask