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