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,1268 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ #
4
+ # Copyright 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 argparse
20
+ import copy
21
+ import logging
22
+ import os
23
+ import sys
24
+ import time
25
+ from argparse import Namespace
26
+ from pathlib import Path
27
+ from typing import Any, Callable, Dict, List, Optional, Tuple, Union
28
+
29
+ import numpy as np
30
+ from numpy.typing import NDArray
31
+ from scipy.stats import pearsonr
32
+ from sklearn.decomposition import PCA
33
+
34
+ import rapidtide.filter as tide_filt
35
+ import rapidtide.io as tide_io
36
+ import rapidtide.multiproc as tide_multiproc
37
+ import rapidtide.refinedelay as tide_refinedelay
38
+ import rapidtide.resample as tide_resample
39
+ import rapidtide.stats as tide_stats
40
+ import rapidtide.util as tide_util
41
+ import rapidtide.voxelData as tide_voxelData
42
+ import rapidtide.workflows.parser_funcs as pf
43
+ import rapidtide.workflows.regressfrommaps as tide_regressfrommaps
44
+
45
+ from .utils import setup_logger
46
+
47
+
48
+ # Create a sentinel.
49
+ # from https://stackoverflow.com/questions/58594956/find-out-which-arguments-were-passed-explicitly-in-argparse
50
+ class _Sentinel:
51
+ pass
52
+
53
+
54
+ sentinel = _Sentinel()
55
+ LGR = logging.getLogger(__name__)
56
+ ErrorLGR = logging.getLogger("ERROR")
57
+ TimingLGR = logging.getLogger("TIMING")
58
+
59
+ DEFAULT_REGRESSIONFILTDERIVS = 0
60
+ DEFAULT_PATCHTHRESH = 3.0
61
+ DEFAULT_REFINEDELAYMINDELAY = -2.5
62
+ DEFAULT_REFINEDELAYMAXDELAY = 2.5
63
+ DEFAULT_REFINEDELAYNUMPOINTS = 201
64
+ DEFAULT_DELAYOFFSETSPATIALFILT = -1
65
+ DEFAULT_WINDOWSIZE = 30.0
66
+ DEFAULT_SYSTEMICFITTYPE = "pca"
67
+ DEFAULT_PCACOMPONENTS = 1
68
+ DEFAULT_LAGMIN = -999
69
+ DEFAULT_LAGMAX = -999
70
+ DEFAULT_TRAINSTEP = 0.5
71
+
72
+
73
+ def _get_parser() -> Any:
74
+ """
75
+ Argument parser for glmfilt.
76
+
77
+ This function constructs and returns an `argparse.ArgumentParser` object configured
78
+ for parsing command-line arguments used by the `glmfilt` tool. It defines required
79
+ and optional arguments for processing fMRI data, including file paths, filtering
80
+ options, output settings, and experimental parameters.
81
+
82
+ Returns
83
+ -------
84
+ argparse.ArgumentParser
85
+ Configured argument parser for the glmfilt tool.
86
+
87
+ Notes
88
+ -----
89
+ The parser includes both standard and experimental options. Experimental options
90
+ are marked as such and may not be fully tested or stable.
91
+
92
+ Examples
93
+ --------
94
+ >>> parser = _get_parser()
95
+ >>> args = parser.parse_args()
96
+ """
97
+ parser = argparse.ArgumentParser(
98
+ prog="delayvar",
99
+ description="Calculate variation in delay time over the course of an acquisition.",
100
+ allow_abbrev=False,
101
+ )
102
+
103
+ # Required arguments
104
+ parser.add_argument(
105
+ "fmrifile",
106
+ type=lambda x: pf.is_valid_file(parser, x),
107
+ help="The name of 4D nifti fmri file to filter.",
108
+ )
109
+ parser.add_argument(
110
+ "datafileroot",
111
+ type=str,
112
+ help="The root name of the previously run rapidtide dataset (everything up to but not including the underscore.)",
113
+ )
114
+ parser.add_argument(
115
+ "--alternateoutput",
116
+ dest="alternateoutput",
117
+ type=str,
118
+ help="Alternate output root (if not specified, will use the same root as the previous dataset).",
119
+ default=None,
120
+ )
121
+ parser.add_argument(
122
+ "--nprocs",
123
+ dest="nprocs",
124
+ action="store",
125
+ type=int,
126
+ metavar="NPROCS",
127
+ help=(
128
+ "Use NPROCS worker processes for multiprocessing. "
129
+ "Setting NPROCS to less than 1 sets the number of "
130
+ "worker processes to n_cpus."
131
+ ),
132
+ default=1,
133
+ )
134
+ parser.add_argument(
135
+ "--numskip",
136
+ dest="numskip",
137
+ action="store",
138
+ type=lambda x: pf.is_int(parser, x, minval=0),
139
+ metavar="NUMSKIP",
140
+ help=("Skip NUMSKIP points at the beginning of the fmri file."),
141
+ default=0,
142
+ )
143
+ parser.add_argument(
144
+ "--outputlevel",
145
+ dest="outputlevel",
146
+ action="store",
147
+ type=str,
148
+ choices=["min", "less", "normal", "more", "max"],
149
+ help=(
150
+ "The level of file output produced. 'min' produces only absolutely essential files, 'less' adds in "
151
+ "the sLFO filtered data (rather than just filter efficacy metrics), 'normal' saves what you "
152
+ "would typically want around for interactive data exploration, "
153
+ "'more' adds files that are sometimes useful, and 'max' outputs anything you might possibly want. "
154
+ "Selecting 'max' will produce ~3x your input datafile size as output. "
155
+ f'Default is "normal".'
156
+ ),
157
+ default="normal",
158
+ )
159
+ parser.add_argument(
160
+ "--noprogressbar",
161
+ dest="showprogressbar",
162
+ action="store_false",
163
+ help=("Will disable showing progress bars (helpful if stdout is going to a file)."),
164
+ default=True,
165
+ )
166
+ parser.add_argument(
167
+ "--nohpfilter",
168
+ dest="hpf",
169
+ action="store_false",
170
+ help=("Disable highpass filtering on data and regressor."),
171
+ default=True,
172
+ )
173
+ parser.add_argument(
174
+ "--trainrange",
175
+ dest="lag_extrema",
176
+ action=pf.IndicateSpecifiedAction,
177
+ nargs=2,
178
+ type=float,
179
+ metavar=("LAGMIN", "LAGMAX"),
180
+ help=(
181
+ "Set the range of delay offset center frequencies to span LAGMIN to LAGMAX. The derivative "
182
+ "ratio calculation only works over a narrow range, so if the static offset is large, "
183
+ "you need to train the ratio calculation with a central delay close to that value. "
184
+ f"LAGMAX. Default is {DEFAULT_LAGMIN} to {DEFAULT_LAGMAX} seconds. "
185
+ ),
186
+ default=(DEFAULT_LAGMIN, DEFAULT_LAGMAX),
187
+ )
188
+ parser.add_argument(
189
+ "--trainstep",
190
+ dest="trainstep",
191
+ action="store",
192
+ type=float,
193
+ metavar="STEP",
194
+ help=(
195
+ "Use this step size (in seconds) to span the training width. The derivative "
196
+ "ratio calculation only works over a narrow range, so if the static offset is large, "
197
+ "you need to train the ratio calculation with a central delay close to that value. "
198
+ f"Default is {DEFAULT_TRAINSTEP}"
199
+ ),
200
+ default=DEFAULT_TRAINSTEP,
201
+ )
202
+ parser.add_argument(
203
+ "--delaypatchthresh",
204
+ dest="delaypatchthresh",
205
+ action="store",
206
+ type=float,
207
+ metavar="NUMMADs",
208
+ help=(
209
+ "Maximum number of robust standard deviations to permit in the offset delay refine map. "
210
+ f"Default is {DEFAULT_PATCHTHRESH}"
211
+ ),
212
+ default=DEFAULT_PATCHTHRESH,
213
+ )
214
+ parser.add_argument(
215
+ "--systemicfittype",
216
+ dest="systemicfittype",
217
+ action="store",
218
+ type=str,
219
+ choices=[
220
+ "mean",
221
+ "pca",
222
+ ],
223
+ help=(
224
+ f"Use mean or pca to fit the systemic variation in delay offset. "
225
+ f'Default is "{DEFAULT_SYSTEMICFITTYPE}".'
226
+ ),
227
+ default=DEFAULT_SYSTEMICFITTYPE,
228
+ )
229
+ parser.add_argument(
230
+ "--pcacomponents",
231
+ metavar="NCOMP",
232
+ dest="pcacomponents",
233
+ type=float,
234
+ help="Use NCOMP components for PCA fit of delay offset.",
235
+ default=DEFAULT_PCACOMPONENTS,
236
+ )
237
+ parser.add_argument(
238
+ "--verbose",
239
+ dest="verbose",
240
+ action="store_true",
241
+ help=("Be wicked chatty."),
242
+ default=False,
243
+ )
244
+ parser.add_argument(
245
+ "--debug",
246
+ dest="debug",
247
+ action="store_true",
248
+ help=("Output lots of helpful information."),
249
+ default=False,
250
+ )
251
+ parser.add_argument(
252
+ "--focaldebug",
253
+ dest="focaldebug",
254
+ action="store_true",
255
+ help=("Output lots of helpful information on a limited subset of operations."),
256
+ default=False,
257
+ )
258
+ experimental = parser.add_argument_group(
259
+ "Experimental options (not fully tested, or not tested at all, may not work). Beware!"
260
+ )
261
+ experimental.add_argument(
262
+ "--windowsize",
263
+ dest="windowsize",
264
+ action="store",
265
+ type=lambda x: pf.is_float(parser, x, minval=10.0),
266
+ metavar="SIZE",
267
+ help=(
268
+ f"Set segmented delay analysis window size to SIZE seconds. Default is {DEFAULT_WINDOWSIZE}."
269
+ ),
270
+ default=DEFAULT_WINDOWSIZE,
271
+ )
272
+ experimental.add_argument(
273
+ "--windelayoffsetspatialfilt",
274
+ dest="windelayoffsetgausssigma",
275
+ action="store",
276
+ type=float,
277
+ metavar="GAUSSSIGMA",
278
+ help=(
279
+ "Spatially filter fMRI data prior to calculating windowed delay offsets "
280
+ "using GAUSSSIGMA in mm. Set GAUSSSIGMA negative "
281
+ "to have rapidtide set it to half the mean voxel "
282
+ "dimension (a rule of thumb for a good value)."
283
+ ),
284
+ default=DEFAULT_DELAYOFFSETSPATIALFILT,
285
+ )
286
+
287
+ return parser
288
+
289
+
290
+ def delayvar(args: Any) -> None:
291
+ """
292
+ Perform windowed delay variance analysis on fMRI data.
293
+
294
+ This function conducts a comprehensive delay variance analysis on fMRI data,
295
+ computing delay offsets for each voxel across temporal windows. It supports
296
+ various filtering options, PCA-based systemic component removal, and outputs
297
+ detailed timing information and processed maps.
298
+
299
+ Parameters
300
+ ----------
301
+ args : Any
302
+ Namespace object containing all required arguments for the analysis.
303
+ Expected attributes include:
304
+ - fmrifile : str
305
+ Path to the input fMRI NIfTI file.
306
+ - datafileroot : str
307
+ Root name for output files.
308
+ - lag_extrema : tuple of int
309
+ Minimum and maximum lag values for analysis.
310
+ - alternateoutput : str, optional
311
+ Alternate output name.
312
+ - debug : bool
313
+ Enable debug mode.
314
+ - outputlevel : str
315
+ Level of output files to save ('min', 'less', 'normal', 'more', 'max').
316
+ - nprocs : int
317
+ Number of processes to use.
318
+ - hpf : bool
319
+ Apply highpass filtering.
320
+ - windowsize : float
321
+ Size of temporal windows in seconds.
322
+ - windelayoffsetgausssigma : float
323
+ Sigma for Gaussian smoothing of delay offsets.
324
+ - delaypatchthresh : float
325
+ Threshold for patch-based delay correction.
326
+ - systemicfittype : str
327
+ Type of systemic component removal ('pca' or 'mean').
328
+ - pcacomponents : float
329
+ Number of PCA components to use.
330
+ - trainstep : float
331
+ Step size for training the delay model.
332
+ - numskip : int
333
+ Number of initial timepoints to skip.
334
+ - focaldebug : bool
335
+ Enable focal debugging mode.
336
+ - verbose : bool
337
+ Enable verbose output.
338
+ - showprogressbar : bool
339
+ Show progress bar during processing.
340
+
341
+ Returns
342
+ -------
343
+ None
344
+ This function does not return a value but writes multiple output files
345
+ including:
346
+ - Delay offset maps in temporal windows
347
+ - Systemic component timeseries
348
+ - PCA component information
349
+ - Timing and runoptions files
350
+ - Histograms of delay offsets
351
+ - Various intermediate processing results
352
+
353
+ Notes
354
+ -----
355
+ The function performs the following key steps:
356
+ 1. Windowed processing of fMRI data
357
+ 2. Derivative ratio calculation and filtering
358
+ 3. Delay offset training and calculation
359
+ 4. Systemic component removal (PCA or mean)
360
+ 5. Output generation and cleanup
361
+
362
+ Examples
363
+ --------
364
+ >>> import argparse
365
+ >>> args = argparse.Namespace(
366
+ ... fmrifile='data.nii.gz',
367
+ ... datafileroot='output',
368
+ ... lag_extrema=(0, 10),
369
+ ... debug=False,
370
+ ... outputlevel='normal',
371
+ ... nprocs=4,
372
+ ... hpf=True,
373
+ ... windowsize=30.0,
374
+ ... windelayoffsetgausssigma=2.0,
375
+ ... delaypatchthresh=0.5,
376
+ ... systemicfittype='pca',
377
+ ... pcacomponents=0.8,
378
+ ... trainstep=0.1,
379
+ ... numskip=5,
380
+ ... focaldebug=False,
381
+ ... verbose=True,
382
+ ... showprogressbar=True
383
+ ... )
384
+ >>> delayvar(args)
385
+ """
386
+ # get the pid of the parent process
387
+ args.pid = os.getpid()
388
+
389
+ args.lagmin = args.lag_extrema[0]
390
+ args.lagmax = args.lag_extrema[1]
391
+
392
+ # specify the output name
393
+ if args.alternateoutput is None:
394
+ outputname = args.datafileroot
395
+ else:
396
+ outputname = args.alternateoutput
397
+
398
+ # start the loggers low that we know the output name
399
+ sh = logging.StreamHandler()
400
+ if args.debug:
401
+ logging.basicConfig(level=logging.DEBUG, handlers=[sh])
402
+ else:
403
+ logging.basicConfig(level=logging.INFO, handlers=[sh])
404
+ # Set up loggers for workflow
405
+ setup_logger(
406
+ logger_filename=f"{outputname}_retrolog.txt",
407
+ timing_filename=f"{outputname}_retroruntimings.tsv",
408
+ error_filename=f"{outputname}_retroerrorlog.txt",
409
+ isverbose=False,
410
+ debug=args.debug,
411
+ )
412
+ TimingLGR.info("Start")
413
+ LGR.info(f"starting delayvar")
414
+
415
+ # set some global values
416
+ args.mindelay = DEFAULT_REFINEDELAYMINDELAY
417
+ args.maxdelay = DEFAULT_REFINEDELAYMAXDELAY
418
+ args.numpoints = DEFAULT_REFINEDELAYNUMPOINTS
419
+
420
+ if args.outputlevel == "min":
421
+ args.saveminimumsLFOfiltfiles = False
422
+ args.savenormalsLFOfiltfiles = False
423
+ args.savemovingsignal = False
424
+ args.saveallsLFOfiltfiles = False
425
+ elif args.outputlevel == "less":
426
+ args.saveminimumsLFOfiltfiles = True
427
+ args.savenormalsLFOfiltfiles = False
428
+ args.savemovingsignal = False
429
+ args.saveallsLFOfiltfiles = False
430
+ elif args.outputlevel == "normal":
431
+ args.saveminimumsLFOfiltfiles = True
432
+ args.savenormalsLFOfiltfiles = True
433
+ args.savemovingsignal = False
434
+ args.saveallsLFOfiltfiles = False
435
+ elif args.outputlevel == "more":
436
+ args.saveminimumsLFOfiltfiles = True
437
+ args.savenormalsLFOfiltfiles = True
438
+ args.savemovingsignal = True
439
+ args.saveallsLFOfiltfiles = False
440
+ elif args.outputlevel == "max":
441
+ args.saveminimumsLFOfiltfiles = True
442
+ args.savenormalsLFOfiltfiles = True
443
+ args.savemovingsignal = True
444
+ args.saveallsLFOfiltfiles = True
445
+ else:
446
+ print(f"illegal output level {args['outputlevel']}")
447
+ sys.exit()
448
+
449
+ thecommandline = " ".join(sys.argv[1:])
450
+
451
+ if args.nprocs < 1:
452
+ args.nprocs = tide_multiproc.maxcpus()
453
+ # don't use shared memory if there is only one process
454
+ if args.nprocs == 1:
455
+ usesharedmem = False
456
+ else:
457
+ usesharedmem = True
458
+
459
+ # read the runoptions file, update if necessary
460
+ print("reading runoptions")
461
+ runoptionsfile = f"{args.datafileroot}_desc-runoptions_info"
462
+ therunoptions = tide_io.readoptionsfile(runoptionsfile)
463
+ sublist = (
464
+ ("retroglmcompatible", "retroregresscompatible"),
465
+ ("glmthreshval", "regressfiltthreshval"),
466
+ )
467
+ therunoptions["singleproc_regressionfilt"] = False
468
+ therunoptions["nprocs_regressionfilt"] = args.nprocs
469
+ for subpair in sublist:
470
+ try:
471
+ therunoptions[subpair[1]] = therunoptions[subpair[0]]
472
+ print(f"substituting {subpair[1]} for {subpair[0]} in runoptions")
473
+ except KeyError:
474
+ pass
475
+
476
+ try:
477
+ candoretroregress = therunoptions["retroregresscompatible"]
478
+ except KeyError:
479
+ print(
480
+ f"based on {runoptionsfile}, this rapidtide dataset does not support retrospective GLM calculation"
481
+ )
482
+ sys.exit()
483
+
484
+ if therunoptions["internalprecision"] == "double":
485
+ rt_floattype = np.dtype(np.float64)
486
+ else:
487
+ rt_floattype = np.dtype(np.float32)
488
+
489
+ # set the output precision
490
+ if therunoptions["outputprecision"] == "double":
491
+ rt_outfloattype = np.dtype(np.float64)
492
+ else:
493
+ rt_outfloattype = np.dtype(np.float32)
494
+ therunoptions["saveminimumsLFOfiltfiles"] = args.saveminimumsLFOfiltfiles
495
+
496
+ # read the fmri input files
497
+ print("reading fmrifile")
498
+ theinputdata = tide_voxelData.VoxelData(args.fmrifile)
499
+ xsize, ysize, numslices, timepoints = theinputdata.getdims()
500
+ xdim, ydim, slicethickness, fmritr = theinputdata.getsizes()
501
+ fmri_header = theinputdata.copyheader()
502
+ fmri_data = theinputdata.byvol()
503
+ numspatiallocs = theinputdata.numspatiallocs
504
+
505
+ # create the canary file
506
+ Path(f"{outputname}_DELAYVARISRUNNING.txt").touch()
507
+
508
+ if args.debug:
509
+ print(f"{fmri_data.shape=}")
510
+ fmri_data_spacebytime = theinputdata.byvoxel()
511
+ if args.debug:
512
+ print(f"{fmri_data_spacebytime.shape=}")
513
+
514
+ # read the processed mask
515
+ print("reading procfit maskfile")
516
+ procmaskfile = f"{args.datafileroot}_desc-processed_mask.nii.gz"
517
+ (
518
+ procmask_input,
519
+ procmask,
520
+ procmask_header,
521
+ procmask_dims,
522
+ procmask_sizes,
523
+ ) = tide_io.readfromnifti(procmaskfile)
524
+ if not tide_io.checkspacematch(fmri_header, procmask_header):
525
+ raise ValueError("procmask dimensions do not match fmri dimensions")
526
+ procmask_spacebytime = procmask.reshape((numspatiallocs))
527
+ if args.debug:
528
+ print(f"{procmask_spacebytime.shape=}")
529
+ print(f"{tide_stats.getmasksize(procmask_spacebytime)=}")
530
+
531
+ # read the corrfit mask
532
+ print("reading corrfit maskfile")
533
+ corrmaskfile = f"{args.datafileroot}_desc-corrfit_mask.nii.gz"
534
+ (
535
+ corrmask_input,
536
+ corrmask,
537
+ corrmask_header,
538
+ corrmask_dims,
539
+ corrmask_sizes,
540
+ ) = tide_io.readfromnifti(corrmaskfile)
541
+ if not tide_io.checkspacematch(fmri_header, corrmask_header):
542
+ raise ValueError("corrmask dimensions do not match fmri dimensions")
543
+ corrmask_spacebytime = corrmask.reshape((numspatiallocs))
544
+ if args.debug:
545
+ print(f"{corrmask_spacebytime.shape=}")
546
+ print(f"{tide_stats.getmasksize(corrmask_spacebytime)=}")
547
+
548
+ print("reading lagtimes")
549
+ lagtimesfile = f"{args.datafileroot}_desc-maxtimerefined_map.nii.gz"
550
+ if not os.path.exists(lagtimesfile):
551
+ lagtimesfile = f"{args.datafileroot}_desc-maxtime_map.nii.gz"
552
+ (
553
+ lagtimes_input,
554
+ lagtimes,
555
+ lagtimes_header,
556
+ lagtimes_dims,
557
+ lagtimes_sizes,
558
+ ) = tide_io.readfromnifti(lagtimesfile)
559
+ if not tide_io.checkspacematch(fmri_header, lagtimes_header):
560
+ raise ValueError("lagtimes dimensions do not match fmri dimensions")
561
+ if args.debug:
562
+ print(f"{lagtimes.shape=}")
563
+ lagtimes_spacebytime = lagtimes.reshape((numspatiallocs))
564
+ if args.debug:
565
+ print(f"{lagtimes_spacebytime.shape=}")
566
+
567
+ startpt = args.numskip
568
+ endpt = timepoints - 1
569
+ validtimepoints = endpt - startpt + 1
570
+ skiptime = startpt * fmritr
571
+ initial_fmri_x = (
572
+ np.linspace(0.0, validtimepoints * fmritr, num=validtimepoints, endpoint=False) + skiptime
573
+ )
574
+
575
+ # read the lagtc generator file
576
+ print("reading lagtc generator")
577
+ lagtcgeneratorfile = f"{args.datafileroot}_desc-lagtcgenerator_timeseries"
578
+ thepadtime = therunoptions["padseconds"]
579
+ genlagtc = tide_resample.FastResamplerFromFile(lagtcgeneratorfile, padtime=thepadtime)
580
+
581
+ # select the voxels in the mask
582
+ print("figuring out valid voxels")
583
+ validvoxels = np.where(procmask_spacebytime > 0)[0]
584
+ numvalidspatiallocs = np.shape(validvoxels)[0]
585
+ if args.debug:
586
+ print(f"{numvalidspatiallocs=}")
587
+
588
+ # slicing to valid voxels
589
+ print("selecting valid voxels")
590
+ fmri_data_valid = fmri_data_spacebytime[validvoxels, :]
591
+ lagtimes_valid = lagtimes_spacebytime[validvoxels]
592
+ corrmask_valid = corrmask_spacebytime[validvoxels]
593
+ procmask_valid = procmask_spacebytime[validvoxels]
594
+ if args.debug:
595
+ print(f"{fmri_data_valid.shape=}")
596
+
597
+ oversampfactor = int(therunoptions["oversampfactor"])
598
+ if args.debug:
599
+ print(f"{outputname=}")
600
+ oversamptr = fmritr / oversampfactor
601
+ try:
602
+ threshval = therunoptions["regressfiltthreshval"]
603
+ except KeyError:
604
+ threshval = 0.0
605
+ therunoptions["regressfiltthreshval"] = threshval
606
+ mode = "glm"
607
+
608
+ if args.debug:
609
+ print(f"{validvoxels.shape=}")
610
+ np.savetxt(f"{outputname}_validvoxels.txt", validvoxels)
611
+
612
+ outputpath = os.path.dirname(outputname)
613
+ rawsources = [
614
+ os.path.relpath(args.fmrifile, start=outputpath),
615
+ os.path.relpath(lagtimesfile, start=outputpath),
616
+ os.path.relpath(corrmaskfile, start=outputpath),
617
+ os.path.relpath(procmaskfile, start=outputpath),
618
+ os.path.relpath(runoptionsfile, start=outputpath),
619
+ os.path.relpath(lagtcgeneratorfile, start=outputpath),
620
+ ]
621
+
622
+ bidsbasedict = {
623
+ "RawSources": rawsources,
624
+ "Units": "arbitrary",
625
+ "CommandLineArgs": thecommandline,
626
+ }
627
+
628
+ # windowed delay deviation estimation
629
+ lagstouse_valid = lagtimes_valid
630
+
631
+ # find the robust range of the static delays
632
+ (
633
+ pct02,
634
+ pct98,
635
+ ) = tide_stats.getfracvals(lagstouse_valid, [0.02, 0.98], debug=args.debug)
636
+ if args.lagmin == -999:
637
+ args.lagmin = np.round(pct02 / args.trainstep, 0) * args.trainstep
638
+ if args.lagmax == -999:
639
+ args.lagmax = np.round(pct98 / args.trainstep, 0) * args.trainstep
640
+
641
+ print("\n\nWindowed delay estimation")
642
+ TimingLGR.info("Windowed delay estimation start")
643
+ LGR.info("\n\nWindowed delay estimation")
644
+
645
+ if args.windelayoffsetgausssigma < 0.0:
646
+ # set gausssigma automatically
647
+ args.windelayoffsetgausssigma = np.mean([xdim, ydim, slicethickness]) / 2.0
648
+
649
+ wintrs = int(np.round(args.windowsize / fmritr, 0))
650
+ wintrs += wintrs % 2
651
+ winskip = wintrs // 2
652
+ numtrs = fmri_data_valid.shape[1]
653
+ numwins = (numtrs // winskip) - 2
654
+ winspace = winskip * fmritr
655
+ winwidth = wintrs * fmritr
656
+
657
+ # make a highpass filter
658
+ if args.hpf:
659
+ hpfcutoff = 1.0 / winwidth
660
+ thehpf = tide_filt.NoncausalFilter(
661
+ "arb",
662
+ transferfunc="trapezoidal",
663
+ padtime=30.0,
664
+ padtype="reflect",
665
+ )
666
+ thehpf.setfreqs(hpfcutoff * 0.95, hpfcutoff, 0.15, 0.15)
667
+
668
+ # make a filtered lagtc generator if necessary
669
+ if args.hpf:
670
+ reference_x, reference_y, dummy, dummy, genlagsamplerate = genlagtc.getdata()
671
+ genlagtc = tide_resample.FastResampler(
672
+ reference_x,
673
+ thehpf.apply(genlagsamplerate, reference_y),
674
+ padtime=thepadtime,
675
+ )
676
+ genlagtc.save(f"{outputname}_desc-hpflagtcgenerator_timeseries")
677
+
678
+ # and filter the data if necessary
679
+ if args.hpf:
680
+ Fs = 1.0 / fmritr
681
+ print("highpass filtering fmri data")
682
+ themean = fmri_data_valid.mean(axis=1)
683
+ for vox in range(fmri_data_valid.shape[0]):
684
+ fmri_data_valid[vox, :] = thehpf.apply(Fs, fmri_data_valid[vox, :]) + themean[vox]
685
+ if args.focaldebug:
686
+ # dump the filtered fmri input file
687
+ theheader = copy.deepcopy(fmri_header)
688
+ theheader["dim"][4] = validtimepoints
689
+ theheader["pixdim"][4] = fmritr
690
+
691
+ maplist = [
692
+ (
693
+ fmri_data_valid,
694
+ "hpfinputdata",
695
+ "bold",
696
+ None,
697
+ "fMRI data after highpass filtering",
698
+ ),
699
+ ]
700
+ tide_io.savemaplist(
701
+ outputname,
702
+ maplist,
703
+ validvoxels,
704
+ (xsize, ysize, numslices, validtimepoints),
705
+ theheader,
706
+ bidsbasedict,
707
+ filetype=theinputdata.filetype,
708
+ rt_floattype=rt_floattype,
709
+ cifti_hdr=None,
710
+ )
711
+
712
+ # allocate destination arrays
713
+ internalwinspaceshape = (numvalidspatiallocs, numwins)
714
+ internalwinspaceshapederivs = (
715
+ numvalidspatiallocs,
716
+ 2,
717
+ numwins,
718
+ )
719
+ internalwinfmrishape = (numvalidspatiallocs, wintrs)
720
+ if args.debug:
721
+ print(f"window space shape = {internalwinspaceshape}")
722
+ print(f"internalwindowfmrishape shape = {internalwinfmrishape}")
723
+
724
+ windowedregressderivratios = np.zeros(internalwinspaceshape, dtype=float)
725
+ windowedregressrvalues = np.zeros(internalwinspaceshape, dtype=float)
726
+ windowedmedfiltregressderivratios = np.zeros(internalwinspaceshape, dtype=float)
727
+ windowedfilteredregressderivratios = np.zeros(internalwinspaceshape, dtype=float)
728
+ windoweddelayoffset = np.zeros(internalwinspaceshape, dtype=float)
729
+ windowedclosestoffset = np.zeros(internalwinspaceshape, dtype=float)
730
+
731
+ winsLFOfitmean, winsLFOfitmean_shm = tide_util.allocarray(
732
+ internalwinspaceshape, rt_outfloattype, shared=usesharedmem
733
+ )
734
+ winrvalue, winrvalue_shm = tide_util.allocarray(
735
+ internalwinspaceshape, rt_outfloattype, shared=usesharedmem
736
+ )
737
+ winr2value, winr2value_shm = tide_util.allocarray(
738
+ internalwinspaceshape, rt_outfloattype, shared=usesharedmem
739
+ )
740
+ winfitNorm, winfitNorm_shm = tide_util.allocarray(
741
+ internalwinspaceshapederivs, rt_outfloattype, shared=usesharedmem
742
+ )
743
+ winfitcoeff, winitcoeff_shm = tide_util.allocarray(
744
+ internalwinspaceshapederivs, rt_outfloattype, shared=usesharedmem
745
+ )
746
+ winmovingsignal, winmovingsignal_shm = tide_util.allocarray(
747
+ internalwinfmrishape, rt_outfloattype, shared=usesharedmem
748
+ )
749
+ winlagtc, winlagtc_shm = tide_util.allocarray(
750
+ internalwinfmrishape, rt_floattype, shared=usesharedmem
751
+ )
752
+ winfiltereddata, winfiltereddata_shm = tide_util.allocarray(
753
+ internalwinfmrishape, rt_outfloattype, shared=usesharedmem
754
+ )
755
+ if usesharedmem:
756
+ if args.debug:
757
+ print("allocating shared memory")
758
+ else:
759
+ if args.debug:
760
+ print("allocating memory")
761
+
762
+ if args.debug:
763
+ print(f"wintrs={wintrs}, winskip={winskip}, numtrs={numtrs}, numwins={numwins}")
764
+ thewindowprocoptions = therunoptions
765
+ if args.verbose:
766
+ thewindowprocoptions["showprogressbar"] = True
767
+ else:
768
+ thewindowprocoptions["showprogressbar"] = False
769
+ if args.focaldebug:
770
+ thewindowprocoptions["saveminimumsLFOfiltfiles"] = True
771
+ winoutputlevel = "max"
772
+ else:
773
+ thewindowprocoptions["saveminimumsLFOfiltfiles"] = False
774
+ winoutputlevel = "min"
775
+
776
+ # Now get the derivative ratios the individual windows
777
+ print("Finding derivative ratios:")
778
+ for thewin in range(numwins):
779
+ print(f"\tProcessing window {thewin + 1} of {numwins}")
780
+ starttr = thewin * winskip
781
+ endtr = starttr + wintrs
782
+ winlabel = f"_win-{str(thewin + 1).zfill(3)}"
783
+ if args.verbose:
784
+ thisLGR = LGR
785
+ thisTimingLGR = TimingLGR
786
+ else:
787
+ thisLGR = None
788
+ thisTimingLGR = None
789
+
790
+ windowedregressderivratios[:, thewin], windowedregressrvalues[:, thewin] = (
791
+ tide_refinedelay.getderivratios(
792
+ fmri_data_valid,
793
+ validvoxels,
794
+ initial_fmri_x,
795
+ lagstouse_valid,
796
+ corrmask_valid,
797
+ genlagtc,
798
+ mode,
799
+ outputname + winlabel,
800
+ oversamptr,
801
+ winsLFOfitmean[:, thewin],
802
+ winrvalue[:, thewin],
803
+ winr2value[:, thewin],
804
+ winfitNorm[:, :, thewin],
805
+ winfitcoeff[:, :, thewin],
806
+ winmovingsignal,
807
+ winlagtc,
808
+ winfiltereddata,
809
+ thisLGR,
810
+ thisTimingLGR,
811
+ thewindowprocoptions,
812
+ regressderivs=1,
813
+ starttr=starttr,
814
+ endtr=endtr,
815
+ debug=args.debug,
816
+ )
817
+ )
818
+ if args.focaldebug:
819
+ theheader = copy.deepcopy(fmri_header)
820
+ theheader["dim"][4] = wintrs
821
+ theheader["toffset"] = winwidth / 2.0
822
+ maplist = [
823
+ (
824
+ winlagtc,
825
+ "windowedlagtcs",
826
+ "bold",
827
+ None,
828
+ f"Lagtcs in each {winspace} second window",
829
+ ),
830
+ ]
831
+ tide_io.savemaplist(
832
+ outputname + winlabel,
833
+ maplist,
834
+ validvoxels,
835
+ (xsize, ysize, numslices, wintrs),
836
+ theheader,
837
+ bidsbasedict,
838
+ debug=args.debug,
839
+ )
840
+
841
+ # Filter the derivative ratios
842
+ print("Filtering derivative ratios:")
843
+ for thewin in range(numwins):
844
+ print(f"\tProcessing window {thewin + 1} of {numwins}")
845
+ (
846
+ windowedmedfiltregressderivratios[:, thewin],
847
+ windowedfilteredregressderivratios[:, thewin],
848
+ windoweddelayoffsetMAD,
849
+ ) = tide_refinedelay.filterderivratios(
850
+ windowedregressderivratios[:, thewin],
851
+ (xsize, ysize, numslices),
852
+ validvoxels,
853
+ (xdim, ydim, slicethickness),
854
+ gausssigma=args.windelayoffsetgausssigma,
855
+ patchthresh=args.delaypatchthresh,
856
+ rt_floattype=rt_floattype,
857
+ verbose=args.verbose,
858
+ debug=args.debug,
859
+ )
860
+
861
+ # Train the ratio offsets
862
+ print("Training ratio offsets:")
863
+ for thewin in range(numwins):
864
+ print(f"\tProcessing window {thewin + 1} of {numwins}")
865
+ starttr = thewin * winskip
866
+ endtr = starttr + wintrs
867
+ winlabel = f"_win-{str(thewin + 1).zfill(3)}"
868
+ # find the mapping of glm ratios to delays
869
+ tide_refinedelay.trainratiotooffset(
870
+ genlagtc,
871
+ initial_fmri_x[starttr:endtr],
872
+ outputname + winlabel,
873
+ winoutputlevel,
874
+ trainlagmin=args.lagmin,
875
+ trainlagmax=args.lagmax,
876
+ trainlagstep=args.trainstep,
877
+ mindelay=args.mindelay,
878
+ maxdelay=args.maxdelay,
879
+ numpoints=args.numpoints,
880
+ verbose=args.verbose,
881
+ debug=args.focaldebug,
882
+ )
883
+ TimingLGR.info("Refinement calibration end")
884
+
885
+ # now calculate the delay offsets
886
+ print("Calculating delay offsets:")
887
+ for thewin in range(numwins):
888
+ print(f"\tProcessing window {thewin + 1} of {numwins}")
889
+ winlabel = f"_win-{str(thewin + 1).zfill(3)}"
890
+ TimingLGR.info("Calculating delay offsets")
891
+ if args.debug:
892
+ print(
893
+ f"calculating delayoffsets for {windowedfilteredregressderivratios.shape[0]} voxels"
894
+ )
895
+ for i in range(windowedfilteredregressderivratios.shape[0]):
896
+ (windoweddelayoffset[i, thewin], windowedclosestoffset[i, thewin]) = (
897
+ tide_refinedelay.ratiotodelay(
898
+ windowedfilteredregressderivratios[i, thewin],
899
+ offset=lagstouse_valid[i],
900
+ debug=args.focaldebug,
901
+ )
902
+ )
903
+ namesuffix = "_desc-delayoffset_hist"
904
+ tide_stats.makeandsavehistogram(
905
+ windoweddelayoffset[:, thewin],
906
+ therunoptions["histlen"],
907
+ 1,
908
+ outputname + winlabel + namesuffix,
909
+ displaytitle="Histogram of delay offsets calculated from GLM",
910
+ dictvarname="delayoffsethist",
911
+ thedict=None,
912
+ )
913
+
914
+ # now see if there are common timecourses in the delay offsets
915
+ themean = np.mean(windoweddelayoffset, axis=1)
916
+ thevar = np.var(windoweddelayoffset, axis=1)
917
+ scaledvoxels = np.zeros_like(windoweddelayoffset)
918
+ for vox in range(0, windoweddelayoffset.shape[0]):
919
+ scaledvoxels[vox, :] = windoweddelayoffset[vox, :] - themean[vox]
920
+ if thevar[vox] > 0.0:
921
+ scaledvoxels[vox, :] = scaledvoxels[vox, :] / thevar[vox]
922
+ if args.systemicfittype == "pca":
923
+ if args.pcacomponents < 0.0:
924
+ pcacomponents = "mle"
925
+ elif args.pcacomponents >= 1.0:
926
+ pcacomponents = int(np.round(args.pcacomponents))
927
+ elif args.pcacomponents == 0.0:
928
+ print("0.0 is not an allowed value for pcacomponents")
929
+ sys.exit()
930
+ else:
931
+ pcacomponents = args.pcacomponents
932
+
933
+ # use the method of "A novel perspective to calibrate temporal delays in cerebrovascular reactivity
934
+ # using hypercapnic and hyperoxic respiratory challenges". NeuroImage 187, 154?165 (2019).
935
+ print(f"performing pca refinement with pcacomponents set to {pcacomponents}")
936
+ try:
937
+ thefit = PCA(n_components=pcacomponents).fit(scaledvoxels)
938
+ except ValueError:
939
+ if pcacomponents == "mle":
940
+ print("mle estimation failed - falling back to pcacomponents=0.8")
941
+ thefit = PCA(n_components=0.8).fit(scaledvoxels)
942
+ else:
943
+ print("unhandled math exception in PCA refinement - exiting")
944
+ sys.exit()
945
+ print(
946
+ f"Using {len(thefit.components_)} component(s), accounting for "
947
+ + f"{100.0 * np.cumsum(thefit.explained_variance_ratio_)[len(thefit.components_) - 1]:.2f}% of the variance"
948
+ )
949
+ reduceddata = thefit.inverse_transform(thefit.transform(scaledvoxels))
950
+ # unscale the PCA cleaned data
951
+ for vox in range(0, windoweddelayoffset.shape[0]):
952
+ reduceddata[vox, :] = reduceddata[vox, :] * thevar[vox] + themean[vox]
953
+ if args.debug:
954
+ print("complex processing: reduceddata.shape =", scaledvoxels.shape)
955
+ # pcadata = np.mean(reduceddata, axis=0)
956
+ pcadata = thefit.components_[0]
957
+ averagedata = np.mean(windoweddelayoffset, axis=0)
958
+ thepxcorr = pearsonr(averagedata, pcadata).statistic
959
+ LGR.info(f"pca/avg correlation = {thepxcorr}")
960
+ if thepxcorr > 0.0:
961
+ systemiccomp = 1.0 * pcadata
962
+ else:
963
+ systemiccomp = -1.0 * pcadata
964
+ thecomponents = thefit.components_[:]
965
+ tide_io.writebidstsv(
966
+ f"{outputname}_desc-pcacomponents_timeseries",
967
+ thecomponents,
968
+ 1.0 / winspace,
969
+ )
970
+ tide_io.writevec(
971
+ 100.0 * thefit.explained_variance_ratio_,
972
+ f"{outputname}_desc-pcaexplainedvarianceratio_info.tsv",
973
+ )
974
+ elif args.systemicfittype == "mean":
975
+ systemiccomp = np.mean(scaledvoxels, axis=0)
976
+ reduceddata = None
977
+ else:
978
+ print("unhandled systemic filter type")
979
+ sys.exit(0)
980
+ tide_io.writebidstsv(
981
+ f"{outputname}_desc-systemiccomponent_timeseries",
982
+ systemiccomp,
983
+ 1.0 / winspace,
984
+ )
985
+
986
+ doregress = False
987
+ if doregress:
988
+ systemicsLFOfitmean, systemicsLFOfitmean_shm = tide_util.allocarray(
989
+ internalwinspaceshape, rt_outfloattype, shared=usesharedmem
990
+ )
991
+ systemicrvalue, systemicrvalue_shm = tide_util.allocarray(
992
+ internalwinspaceshape, rt_outfloattype, shared=usesharedmem
993
+ )
994
+ systemicr2value, systemicr2value_shm = tide_util.allocarray(
995
+ internalwinspaceshape, rt_outfloattype, shared=usesharedmem
996
+ )
997
+ systemicfitNorm, systemicfitNorm_shm = tide_util.allocarray(
998
+ internalwinspaceshapederivs, rt_outfloattype, shared=usesharedmem
999
+ )
1000
+ systemicfitcoeff, systemicitcoeff_shm = tide_util.allocarray(
1001
+ internalwinspaceshapederivs, rt_outfloattype, shared=usesharedmem
1002
+ )
1003
+ systemicmovingsignal, systemicmovingsignal_shm = tide_util.allocarray(
1004
+ internalwinspaceshape, rt_outfloattype, shared=usesharedmem
1005
+ )
1006
+ systemiclagtc, systemiclagtc_shm = tide_util.allocarray(
1007
+ internalwinspaceshape, rt_floattype, shared=usesharedmem
1008
+ )
1009
+ systemicfiltereddata, systemicfiltereddata_shm = tide_util.allocarray(
1010
+ internalwinspaceshape, rt_outfloattype, shared=usesharedmem
1011
+ )
1012
+ if usesharedmem:
1013
+ if args.debug:
1014
+ print("allocating shared memory")
1015
+ else:
1016
+ if args.debug:
1017
+ print("allocating memory")
1018
+
1019
+ windowlocs = np.linspace(0.0, winspace * numwins, num=numwins, endpoint=False) + skiptime
1020
+ voxelsprocessed_regressionfilt, regressorset, evset = tide_regressfrommaps.regressfrommaps(
1021
+ windoweddelayoffset,
1022
+ validvoxels,
1023
+ windowlocs,
1024
+ 0.0 * lagstouse_valid,
1025
+ corrmask_valid,
1026
+ genlagtc,
1027
+ mode,
1028
+ outputname,
1029
+ oversamptr,
1030
+ systemicsLFOfitmean,
1031
+ systemicrvalue,
1032
+ systemicr2value,
1033
+ systemicfitNorm[:, :],
1034
+ systemicfitcoeff[:, :],
1035
+ systemicmovingsignal,
1036
+ systemiclagtc,
1037
+ systemicfiltereddata,
1038
+ LGR,
1039
+ TimingLGR,
1040
+ threshval,
1041
+ False,
1042
+ nprocs_makelaggedtcs=args.nprocs,
1043
+ nprocs_regressionfilt=args.nprocs,
1044
+ regressderivs=1,
1045
+ showprogressbar=args.showprogressbar,
1046
+ debug=args.debug,
1047
+ )
1048
+
1049
+ theheader = copy.deepcopy(fmri_header)
1050
+ theheader["dim"][4] = numwins
1051
+ theheader["pixdim"][4] = winspace
1052
+ theheader["toffset"] = winwidth / 2.0
1053
+ maplist = [
1054
+ (
1055
+ windoweddelayoffset,
1056
+ "windoweddelayoffset",
1057
+ "info",
1058
+ None,
1059
+ f"Delay offsets in each {winspace} second window",
1060
+ ),
1061
+ (
1062
+ windowedclosestoffset,
1063
+ "windowedclosestoffset",
1064
+ "info",
1065
+ None,
1066
+ f"Closest delay offsets in each {winspace} second window",
1067
+ ),
1068
+ (
1069
+ np.square(windowedregressrvalues),
1070
+ "windowedregressr2values",
1071
+ "info",
1072
+ None,
1073
+ f"R2 values for regression in each {winspace} second window",
1074
+ ),
1075
+ ]
1076
+ if doregress:
1077
+ maplist += [
1078
+ (
1079
+ systemicfiltereddata,
1080
+ "systemicfiltereddata",
1081
+ "info",
1082
+ None,
1083
+ f"Systemic filtered delay offsets in each {winspace} second window",
1084
+ ),
1085
+ (
1086
+ np.square(systemicr2value),
1087
+ "systemicr2value",
1088
+ "info",
1089
+ None,
1090
+ f"R2 values for systemic regression in each {winspace} second window",
1091
+ ),
1092
+ ]
1093
+ if args.focaldebug:
1094
+ maplist += [
1095
+ (
1096
+ systemicsLFOfitmean,
1097
+ "systemicsLFOfitmean",
1098
+ "info",
1099
+ None,
1100
+ "Constant coefficient for systemic filter",
1101
+ ),
1102
+ (
1103
+ systemicfitcoeff[:, 0],
1104
+ "systemiccoffEV0",
1105
+ "info",
1106
+ None,
1107
+ "Coefficient 0 for systemic filter",
1108
+ ),
1109
+ (
1110
+ systemicfitcoeff[:, 1],
1111
+ "systemiccoffEV1",
1112
+ "info",
1113
+ None,
1114
+ "Coefficient 1 for systemic filter",
1115
+ ),
1116
+ ]
1117
+ if reduceddata is not None:
1118
+ maplist += (
1119
+ (
1120
+ reduceddata,
1121
+ "windoweddelayoffsetPCA",
1122
+ "info",
1123
+ None,
1124
+ f"PCA cleaned delay offsets in each {winspace} second window",
1125
+ ),
1126
+ )
1127
+
1128
+ """(
1129
+ filtwindoweddelayoffset,
1130
+ "filtwindoweddelayoffset",
1131
+ "info",
1132
+ None,
1133
+ f"Delay offsets in each {winspace} second window with the systemic component removed",
1134
+ ),"""
1135
+ if args.focaldebug:
1136
+ maplist += [
1137
+ (
1138
+ windowedmedfiltregressderivratios,
1139
+ "windowedmedfiltregressderivratios",
1140
+ "info",
1141
+ None,
1142
+ f"Mediean filtered derivative ratios in each {winspace} second window",
1143
+ ),
1144
+ (
1145
+ windowedfilteredregressderivratios,
1146
+ "windowedfilteredregressderivratios",
1147
+ "info",
1148
+ None,
1149
+ f"Filtered derivative ratios in each {winspace} second window",
1150
+ ),
1151
+ (
1152
+ windowedregressderivratios,
1153
+ "windowedregressderivratios",
1154
+ "info",
1155
+ None,
1156
+ f"Raw derivative ratios in each {winspace} second window",
1157
+ ),
1158
+ ]
1159
+ tide_io.savemaplist(
1160
+ outputname,
1161
+ maplist,
1162
+ validvoxels,
1163
+ (xsize, ysize, numslices, numwins),
1164
+ theheader,
1165
+ bidsbasedict,
1166
+ debug=args.debug,
1167
+ )
1168
+ #########################
1169
+ # End window processing
1170
+ #########################
1171
+
1172
+ # save outputs
1173
+ TimingLGR.info("Starting output save")
1174
+ bidsdict = bidsbasedict.copy()
1175
+
1176
+ # read the runoptions file
1177
+ print("writing runoptions")
1178
+ therunoptions["delayvar_runtime"] = time.strftime(
1179
+ "%a, %d %b %Y %H:%M:%S %Z", time.localtime(time.time())
1180
+ )
1181
+
1182
+ # clean up shared memory
1183
+ if usesharedmem:
1184
+ tide_util.cleanup_shm(winsLFOfitmean_shm)
1185
+ tide_util.cleanup_shm(winrvalue_shm)
1186
+ tide_util.cleanup_shm(winr2value_shm)
1187
+ tide_util.cleanup_shm(winfitNorm_shm)
1188
+ tide_util.cleanup_shm(winitcoeff_shm)
1189
+ tide_util.cleanup_shm(winmovingsignal_shm)
1190
+ tide_util.cleanup_shm(winlagtc_shm)
1191
+ tide_util.cleanup_shm(winfiltereddata_shm)
1192
+ if doregress:
1193
+ tide_util.cleanup_shm(systemicsLFOfitmean_shm)
1194
+ tide_util.cleanup_shm(systemicrvalue_shm)
1195
+ tide_util.cleanup_shm(systemicr2value_shm)
1196
+ tide_util.cleanup_shm(systemicfitNorm_shm)
1197
+ tide_util.cleanup_shm(systemicitcoeff_shm)
1198
+ tide_util.cleanup_shm(systemicmovingsignal_shm)
1199
+ tide_util.cleanup_shm(systemiclagtc_shm)
1200
+ tide_util.cleanup_shm(systemicfiltereddata_shm)
1201
+ TimingLGR.info("Shared memory cleanup complete")
1202
+
1203
+ # shut down logging
1204
+ TimingLGR.info("Done")
1205
+ logging.shutdown()
1206
+
1207
+ # reformat timing information and delete the unformatted version
1208
+ timingdata, therunoptions["totalretroruntime"] = tide_util.proctiminglogfile(
1209
+ f"{outputname}_retroruntimings.tsv"
1210
+ )
1211
+ tide_io.writevec(
1212
+ np.asarray(timingdata),
1213
+ f"{outputname}_desc-formattedretroruntimings_info.tsv",
1214
+ )
1215
+ Path(f"{outputname}_retroruntimings.tsv").unlink(missing_ok=True)
1216
+
1217
+ # save the modified runoptions file
1218
+ tide_io.writedicttojson(therunoptions, f"{outputname}_desc-runoptions_info.json")
1219
+
1220
+ # shut down the loggers
1221
+ for thelogger in [LGR, ErrorLGR, TimingLGR]:
1222
+ handlers = thelogger.handlers[:]
1223
+ for handler in handlers:
1224
+ thelogger.removeHandler(handler)
1225
+ handler.close()
1226
+
1227
+ # delete the canary file
1228
+ Path(f"{outputname}_DELAYVARISRUNNING.txt").unlink()
1229
+
1230
+ # create the finished file
1231
+ Path(f"{outputname}_DELAYVARDONE.txt").touch()
1232
+
1233
+
1234
+ def process_args(inputargs: Optional[Any] = None) -> argparse.Namespace:
1235
+ """
1236
+ Compile arguments for delayvar workflow.
1237
+
1238
+ This function processes input arguments for the delayvar workflow by parsing
1239
+ command line arguments or provided input arguments using a predefined parser.
1240
+
1241
+ Parameters
1242
+ ----------
1243
+ inputargs : Any, optional
1244
+ Input arguments to be processed. Can be None (default) to use command line
1245
+ arguments, or a list of arguments to parse. Default is None.
1246
+
1247
+ Returns
1248
+ -------
1249
+ dict
1250
+ Parsed arguments as a dictionary. The exact structure depends on the
1251
+ argument parser (_get_parser) used internally.
1252
+
1253
+ Notes
1254
+ -----
1255
+ This function internally calls `pf.setargs` with the `_get_parser` function
1256
+ and the provided input arguments. The returned arguments are typically used
1257
+ to configure the delayvar workflow parameters.
1258
+
1259
+ Examples
1260
+ --------
1261
+ >>> # Using default command line arguments
1262
+ >>> args = process_args()
1263
+
1264
+ >>> # Using custom arguments
1265
+ >>> args = process_args(['--input', 'data.txt', '--output', 'result.txt'])
1266
+ """
1267
+ args, argstowrite = pf.setargs(_get_parser, inputargs=inputargs)
1268
+ return args