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,939 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ #
4
+ # Copyright 2016-2025 Blaise Frederick
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ #
19
+ import gc
20
+ import logging
21
+ import sys
22
+ from typing import Any
23
+
24
+ import numpy as np
25
+ import statsmodels as sm
26
+ from numpy.typing import NDArray
27
+ from scipy.stats import pearsonr
28
+ from sklearn.decomposition import PCA, FastICA
29
+
30
+ import rapidtide.fit as tide_fit
31
+ import rapidtide.genericmultiproc as tide_genericmultiproc
32
+ import rapidtide.io as tide_io
33
+ import rapidtide.miscmath as tide_math
34
+ import rapidtide.resample as tide_resample
35
+ import rapidtide.stats as tide_stats
36
+
37
+ LGR = logging.getLogger("GENERAL")
38
+
39
+
40
+ def _procOneVoxelTimeShift(
41
+ vox: int,
42
+ voxelargs: tuple,
43
+ **kwargs: Any,
44
+ ) -> tuple[int, NDArray, NDArray, NDArray, NDArray]:
45
+ options = {
46
+ "detrendorder": 1,
47
+ "offsettime": 0.0,
48
+ "debug": False,
49
+ }
50
+ options.update(kwargs)
51
+ detrendorder = int(options["detrendorder"])
52
+ offsettime = options["offsettime"]
53
+ debug = options["debug"]
54
+ if debug:
55
+ print(f"{detrendorder=} {offsettime=}")
56
+ (
57
+ fmritc,
58
+ lagtime,
59
+ padtrs,
60
+ fmritr,
61
+ ) = voxelargs
62
+ if detrendorder > 0:
63
+ normtc = tide_fit.detrend(fmritc, order=detrendorder, demean=True)
64
+ else:
65
+ normtc = fmritc + 0.0
66
+ shifttr = -(-offsettime + lagtime) / fmritr # lagtime is in seconds
67
+ [shiftedtc, weights, paddedshiftedtc, paddedweights] = tide_resample.timeshift(
68
+ normtc, shifttr, padtrs
69
+ )
70
+ return vox, shiftedtc, weights, paddedshiftedtc, paddedweights
71
+
72
+
73
+ def _packvoxeldata(voxnum: int, voxelargs: tuple) -> list:
74
+ """
75
+ Pack voxel data into a list structure.
76
+
77
+ Parameters
78
+ ----------
79
+ voxnum : int
80
+ The voxel index to extract data from.
81
+ voxelargs : tuple
82
+ A tuple containing voxel data with the following structure:
83
+ - voxelargs[0]: 2D array of shape (n_voxels, n_features) containing voxel features
84
+ - voxelargs[1]: 1D array of shape (n_voxels,) containing voxel labels or values
85
+ - voxelargs[2]: Additional voxel parameter (type depends on context)
86
+ - voxelargs[3]: Additional voxel parameter (type depends on context)
87
+
88
+ Returns
89
+ -------
90
+ list
91
+ A list containing:
92
+ - [0]: 1D array of shape (n_features,) representing voxel features at voxnum
93
+ - [1]: scalar value representing voxel label or value at voxnum
94
+ - [2]: third element from voxelargs tuple
95
+ - [3]: fourth element from voxelargs tuple
96
+
97
+ Notes
98
+ -----
99
+ This function is typically used for extracting and packaging voxel data for further processing
100
+ in neuroimaging or 3D data analysis workflows.
101
+
102
+ Examples
103
+ --------
104
+ >>> voxel_features = np.array([[1, 2, 3], [4, 5, 6]])
105
+ >>> voxel_labels = np.array([10, 20])
106
+ >>> extra_param1 = "param1"
107
+ >>> extra_param2 = "param2"
108
+ >>> result = _packvoxeldata(0, (voxel_features, voxel_labels, extra_param1, extra_param2))
109
+ >>> print(result)
110
+ [[1, 2, 3], 10, 'param1', 'param2']
111
+ """
112
+ return [(voxelargs[0])[voxnum, :], (voxelargs[1])[voxnum], voxelargs[2], voxelargs[3]]
113
+
114
+
115
+ def _unpackvoxeldata(retvals: tuple, voxelproducts: list) -> None:
116
+ """
117
+ Unpack voxel data from retvals into voxelproducts arrays.
118
+
119
+ Parameters
120
+ ----------
121
+ retvals : tuple
122
+ Tuple containing voxel data to be unpacked. Expected to contain at least 5 elements
123
+ where retvals[0] is the index for assignment and retvals[1:5] are the data arrays.
124
+ voxelproducts : list
125
+ List of arrays where voxel data will be unpacked. Expected to contain exactly 4 arrays
126
+ that will be modified in-place.
127
+
128
+ Returns
129
+ -------
130
+ None
131
+ This function modifies the voxelproducts arrays in-place and does not return anything.
132
+
133
+ Notes
134
+ -----
135
+ This function performs in-place assignment of voxel data. The first element of retvals
136
+ is used as an index for row-wise assignment into each of the four arrays in voxelproducts.
137
+ All arrays in voxelproducts must have sufficient dimensions to accommodate the assignment.
138
+
139
+ Examples
140
+ --------
141
+ >>> import numpy as np
142
+ >>> voxel_data = [np.zeros((10, 5)), np.zeros((10, 5)), np.zeros((10, 5)), np.zeros((10, 5))]
143
+ >>> retvals = (2, np.array([1, 2, 3, 4, 5]), np.array([6, 7, 8, 9, 10]),
144
+ ... np.array([11, 12, 13, 14, 15]), np.array([16, 17, 18, 19, 20]))
145
+ >>> _unpackvoxeldata(retvals, voxel_data)
146
+ >>> print(voxel_data[0][2, :]) # Should print [1 2 3 4 5]
147
+ """
148
+ (voxelproducts[0])[retvals[0], :] = retvals[1]
149
+ (voxelproducts[1])[retvals[0], :] = retvals[2]
150
+ (voxelproducts[2])[retvals[0], :] = retvals[3]
151
+ (voxelproducts[3])[retvals[0], :] = retvals[4]
152
+
153
+
154
+ def findecho(
155
+ nlags: int,
156
+ shiftedtcs: NDArray,
157
+ sigmav: NDArray,
158
+ arcoefs: NDArray,
159
+ pacf: NDArray,
160
+ sigma: NDArray,
161
+ phi: NDArray,
162
+ ) -> None:
163
+ """
164
+ Compute autoregressive parameters and related statistics for each voxel using Levinson-Durbin recursion.
165
+
166
+ This function applies the Levinson-Durbin algorithm to estimate autoregressive coefficients
167
+ and associated statistics for time series data from multiple voxels. The algorithm computes
168
+ the variance, autoregressive coefficients, partial autocorrelations, and other related
169
+ parameters for each voxel's time series.
170
+
171
+ Parameters
172
+ ----------
173
+ nlags : int
174
+ Number of lags to compute for the autoregressive model.
175
+ shiftedtcs : NDArray
176
+ Input time series data with shape (n_voxels, n_timepoints), where each row represents
177
+ a voxel's time series.
178
+ sigmav : NDArray
179
+ Output array for variance estimates, shape (n_voxels,).
180
+ arcoefs : NDArray
181
+ Output array for autoregressive coefficients, shape (n_voxels, nlags).
182
+ pacf : NDArray
183
+ Output array for partial autocorrelations, shape (n_voxels, nlags).
184
+ sigma : NDArray
185
+ Output array for sigma values, shape (n_voxels, nlags).
186
+ phi : NDArray
187
+ Output array for phi values, shape (n_voxels, nlags).
188
+
189
+ Returns
190
+ -------
191
+ None
192
+ This function modifies the input arrays in-place and does not return any value.
193
+
194
+ Notes
195
+ -----
196
+ The function uses `statsmodels.tsa.stattools.levinson_durbin` to compute the autoregressive
197
+ parameters. This algorithm is efficient for computing autoregressive parameters and is
198
+ commonly used in time series analysis for estimating model parameters.
199
+
200
+ Examples
201
+ --------
202
+ >>> import numpy as np
203
+ >>> from statsmodels.tsa import stattools
204
+ >>> nlags = 5
205
+ >>> shiftedtcs = np.random.randn(100, 1000)
206
+ >>> sigmav = np.zeros(100)
207
+ >>> arcoefs = np.zeros((100, 5))
208
+ >>> pacf = np.zeros((100, 5))
209
+ >>> sigma = np.zeros((100, 5))
210
+ >>> phi = np.zeros((100, 5))
211
+ >>> findecho(nlags, shiftedtcs, sigmav, arcoefs, pacf, sigma, phi)
212
+ """
213
+ inputshape = np.shape(shiftedtcs)
214
+ for voxel in range(inputshape[0]):
215
+ sigmav[voxel], arcoefs[voxel, :], pacf[voxel, :], sigma[voxel, :], phi[voxel, :] = (
216
+ sm.tsa.stattools.levinson_durbin(shiftedtcs[voxel, :], nlags=nlags, isacov=False)
217
+ )
218
+
219
+
220
+ def alignvoxels(
221
+ fmridata: NDArray,
222
+ fmritr: float,
223
+ shiftedtcs: NDArray,
224
+ weights: NDArray,
225
+ paddedshiftedtcs: NDArray,
226
+ paddedweights: NDArray,
227
+ lagtimes: NDArray,
228
+ lagmask: NDArray,
229
+ detrendorder: int = 1,
230
+ offsettime: float = 0.0,
231
+ nprocs: int = 1,
232
+ alwaysmultiproc: bool = False,
233
+ showprogressbar: bool = True,
234
+ chunksize: int = 1000,
235
+ padtrs: int = 60,
236
+ debug: bool = False,
237
+ rt_floattype: np.dtype = np.float64,
238
+ ) -> int:
239
+ """
240
+ Apply temporal alignment (timeshift) to all voxels in fMRI data based on correlation peaks.
241
+
242
+ This routine applies a time shift to every voxel in the fMRI data based on the lag times
243
+ determined from cross-correlation with a reference signal. The function modifies the input
244
+ arrays in-place to store the aligned timecourses and associated weights.
245
+
246
+ Parameters
247
+ ----------
248
+ fmridata : 4D NDArray
249
+ fMRI data, filtered to the passband, with shape (nx, ny, nz, nt)
250
+ fmritr : float
251
+ Data repetition time (TR), in seconds
252
+ shiftedtcs : 4D NDArray
253
+ Destination array for time-aligned voxel timecourses, shape (nx, ny, nz, nt)
254
+ weights : 4D NDArray
255
+ Weights for each timepoint in the final regressor, shape (nx, ny, nz, nt)
256
+ paddedshiftedtcs : 4D NDArray
257
+ Time-aligned voxel timecourses with padding, shape (nx, ny, nz, nt + 2*padtrs)
258
+ paddedweights : 4D NDArray
259
+ Weights for each timepoint in the padded regressor, shape (nx, ny, nz, nt + 2*padtrs)
260
+ lagtimes : 3D NDArray
261
+ Time delay of maximum crosscorrelation in seconds, shape (nx, ny, nz)
262
+ lagmask : 3D NDArray
263
+ Mask of voxels with successful correlation fits, shape (nx, ny, nz)
264
+ detrendorder : int, optional
265
+ Order of polynomial used to detrend the data (default is 1)
266
+ offsettime : float, optional
267
+ Global time shift to apply to all timecourses in seconds (default is 0.0)
268
+ nprocs : int, optional
269
+ Number of processes to use for multiprocessing (default is 1)
270
+ alwaysmultiproc : bool, optional
271
+ If True, always use multiprocessing even for small datasets (default is False)
272
+ showprogressbar : bool, optional
273
+ If True, show a progress bar during processing (default is True)
274
+ chunksize : int, optional
275
+ Number of voxels to process per chunk in multiprocessing (default is 1000)
276
+ padtrs : int, optional
277
+ Number of timepoints to pad on each end of the timecourses (default is 60)
278
+ debug : bool, optional
279
+ If True, enable additional debugging output (default is False)
280
+ rt_floattype : np.dtype, optional
281
+ Function to coerce variable types (default is np.float64)
282
+
283
+ Returns
284
+ -------
285
+ volumetotal : int
286
+ Total number of voxels processed
287
+
288
+ Notes
289
+ -----
290
+ This function modifies the input arrays `shiftedtcs`, `weights`, `paddedshiftedtcs`, and
291
+ `paddedweights` in-place. The `lagtimes` and `lagmask` arrays are used to determine the
292
+ appropriate time shifts for each voxel.
293
+
294
+ Examples
295
+ --------
296
+ >>> import numpy as np
297
+ >>> from rapidtide import alignvoxels
298
+ >>> fmridata = np.random.rand(64, 64, 32, 100)
299
+ >>> fmritr = 2.0
300
+ >>> shiftedtcs = np.zeros_like(fmridata)
301
+ >>> weights = np.ones_like(fmridata)
302
+ >>> paddedshiftedtcs = np.zeros((64, 64, 32, 100 + 2*60))
303
+ >>> paddedweights = np.ones((64, 64, 32, 100 + 2*60))
304
+ >>> lagtimes = np.random.rand(64, 64, 32)
305
+ >>> lagmask = np.ones((64, 64, 32))
306
+ >>> volumetotal = alignvoxels(
307
+ ... fmridata, fmritr, shiftedtcs, weights, paddedshiftedtcs, paddedweights,
308
+ ... lagtimes, lagmask, nprocs=4
309
+ ... )
310
+ >>> print(f"Processed {volumetotal} voxels")
311
+ """
312
+ inputshape = np.shape(fmridata)
313
+ voxelargs = [fmridata, lagtimes, padtrs, fmritr]
314
+ voxelfunc = _procOneVoxelTimeShift
315
+ packfunc = _packvoxeldata
316
+ unpackfunc = _unpackvoxeldata
317
+ voxeltargets = [
318
+ shiftedtcs,
319
+ weights,
320
+ paddedshiftedtcs,
321
+ paddedweights,
322
+ ]
323
+ if debug:
324
+ print("alignvoxels: {inputshape}")
325
+ print("volumetotal: {volumetotal}")
326
+
327
+ # timeshift the valid voxels
328
+ # NOTE need to figure out how to use kwargs to pass extra arguments
329
+ volumetotal = tide_genericmultiproc.run_multiproc(
330
+ voxelfunc,
331
+ packfunc,
332
+ unpackfunc,
333
+ voxelargs,
334
+ voxeltargets,
335
+ inputshape,
336
+ lagmask,
337
+ LGR,
338
+ nprocs,
339
+ alwaysmultiproc,
340
+ showprogressbar,
341
+ chunksize,
342
+ detrendorder=detrendorder,
343
+ offsettime=offsettime,
344
+ debug=debug,
345
+ )
346
+
347
+ LGR.info(
348
+ "Timeshift applied to " + str(int(volumetotal)) + " voxels",
349
+ )
350
+
351
+ # garbage collect
352
+ uncollected = gc.collect()
353
+ if uncollected != 0:
354
+ LGR.info(f"garbage collected - unable to collect {uncollected} objects")
355
+ else:
356
+ LGR.info("garbage collected")
357
+
358
+ return volumetotal
359
+
360
+
361
+ def makerefinemask(
362
+ lagstrengths: NDArray,
363
+ lagtimes: NDArray,
364
+ lagsigma: NDArray,
365
+ lagmask: NDArray,
366
+ offsettime: float = 0.0,
367
+ ampthresh: float = 0.3,
368
+ lagmaskside: str = "both",
369
+ lagminthresh: float = 0.5,
370
+ lagmaxthresh: float = 5.0,
371
+ sigmathresh: float = 100,
372
+ cleanrefined: bool = False,
373
+ bipolar: bool = False,
374
+ includemask: NDArray | None = None,
375
+ excludemask: NDArray | None = None,
376
+ fixdelay: bool = False,
377
+ debug: bool = False,
378
+ rt_floattype: np.dtype = np.float64,
379
+ ) -> tuple[int, NDArray | None, int, int, int, int, int]:
380
+ """
381
+ Determine which voxels should be used for regressor refinement based on correlation strength,
382
+ time delay, and peak width criteria.
383
+
384
+ This routine evaluates a set of voxels defined by their correlation properties and applies
385
+ various thresholds to determine which ones are suitable for refinement. It supports optional
386
+ masking, bipolar correlation handling, and debugging output.
387
+
388
+ Parameters
389
+ ----------
390
+ lagstrengths : ndarray
391
+ 3D numpy float array of maximum correlation coefficients in every voxel.
392
+ lagtimes : ndarray
393
+ 3D numpy float array of time delays (in seconds) of maximum crosscorrelation.
394
+ lagsigma : ndarray
395
+ 3D numpy float array of Gaussian widths (in seconds) of the crosscorrelation peaks.
396
+ lagmask : ndarray
397
+ 3D numpy float array masking voxels with successful correlation fits.
398
+ offsettime : float, optional
399
+ Offset time in seconds to apply to all regressors. Default is 0.0.
400
+ ampthresh : float, optional
401
+ Lower limit of correlation values to consider for refine mask inclusion.
402
+ If negative, treated as percentile. Default is 0.3.
403
+ lagmaskside : str, optional
404
+ Which side of the lag values to consider: 'upper', 'lower', or 'both'.
405
+ Default is 'both'.
406
+ lagminthresh : float, optional
407
+ Lower limit of absolute lag values to consider for inclusion. Default is 0.5.
408
+ lagmaxthresh : float, optional
409
+ Upper limit of absolute lag values to consider for inclusion. Default is 5.0.
410
+ sigmathresh : float, optional
411
+ Upper limit of lag peak width (in seconds) for inclusion. Default is 100.
412
+ cleanrefined : bool, optional
413
+ If True, uses the full location mask for refinement; otherwise, uses the refined mask.
414
+ Default is False.
415
+ bipolar : bool, optional
416
+ If True, considers both positive and negative correlation peaks. Default is False.
417
+ includemask : ndarray, optional
418
+ 3D array masking voxels to include in refinement. Default is None (all voxels).
419
+ excludemask : ndarray, optional
420
+ 3D array masking voxels to exclude from refinement. Default is None (no voxels).
421
+ fixdelay : bool, optional
422
+ If True, uses the raw `lagmask` without applying delay thresholds. Default is False.
423
+ debug : bool, optional
424
+ Enable additional debugging output. Default is False.
425
+ rt_floattype : np.dtype, optional
426
+ Data type for internal arrays. Default is `np.float64`.
427
+
428
+ Returns
429
+ -------
430
+ volumetotal : int
431
+ Number of voxels processed for refinement.
432
+ maskarray : ndarray or None
433
+ 3D mask of voxels used for refinement. Returns None if no voxels remain after filtering.
434
+ locationfails : int
435
+ Number of voxels eliminated due to include/exclude mask constraints.
436
+ ampfails : int
437
+ Number of voxels eliminated due to low correlation amplitude.
438
+ lagfails : int
439
+ Number of voxels eliminated due to lag value out of range.
440
+ sigmafails : int
441
+ Number of voxels eliminated due to wide correlation peak.
442
+ numinmask : int
443
+ Total number of voxels in the original `lagmask`.
444
+
445
+ Notes
446
+ -----
447
+ - The function applies multiple filtering steps: amplitude, lag time, and sigma (peak width).
448
+ - If `ampthresh` is negative, it is interpreted as a percentile threshold.
449
+ - The `lagmaskside` parameter controls which direction of the lag values to consider:
450
+ 'upper' for positive lags, 'lower' for negative lags, 'both' for both.
451
+ - If no voxels remain after filtering, an error is printed and the function returns early.
452
+
453
+ Examples
454
+ --------
455
+ >>> import numpy as np
456
+ >>> lagstrengths = np.random.rand(10, 10, 10)
457
+ >>> lagtimes = np.random.rand(10, 10, 10) * 10
458
+ >>> lagsigma = np.random.rand(10, 10, 10) * 50
459
+ >>> lagmask = np.ones((10, 10, 10))
460
+ >>> volumetotal, maskarray, locfails, ampfails, lagfails, sigfails, numinmask = makerefinemask(
461
+ ... lagstrengths, lagtimes, lagsigma, lagmask, ampthresh=0.4, lagminthresh=1.0
462
+ ... )
463
+ """
464
+ if ampthresh < 0.0:
465
+ if bipolar:
466
+ theampthresh = tide_stats.getfracval(np.fabs(lagstrengths), -ampthresh, nozero=True)
467
+ else:
468
+ theampthresh = tide_stats.getfracval(lagstrengths, -ampthresh, nozero=True)
469
+ LGR.info(f"setting ampthresh to the {-100.0 * ampthresh}th percentile ({theampthresh})")
470
+ else:
471
+ theampthresh = ampthresh
472
+ if debug:
473
+ print(f"makerefinemask: {theampthresh=}")
474
+ if bipolar:
475
+ ampmask = np.where(np.fabs(lagstrengths) >= theampthresh, np.int16(1), np.int16(0))
476
+ else:
477
+ ampmask = np.where(lagstrengths >= theampthresh, np.int16(1), np.int16(0))
478
+ if fixdelay:
479
+ delaymask = lagmask + 0
480
+ else:
481
+ if lagmaskside == "upper":
482
+ delaymask = np.where(
483
+ (lagtimes - offsettime) > lagminthresh,
484
+ np.int16(1),
485
+ np.int16(0),
486
+ ) * np.where(
487
+ (lagtimes - offsettime) < lagmaxthresh,
488
+ np.int16(1),
489
+ np.int16(0),
490
+ )
491
+ elif lagmaskside == "lower":
492
+ delaymask = np.where(
493
+ (lagtimes - offsettime) < -lagminthresh,
494
+ np.int16(1),
495
+ np.int16(0),
496
+ ) * np.where(
497
+ (lagtimes - offsettime) > -lagmaxthresh,
498
+ np.int16(1),
499
+ np.int16(0),
500
+ )
501
+ else:
502
+ abslag = abs(lagtimes - offsettime)
503
+ delaymask = np.where(abslag > lagminthresh, np.int16(1), np.int16(0)) * np.where(
504
+ abslag < lagmaxthresh, np.int16(1), np.int16(0)
505
+ )
506
+ if debug:
507
+ print(f"makerefinemask: {lagmaskside=}")
508
+ print(f"makerefinemask: {lagminthresh=}")
509
+ print(f"makerefinemask: {lagmaxthresh=}")
510
+ print(f"makerefinemask: {offsettime=}")
511
+ sigmamask = np.where(lagsigma < sigmathresh, np.int16(1), np.int16(0))
512
+ locationmask = lagmask + 0
513
+ if includemask is not None:
514
+ locationmask = locationmask * includemask
515
+ if excludemask is not None:
516
+ locationmask = locationmask * (1 - excludemask)
517
+ locationmask = locationmask.astype(np.int16)
518
+ LGR.info("location mask created")
519
+
520
+ # first generate the refine mask
521
+ locationfails = np.sum(1 - locationmask)
522
+ ampfails = np.sum(1 - ampmask * locationmask)
523
+ lagfails = np.sum(1 - delaymask * locationmask)
524
+ sigmafails = np.sum(1 - sigmamask * locationmask)
525
+ refinemask = locationmask * ampmask * delaymask * sigmamask
526
+ if tide_stats.getmasksize(refinemask) == 0:
527
+ print("ERROR: no voxels in the refine mask:")
528
+ print(
529
+ "\n ",
530
+ locationfails,
531
+ " locationfails",
532
+ "\n ",
533
+ ampfails,
534
+ " ampfails",
535
+ "\n ",
536
+ lagfails,
537
+ " lagfails",
538
+ "\n ",
539
+ sigmafails,
540
+ " sigmafails",
541
+ )
542
+ if (includemask is None) and (excludemask is None):
543
+ print("\nRelax ampthresh, delaythresh, or sigmathresh - exiting")
544
+ else:
545
+ print(
546
+ "\nChange include/exclude masks or relax ampthresh, delaythresh, or sigmathresh - exiting"
547
+ )
548
+ return 0, None, locationfails, ampfails, lagfails, sigmafails, 0
549
+
550
+ if cleanrefined:
551
+ shiftmask = locationmask
552
+ else:
553
+ shiftmask = refinemask
554
+ volumetotal = np.sum(shiftmask)
555
+ LGR.info(
556
+ f"{int(volumetotal)} voxels will be used for refinement:"
557
+ + f"\n {locationfails} locationfails"
558
+ + f"\n {ampfails} ampfails"
559
+ + f"\n {lagfails} lagfails"
560
+ + f"\n {sigmafails} sigmafails"
561
+ )
562
+ numinmask = np.sum(lagmask)
563
+ if numinmask is None:
564
+ numinmask = 0
565
+
566
+ return volumetotal, shiftmask, locationfails, ampfails, lagfails, sigmafails, numinmask
567
+
568
+
569
+ def prenorm(
570
+ shiftedtcs: NDArray,
571
+ refinemask: NDArray,
572
+ lagtimes: NDArray,
573
+ lagmaxthresh: float,
574
+ lagstrengths: NDArray,
575
+ R2vals: NDArray,
576
+ refineprenorm: str,
577
+ refineweighting: str,
578
+ debug: bool = False,
579
+ ) -> None:
580
+ """
581
+ Apply pre-normalization and weighting to shifted time correlation data.
582
+
583
+ This function performs normalization and weighting of time correlation data
584
+ based on specified criteria. It modifies the input `shiftedtcs` array in-place.
585
+
586
+ Parameters
587
+ ----------
588
+ shiftedtcs : NDArray
589
+ Array of shifted time correlation data, shape (n_samples, n_timepoints).
590
+ refinemask : NDArray
591
+ Boolean mask for refining data, shape (n_samples,).
592
+ lagtimes : NDArray
593
+ Array of lag times, shape (n_samples,).
594
+ lagmaxthresh : float
595
+ Threshold for lag time normalization.
596
+ lagstrengths : NDArray
597
+ Array of lag strengths, shape (n_samples,).
598
+ R2vals : NDArray
599
+ Array of R-squared values, shape (n_samples,).
600
+ refineprenorm : str
601
+ Normalization method to use: 'mean', 'var', 'std', or 'invlag'.
602
+ If any other value is provided, unit normalization is applied.
603
+ refineweighting : str
604
+ Weighting method to use: 'R', 'R2', or other (default weighting based on lagstrengths).
605
+ debug : bool, optional
606
+ If True, print debug information about input shapes and intermediate values.
607
+
608
+ Returns
609
+ -------
610
+ None
611
+ The function modifies `shiftedtcs` in-place.
612
+
613
+ Notes
614
+ -----
615
+ The function applies normalization using a divisor computed according to the
616
+ `refineprenorm` parameter and then applies weights based on `refineweighting`.
617
+ The `shiftedtcs` array is updated in-place.
618
+
619
+ Examples
620
+ --------
621
+ >>> import numpy as np
622
+ >>> shiftedtcs = np.random.rand(10, 5)
623
+ >>> refinemask = np.ones(10, dtype=bool)
624
+ >>> lagtimes = np.arange(10)
625
+ >>> lagmaxthresh = 2.0
626
+ >>> lagstrengths = np.random.rand(10)
627
+ >>> R2vals = np.random.rand(10)
628
+ >>> prenorm(shiftedtcs, refinemask, lagtimes, lagmaxthresh, lagstrengths, R2vals, "mean", "R", debug=True)
629
+ """
630
+ if debug:
631
+ print(f"{shiftedtcs.shape=}"),
632
+ print(f"{refinemask.shape=}"),
633
+ print(f"{lagtimes.shape=}"),
634
+ print(f"{lagmaxthresh=}"),
635
+ print(f"{lagstrengths.shape=}"),
636
+ print(f"{R2vals.shape=}"),
637
+ print(f"{refineprenorm=}"),
638
+ print(f"{refineweighting=}"),
639
+ if refineprenorm == "mean":
640
+ thedivisor = np.mean(shiftedtcs, axis=1)
641
+ elif refineprenorm == "var":
642
+ thedivisor = np.var(shiftedtcs, axis=1)
643
+ elif refineprenorm == "std":
644
+ thedivisor = np.std(shiftedtcs, axis=1)
645
+ elif refineprenorm == "invlag":
646
+ thedivisor = np.where(np.fabs(lagtimes) < lagmaxthresh, lagmaxthresh - lagtimes, 0.0)
647
+ else:
648
+ thedivisor = np.ones_like(shiftedtcs[:, 0])
649
+
650
+ normfac = np.where(thedivisor != 0.0, 1.0 / thedivisor, 0.0)
651
+
652
+ if refineweighting == "R":
653
+ thisweight = lagstrengths
654
+ elif refineweighting == "R2":
655
+ thisweight = R2vals
656
+ else:
657
+ thisweight = np.where(lagstrengths > 0.0, 1.0, -1.0)
658
+ thisweight *= refinemask
659
+
660
+ if debug:
661
+ print(f"{thedivisor.shape=}")
662
+ print(f"{normfac.shape=}")
663
+ print(f"{thisweight.shape=}")
664
+
665
+ shiftedtcs *= (normfac * thisweight)[:, None]
666
+
667
+
668
+ def dorefine(
669
+ shiftedtcs: NDArray,
670
+ refinemask: NDArray,
671
+ weights: NDArray,
672
+ theprefilter: Any,
673
+ fmritr: float,
674
+ passnum: int,
675
+ lagstrengths: NDArray,
676
+ lagtimes: NDArray,
677
+ refinetype: str,
678
+ fmrifreq: float,
679
+ outputname: str,
680
+ detrendorder: int = 1,
681
+ pcacomponents: float | str = 0.8,
682
+ dodispersioncalc: bool = False,
683
+ dispersioncalc_lower: float = 0.0,
684
+ dispersioncalc_upper: float = 0.0,
685
+ dispersioncalc_step: float = 0.0,
686
+ windowfunc: str = "hamming",
687
+ cleanrefined: bool = False,
688
+ bipolar: bool = False,
689
+ debug: bool = False,
690
+ rt_floattype: np.dtype = np.float64,
691
+ ) -> tuple[int, NDArray]:
692
+ """
693
+ Refine timecourses using specified method (ICA, PCA, weighted average, or unweighted average).
694
+
695
+ This function applies a refinement process to a set of timecourses based on a mask and
696
+ weights. It supports multiple refinement techniques including ICA, PCA, and averaging,
697
+ and can optionally perform dispersion calculation and cleaning of refined data.
698
+
699
+ Parameters
700
+ ----------
701
+ shiftedtcs : ndarray
702
+ Array of shape (n_voxels, n_timepoints) containing the shifted timecourses.
703
+ refinemask : ndarray
704
+ Boolean mask indicating which voxels to include in refinement.
705
+ weights : ndarray
706
+ Array of shape (n_voxels, n_timepoints) containing weights for each voxel.
707
+ theprefilter : Any
708
+ Pre-filter object with an `apply` method to filter the data.
709
+ fmritr : float
710
+ fMRI repetition time in seconds.
711
+ passnum : int
712
+ Pass number for output file naming.
713
+ lagstrengths : ndarray
714
+ Array of lag strengths for each voxel.
715
+ lagtimes : ndarray
716
+ Array of lag times for each voxel.
717
+ refinetype : str
718
+ Type of refinement to perform: 'ica', 'pca', 'weighted_average', or 'unweighted_average'.
719
+ fmrifreq : float
720
+ fMRI frequency in Hz.
721
+ outputname : str
722
+ Base name for output files.
723
+ detrendorder : int, optional
724
+ Order of detrending for correlation normalization (default is 1).
725
+ pcacomponents : float or str, optional
726
+ Number of PCA components to use. If < 1, treated as fraction of variance; if 'mle', uses MLE.
727
+ Default is 0.8.
728
+ dodispersioncalc : bool, optional
729
+ If True, compute dispersion calculation across lag ranges (default is False).
730
+ dispersioncalc_lower : float, optional
731
+ Lower bound for dispersion calculation lag range (default is 0.0).
732
+ dispersioncalc_upper : float, optional
733
+ Upper bound for dispersion calculation lag range (default is 0.0).
734
+ dispersioncalc_step : float, optional
735
+ Step size for dispersion calculation lag range (default is 0.0).
736
+ windowfunc : str, optional
737
+ Window function for correlation normalization (default is "hamming").
738
+ cleanrefined : bool, optional
739
+ If True, remove linearly fitted discard data from refined output (default is False).
740
+ bipolar : bool, optional
741
+ If True, flip sign of negative lag strengths (default is False).
742
+ debug : bool, optional
743
+ If True, print debug information (default is False).
744
+ rt_floattype : np.dtype, optional
745
+ Data type for floating-point numbers (default is np.float64).
746
+
747
+ Returns
748
+ -------
749
+ tuple[int, ndarray]
750
+ A tuple containing:
751
+ - `volumetotal`: int, total number of voxels included in refinement.
752
+ - `outputdata`: ndarray, refined timecourse of shape (n_timepoints,).
753
+
754
+ Notes
755
+ -----
756
+ - The function supports multiple refinement methods: ICA, PCA, weighted average, and
757
+ unweighted average.
758
+ - If `cleanrefined` is True, a linear regression is performed to remove discard data
759
+ from the refined output.
760
+ - If `dodispersioncalc` is True, dispersion calculation is performed across lag ranges
761
+ and outputs are saved to files with the prefix `outputname`.
762
+
763
+ Examples
764
+ --------
765
+ >>> import numpy as np
766
+ >>> shiftedtcs = np.random.rand(100, 200)
767
+ >>> refinemask = np.ones(100)
768
+ >>> weights = np.ones((100, 200))
769
+ >>> theprefilter = SomeFilter()
770
+ >>> fmritr = 2.0
771
+ >>> passnum = 1
772
+ >>> lagstrengths = np.random.rand(100)
773
+ >>> lagtimes = np.random.rand(100)
774
+ >>> refinetype = "pca"
775
+ >>> fmrifreq = 0.1
776
+ >>> outputname = "test_output"
777
+ >>> volumetotal, outputdata = dorefine(
778
+ ... shiftedtcs, refinemask, weights, theprefilter, fmritr, passnum,
779
+ ... lagstrengths, lagtimes, refinetype, fmrifreq, outputname
780
+ ... )
781
+ """
782
+ # now generate the refined timecourse(s)
783
+ inputshape = np.shape(shiftedtcs)
784
+ validlist = np.where(refinemask > 0)[0]
785
+ volumetotal = len(validlist)
786
+ refinevoxels = shiftedtcs[validlist, :]
787
+ if bipolar:
788
+ for thevoxel in range(len(validlist)):
789
+ if lagstrengths[validlist][thevoxel] < 0.0:
790
+ refinevoxels[thevoxel, :] *= -1.0
791
+ refineweights = weights[validlist]
792
+ weightsum = np.sum(refineweights, axis=0) / volumetotal
793
+ averagedata = np.sum(refinevoxels, axis=0) / volumetotal
794
+ if cleanrefined:
795
+ invalidlist = np.where((1 - refinemask) > 0)[0]
796
+ discardvoxels = shiftedtcs[invalidlist]
797
+ discardweights = weights[invalidlist]
798
+ discardweightsum = np.sum(discardweights, axis=0) / volumetotal
799
+ averagediscard = np.sum(discardvoxels, axis=0) / volumetotal
800
+ if dodispersioncalc:
801
+ LGR.info("splitting regressors by time lag for phase delay estimation")
802
+ laglist = np.arange(
803
+ dispersioncalc_lower,
804
+ dispersioncalc_upper,
805
+ dispersioncalc_step,
806
+ )
807
+ dispersioncalcout = np.zeros((np.shape(laglist)[0], inputshape[1]), dtype=rt_floattype)
808
+ fftlen = int(inputshape[1] // 2)
809
+ fftlen -= fftlen % 2
810
+ dispersioncalcspecmag = np.zeros((np.shape(laglist)[0], fftlen), dtype=rt_floattype)
811
+ dispersioncalcspecphase = np.zeros((np.shape(laglist)[0], fftlen), dtype=rt_floattype)
812
+ ###### BBF dispersioncalc fails when the number of timepoints is odd (or even - not sure). Works the other way.
813
+ for lagnum in range(0, np.shape(laglist)[0]):
814
+ lower = laglist[lagnum] - dispersioncalc_step / 2.0
815
+ upper = laglist[lagnum] + dispersioncalc_step / 2.0
816
+ inlagrange = np.where(
817
+ refinemask
818
+ * np.where(lower < lagtimes, np.int16(1), np.int16(0))
819
+ * np.where(lagtimes < upper, np.int16(1), np.int16(0))
820
+ )[0]
821
+ LGR.info(
822
+ f"\tsumming {np.shape(inlagrange)[0]} regressors with lags from {lower} to {upper}"
823
+ )
824
+ if np.shape(inlagrange)[0] > 0:
825
+ dispersioncalcout[lagnum, :] = tide_math.corrnormalize(
826
+ np.mean(shiftedtcs[inlagrange], axis=0),
827
+ detrendorder=detrendorder,
828
+ windowfunc=windowfunc,
829
+ )
830
+ (
831
+ freqs,
832
+ dispersioncalcspecmag[lagnum, :],
833
+ dispersioncalcspecphase[lagnum, :],
834
+ ) = tide_math.polarfft(dispersioncalcout[lagnum, :], 1.0 / fmritr)
835
+ inlagrange = None
836
+ tide_io.writenpvecs(
837
+ dispersioncalcout,
838
+ outputname + "_dispersioncalcvecs_pass" + str(passnum) + ".txt",
839
+ )
840
+ tide_io.writenpvecs(
841
+ dispersioncalcspecmag,
842
+ outputname + "_dispersioncalcspecmag_pass" + str(passnum) + ".txt",
843
+ )
844
+ tide_io.writenpvecs(
845
+ dispersioncalcspecphase,
846
+ outputname + "_dispersioncalcspecphase_pass" + str(passnum) + ".txt",
847
+ )
848
+ tide_io.writenpvecs(
849
+ freqs,
850
+ outputname + "_dispersioncalcfreqs_pass" + str(passnum) + ".txt",
851
+ )
852
+
853
+ if pcacomponents < 0.0:
854
+ pcacomponents = "mle"
855
+ elif pcacomponents >= 1.0:
856
+ pcacomponents = int(np.round(pcacomponents))
857
+ elif pcacomponents == 0.0:
858
+ print("0.0 is not an allowed value for pcacomponents")
859
+ sys.exit()
860
+ else:
861
+ pcacomponents = pcacomponents
862
+ icacomponents = 1
863
+
864
+ if refinetype == "ica":
865
+ LGR.info("performing ica refinement")
866
+ thefit = FastICA(n_components=icacomponents).fit(refinevoxels) # Reconstruct signals
867
+ LGR.info(f"Using first of {len(thefit.components_)} components")
868
+ icadata = thefit.components_[0]
869
+ filteredavg = tide_math.corrnormalize(
870
+ theprefilter.apply(fmrifreq, averagedata),
871
+ detrendorder=detrendorder,
872
+ )
873
+ filteredica = tide_math.corrnormalize(
874
+ theprefilter.apply(fmrifreq, icadata),
875
+ detrendorder=detrendorder,
876
+ )
877
+ thepxcorr = pearsonr(filteredavg, filteredica).statistic
878
+ LGR.info(f"ica/avg correlation = {thepxcorr}")
879
+ if thepxcorr > 0.0:
880
+ outputdata = 1.0 * icadata
881
+ else:
882
+ outputdata = -1.0 * icadata
883
+ elif refinetype == "pca":
884
+ # use the method of "A novel perspective to calibrate temporal delays in cerebrovascular reactivity
885
+ # using hypercapnic and hyperoxic respiratory challenges". NeuroImage 187, 154?165 (2019).
886
+ LGR.info(f"performing pca refinement with pcacomponents set to {pcacomponents}")
887
+ try:
888
+ thefit = PCA(n_components=pcacomponents).fit(refinevoxels)
889
+ except ValueError:
890
+ if pcacomponents == "mle":
891
+ LGR.info("mle estimation failed - falling back to pcacomponents=0.8")
892
+ thefit = PCA(n_components=0.8).fit(refinevoxels)
893
+ else:
894
+ print("unhandled math exception in PCA refinement - exiting")
895
+ sys.exit()
896
+ LGR.info(
897
+ f"Using {len(thefit.components_)} component(s), accounting for "
898
+ + f"{100.0 * np.cumsum(thefit.explained_variance_ratio_)[len(thefit.components_) - 1]:.2f}% of the variance"
899
+ )
900
+ reduceddata = thefit.inverse_transform(thefit.transform(refinevoxels))
901
+ if debug:
902
+ print("complex processing: reduceddata.shape =", reduceddata.shape)
903
+ pcadata = np.mean(reduceddata, axis=0)
904
+ filteredavg = tide_math.corrnormalize(
905
+ theprefilter.apply(fmrifreq, averagedata),
906
+ detrendorder=detrendorder,
907
+ )
908
+ filteredpca = tide_math.corrnormalize(
909
+ theprefilter.apply(fmrifreq, pcadata),
910
+ detrendorder=detrendorder,
911
+ )
912
+ thepxcorr = pearsonr(filteredavg, filteredpca).statistic
913
+ LGR.info(f"pca/avg correlation = {thepxcorr}")
914
+ if thepxcorr > 0.0:
915
+ outputdata = 1.0 * pcadata
916
+ else:
917
+ outputdata = -1.0 * pcadata
918
+ elif refinetype == "weighted_average":
919
+ LGR.info("performing weighted averaging refinement")
920
+ outputdata = np.nan_to_num(averagedata / weightsum)
921
+ else:
922
+ LGR.info("performing unweighted averaging refinement")
923
+ outputdata = averagedata
924
+
925
+ if cleanrefined:
926
+ thefit, R2 = tide_fit.mlregress(averagediscard, averagedata)
927
+
928
+ fitcoff = thefit[0, 1]
929
+ datatoremove = (fitcoff * averagediscard).astype(rt_floattype)
930
+ outputdata -= datatoremove
931
+
932
+ # garbage collect
933
+ uncollected = gc.collect()
934
+ if uncollected != 0:
935
+ LGR.info(f"garbage collected - unable to collect {uncollected} objects")
936
+ else:
937
+ LGR.info("garbage collected")
938
+
939
+ return volumetotal, outputdata