rapidtide 2.9.6__py3-none-any.whl → 3.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +92 -42
- 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 +2 -2
- 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 +108 -92
- 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 +587 -1116
- rapidtide/io.py +2569 -468
- rapidtide/linfitfiltpass.py +784 -0
- rapidtide/makelaggedtcs.py +267 -97
- rapidtide/maskutil.py +555 -25
- rapidtide/miscmath.py +835 -144
- 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.6.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 +26 -14
- 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 +1785 -1858
- rapidtide/workflows/rapidtide2std.py +101 -3
- rapidtide/workflows/rapidtide_parser.py +590 -389
- 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.6.dist-info → rapidtide-3.1.3.dist-info}/METADATA +30 -223
- rapidtide-3.1.3.dist-info/RECORD +393 -0
- {rapidtide-2.9.6.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.6.data/scripts/adjustoffset +0 -23
- rapidtide-2.9.6.data/scripts/aligntcs +0 -23
- rapidtide-2.9.6.data/scripts/applydlfilter +0 -23
- rapidtide-2.9.6.data/scripts/atlasaverage +0 -23
- rapidtide-2.9.6.data/scripts/atlastool +0 -23
- rapidtide-2.9.6.data/scripts/calcicc +0 -22
- rapidtide-2.9.6.data/scripts/calctexticc +0 -23
- rapidtide-2.9.6.data/scripts/calcttest +0 -22
- rapidtide-2.9.6.data/scripts/ccorrica +0 -23
- rapidtide-2.9.6.data/scripts/diffrois +0 -23
- rapidtide-2.9.6.data/scripts/endtidalproc +0 -23
- rapidtide-2.9.6.data/scripts/filtnifti +0 -23
- rapidtide-2.9.6.data/scripts/filttc +0 -23
- rapidtide-2.9.6.data/scripts/fingerprint +0 -593
- rapidtide-2.9.6.data/scripts/fixtr +0 -23
- rapidtide-2.9.6.data/scripts/glmfilt +0 -24
- rapidtide-2.9.6.data/scripts/gmscalc +0 -22
- rapidtide-2.9.6.data/scripts/happy +0 -25
- rapidtide-2.9.6.data/scripts/happy2std +0 -23
- rapidtide-2.9.6.data/scripts/happywarp +0 -350
- rapidtide-2.9.6.data/scripts/histnifti +0 -23
- rapidtide-2.9.6.data/scripts/histtc +0 -23
- rapidtide-2.9.6.data/scripts/localflow +0 -23
- rapidtide-2.9.6.data/scripts/mergequality +0 -23
- rapidtide-2.9.6.data/scripts/pairproc +0 -23
- rapidtide-2.9.6.data/scripts/pairwisemergenifti +0 -23
- rapidtide-2.9.6.data/scripts/physiofreq +0 -23
- rapidtide-2.9.6.data/scripts/pixelcomp +0 -23
- rapidtide-2.9.6.data/scripts/plethquality +0 -23
- rapidtide-2.9.6.data/scripts/polyfitim +0 -23
- rapidtide-2.9.6.data/scripts/proj2flow +0 -23
- rapidtide-2.9.6.data/scripts/rankimage +0 -23
- rapidtide-2.9.6.data/scripts/rapidtide +0 -23
- rapidtide-2.9.6.data/scripts/rapidtide2std +0 -23
- rapidtide-2.9.6.data/scripts/resamplenifti +0 -23
- rapidtide-2.9.6.data/scripts/resampletc +0 -23
- rapidtide-2.9.6.data/scripts/retroglm +0 -23
- rapidtide-2.9.6.data/scripts/roisummarize +0 -23
- rapidtide-2.9.6.data/scripts/runqualitycheck +0 -23
- rapidtide-2.9.6.data/scripts/showarbcorr +0 -23
- rapidtide-2.9.6.data/scripts/showhist +0 -23
- rapidtide-2.9.6.data/scripts/showstxcorr +0 -23
- rapidtide-2.9.6.data/scripts/showtc +0 -23
- rapidtide-2.9.6.data/scripts/showxcorr_legacy +0 -536
- rapidtide-2.9.6.data/scripts/showxcorrx +0 -23
- rapidtide-2.9.6.data/scripts/showxy +0 -23
- rapidtide-2.9.6.data/scripts/simdata +0 -23
- rapidtide-2.9.6.data/scripts/spatialdecomp +0 -23
- rapidtide-2.9.6.data/scripts/spatialfit +0 -23
- rapidtide-2.9.6.data/scripts/spatialmi +0 -23
- rapidtide-2.9.6.data/scripts/spectrogram +0 -23
- rapidtide-2.9.6.data/scripts/synthASL +0 -23
- rapidtide-2.9.6.data/scripts/tcfrom2col +0 -23
- rapidtide-2.9.6.data/scripts/tcfrom3col +0 -23
- rapidtide-2.9.6.data/scripts/temporaldecomp +0 -23
- rapidtide-2.9.6.data/scripts/threeD +0 -236
- rapidtide-2.9.6.data/scripts/tidepool +0 -23
- rapidtide-2.9.6.data/scripts/variabilityizer +0 -23
- rapidtide-2.9.6.dist-info/RECORD +0 -359
- rapidtide-2.9.6.dist-info/top_level.txt +0 -86
- {rapidtide-2.9.6.dist-info → rapidtide-3.1.3.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,1501 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2024-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 platform
|
|
24
|
+
import sys
|
|
25
|
+
import time
|
|
26
|
+
from argparse import Namespace
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
|
29
|
+
|
|
30
|
+
import numpy as np
|
|
31
|
+
from numpy.typing import NDArray
|
|
32
|
+
|
|
33
|
+
import rapidtide.filter as tide_filt
|
|
34
|
+
import rapidtide.io as tide_io
|
|
35
|
+
import rapidtide.maskutil as tide_mask
|
|
36
|
+
import rapidtide.miscmath as tide_math
|
|
37
|
+
import rapidtide.multiproc as tide_multiproc
|
|
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.refineDelayMap as tide_refineDelayMap
|
|
44
|
+
import rapidtide.workflows.regressfrommaps as tide_regressfrommaps
|
|
45
|
+
|
|
46
|
+
from .rapidtide_parser import DEFAULT_REGRESSIONFILTDERIVS
|
|
47
|
+
from .utils import setup_logger
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# Create a sentinel.
|
|
51
|
+
# from https://stackoverflow.com/questions/58594956/find-out-which-arguments-were-passed-explicitly-in-argparse
|
|
52
|
+
class _Sentinel:
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
sentinel = _Sentinel()
|
|
57
|
+
LGR = logging.getLogger(__name__)
|
|
58
|
+
ErrorLGR = logging.getLogger("ERROR")
|
|
59
|
+
TimingLGR = logging.getLogger("TIMING")
|
|
60
|
+
|
|
61
|
+
DEFAULT_REGRESSIONFILTDERIVS = 0
|
|
62
|
+
DEFAULT_PATCHTHRESH = 3.0
|
|
63
|
+
DEFAULT_REFINEDELAYMINDELAY = -5.0
|
|
64
|
+
DEFAULT_REFINEDELAYMAXDELAY = 5.0
|
|
65
|
+
DEFAULT_REFINEDELAYNUMPOINTS = 501
|
|
66
|
+
DEFAULT_DELAYOFFSETSPATIALFILT = -1
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _get_parser() -> Any:
|
|
70
|
+
"""
|
|
71
|
+
Argument parser for glmfilt.
|
|
72
|
+
|
|
73
|
+
This function constructs and returns an `argparse.ArgumentParser` object configured
|
|
74
|
+
for the `glmfilt` command-line tool, which performs sLFO (spatially localized
|
|
75
|
+
filter) filtering using maps generated from a previous rapidtide analysis.
|
|
76
|
+
|
|
77
|
+
Returns
|
|
78
|
+
-------
|
|
79
|
+
argparse.ArgumentParser
|
|
80
|
+
Configured argument parser for the glmfilt command-line interface.
|
|
81
|
+
|
|
82
|
+
Notes
|
|
83
|
+
-----
|
|
84
|
+
The parser includes both standard and experimental options. Experimental options
|
|
85
|
+
are not fully tested and may not work as expected.
|
|
86
|
+
|
|
87
|
+
Examples
|
|
88
|
+
--------
|
|
89
|
+
>>> parser = _get_parser()
|
|
90
|
+
>>> args = parser.parse_args(['fmri.nii', 'dataset_root'])
|
|
91
|
+
>>> print(args.fmrifile)
|
|
92
|
+
'fmri.nii'
|
|
93
|
+
"""
|
|
94
|
+
parser = argparse.ArgumentParser(
|
|
95
|
+
prog="retroregress",
|
|
96
|
+
description="Do the rapidtide sLFO filtering using the maps generated from a previous analysis.",
|
|
97
|
+
allow_abbrev=False,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# Required arguments
|
|
101
|
+
parser.add_argument(
|
|
102
|
+
"fmrifile",
|
|
103
|
+
type=lambda x: pf.is_valid_file(parser, x),
|
|
104
|
+
help="The name of 4D nifti fmri file to filter.",
|
|
105
|
+
)
|
|
106
|
+
parser.add_argument(
|
|
107
|
+
"datafileroot",
|
|
108
|
+
type=str,
|
|
109
|
+
help="The root name of the previously run rapidtide dataset (everything up to but not including the underscore.)",
|
|
110
|
+
)
|
|
111
|
+
parser.add_argument(
|
|
112
|
+
"--alternateoutput",
|
|
113
|
+
dest="alternateoutput",
|
|
114
|
+
type=str,
|
|
115
|
+
help="Alternate output root (if not specified, will use the same root as the previous dataset).",
|
|
116
|
+
default=None,
|
|
117
|
+
)
|
|
118
|
+
parser.add_argument(
|
|
119
|
+
"--regressderivs",
|
|
120
|
+
dest="regressderivs",
|
|
121
|
+
action="store",
|
|
122
|
+
type=lambda x: pf.is_int(parser, x, minval=0),
|
|
123
|
+
metavar="NDERIVS",
|
|
124
|
+
help=(
|
|
125
|
+
f"When doing final GLM, include derivatives up to NDERIVS order. Default is {DEFAULT_REGRESSIONFILTDERIVS}"
|
|
126
|
+
),
|
|
127
|
+
default=DEFAULT_REGRESSIONFILTDERIVS,
|
|
128
|
+
)
|
|
129
|
+
parser.add_argument(
|
|
130
|
+
"--nprocs",
|
|
131
|
+
dest="nprocs",
|
|
132
|
+
action="store",
|
|
133
|
+
type=int,
|
|
134
|
+
metavar="NPROCS",
|
|
135
|
+
help=(
|
|
136
|
+
"Use NPROCS worker processes for multiprocessing. "
|
|
137
|
+
"Setting NPROCS to less than 1 sets the number of "
|
|
138
|
+
"worker processes to n_cpus."
|
|
139
|
+
),
|
|
140
|
+
default=1,
|
|
141
|
+
)
|
|
142
|
+
parser.add_argument(
|
|
143
|
+
"--numskip",
|
|
144
|
+
dest="numskip",
|
|
145
|
+
action="store",
|
|
146
|
+
type=lambda x: pf.is_int(parser, x, minval=0),
|
|
147
|
+
metavar="NUMSKIP",
|
|
148
|
+
help=("Skip NUMSKIP points at the beginning of the fmri file."),
|
|
149
|
+
default=0,
|
|
150
|
+
)
|
|
151
|
+
parser.add_argument(
|
|
152
|
+
"--outputlevel",
|
|
153
|
+
dest="outputlevel",
|
|
154
|
+
action="store",
|
|
155
|
+
type=str,
|
|
156
|
+
choices=["min", "less", "normal", "more", "max", "onlyregressors"],
|
|
157
|
+
help=(
|
|
158
|
+
"The level of file output produced. 'min' produces only absolutely essential files, 'less' adds in "
|
|
159
|
+
"the sLFO filtered data (rather than just filter efficacy metrics), 'normal' saves what you "
|
|
160
|
+
"would typically want around for interactive data exploration, "
|
|
161
|
+
"'more' adds files that are sometimes useful, and 'max' outputs anything you might possibly want. "
|
|
162
|
+
"Selecting 'max' will produce ~3x your input datafile size as output. 'onlyregressors' will ONLY generate the "
|
|
163
|
+
"voxelwise timecourses to filter and save them without actually running the filter. "
|
|
164
|
+
f'Default is "normal".'
|
|
165
|
+
),
|
|
166
|
+
default="normal",
|
|
167
|
+
)
|
|
168
|
+
parser.add_argument(
|
|
169
|
+
"--noprogressbar",
|
|
170
|
+
dest="showprogressbar",
|
|
171
|
+
action="store_false",
|
|
172
|
+
help=("Will disable showing progress bars (helpful if stdout is going to a file)."),
|
|
173
|
+
default=True,
|
|
174
|
+
)
|
|
175
|
+
parser.add_argument(
|
|
176
|
+
"--makepseudofile",
|
|
177
|
+
dest="makepseudofile",
|
|
178
|
+
action="store_true",
|
|
179
|
+
help=("Make a simulated input file from the mean and the movingsignal."),
|
|
180
|
+
default=False,
|
|
181
|
+
)
|
|
182
|
+
parser.add_argument(
|
|
183
|
+
"--norefinedelay",
|
|
184
|
+
dest="refinedelay",
|
|
185
|
+
action="store_false",
|
|
186
|
+
help=("Do not calculate a refined delay map using GLM information."),
|
|
187
|
+
default=True,
|
|
188
|
+
)
|
|
189
|
+
parser.add_argument(
|
|
190
|
+
"--norefinecorr",
|
|
191
|
+
dest="refinecorr",
|
|
192
|
+
action="store_false",
|
|
193
|
+
help=(
|
|
194
|
+
"Don't recalculate the maxcorr map using GLM coefficient of determination from bandpassed data."
|
|
195
|
+
),
|
|
196
|
+
default=True,
|
|
197
|
+
)
|
|
198
|
+
parser.add_argument(
|
|
199
|
+
"--nofilterwithrefineddelay",
|
|
200
|
+
dest="filterwithrefineddelay",
|
|
201
|
+
action="store_false",
|
|
202
|
+
help=("Do not use the refined delay in sLFO filter."),
|
|
203
|
+
default=True,
|
|
204
|
+
)
|
|
205
|
+
parser.add_argument(
|
|
206
|
+
"--delaypatchthresh",
|
|
207
|
+
dest="delaypatchthresh",
|
|
208
|
+
action="store",
|
|
209
|
+
type=float,
|
|
210
|
+
metavar="NUMMADs",
|
|
211
|
+
help=(
|
|
212
|
+
"Maximum number of robust standard deviations to permit in the offset delay refine map. "
|
|
213
|
+
f"Default is {DEFAULT_PATCHTHRESH}"
|
|
214
|
+
),
|
|
215
|
+
default=DEFAULT_PATCHTHRESH,
|
|
216
|
+
)
|
|
217
|
+
parser.add_argument(
|
|
218
|
+
"--delayoffsetspatialfilt",
|
|
219
|
+
dest="delayoffsetgausssigma",
|
|
220
|
+
action="store",
|
|
221
|
+
type=float,
|
|
222
|
+
metavar="GAUSSSIGMA",
|
|
223
|
+
help=(
|
|
224
|
+
"Spatially filter fMRI data prior to calculating delay offsets "
|
|
225
|
+
"using GAUSSSIGMA in mm. Set GAUSSSIGMA negative "
|
|
226
|
+
"to have rapidtide set it to half the mean voxel "
|
|
227
|
+
"dimension (a rule of thumb for a good value)."
|
|
228
|
+
),
|
|
229
|
+
default=DEFAULT_DELAYOFFSETSPATIALFILT,
|
|
230
|
+
)
|
|
231
|
+
parser.add_argument(
|
|
232
|
+
"--debug",
|
|
233
|
+
dest="debug",
|
|
234
|
+
action="store_true",
|
|
235
|
+
help=("Output lots of helpful information."),
|
|
236
|
+
default=False,
|
|
237
|
+
)
|
|
238
|
+
parser.add_argument(
|
|
239
|
+
"--focaldebug",
|
|
240
|
+
dest="focaldebug",
|
|
241
|
+
action="store_true",
|
|
242
|
+
help=("Output lots of helpful information on a limited subset of operations."),
|
|
243
|
+
default=False,
|
|
244
|
+
)
|
|
245
|
+
parser.add_argument(
|
|
246
|
+
"--sLFOfiltmask",
|
|
247
|
+
dest="sLFOfiltmask",
|
|
248
|
+
action="store_true",
|
|
249
|
+
help=("Limit sLFO filter to fit voxels."),
|
|
250
|
+
default=False,
|
|
251
|
+
)
|
|
252
|
+
experimental = parser.add_argument_group(
|
|
253
|
+
"Experimental options (not fully tested, or not tested at all, may not work). Beware!"
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
return parser
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def retroregress(args: Any) -> None:
|
|
260
|
+
"""
|
|
261
|
+
Perform retrospective regression analysis on fMRI data to filter out slow
|
|
262
|
+
physiological noise (sLFO).
|
|
263
|
+
|
|
264
|
+
This function applies a retrospective regression approach to remove slow
|
|
265
|
+
physiological noise from fMRI data. It uses a delayed sLFO regressor to
|
|
266
|
+
model and remove the noise, optionally refining the delay using temporal
|
|
267
|
+
derivatives of the regressor.
|
|
268
|
+
|
|
269
|
+
Parameters
|
|
270
|
+
----------
|
|
271
|
+
args : argparse.Namespace
|
|
272
|
+
Command-line arguments parsed by argparse. Expected attributes include:
|
|
273
|
+
- data_root : str
|
|
274
|
+
Root path for input data files
|
|
275
|
+
- output_prefix : str
|
|
276
|
+
Prefix for output files
|
|
277
|
+
- filter_type : str
|
|
278
|
+
Type of filtering to apply (e.g., 'bandpass')
|
|
279
|
+
- filter_low : float
|
|
280
|
+
Low cutoff frequency for filtering
|
|
281
|
+
- filter_high : float
|
|
282
|
+
High cutoff frequency for filtering
|
|
283
|
+
- regress_derivs : int
|
|
284
|
+
Number of temporal derivatives to include in the regressor
|
|
285
|
+
- refinedelay : bool
|
|
286
|
+
Whether to refine the delay using temporal derivatives
|
|
287
|
+
- refinecorr : bool
|
|
288
|
+
Whether to compute correlation refinement
|
|
289
|
+
- savemovingsignal : bool
|
|
290
|
+
Whether to save the filtered signal
|
|
291
|
+
- savenormalsLFOfiltfiles : bool
|
|
292
|
+
Whether to save standard output files
|
|
293
|
+
- saveminimumsLFOfiltfiles : bool
|
|
294
|
+
Whether to save minimum output files
|
|
295
|
+
- saveallsLFOfiltfiles : bool
|
|
296
|
+
Whether to save all output files
|
|
297
|
+
- makepseudofile : bool
|
|
298
|
+
Whether to create a pseudo-file
|
|
299
|
+
- nprocs : int
|
|
300
|
+
Number of processes to use
|
|
301
|
+
- debug : bool
|
|
302
|
+
Enable debug mode
|
|
303
|
+
- focaldebug : bool
|
|
304
|
+
Enable focal debug mode
|
|
305
|
+
|
|
306
|
+
Returns
|
|
307
|
+
-------
|
|
308
|
+
None
|
|
309
|
+
This function does not return a value but writes output files to disk.
|
|
310
|
+
|
|
311
|
+
Notes
|
|
312
|
+
-----
|
|
313
|
+
The function performs the following steps:
|
|
314
|
+
1. Reads input data files including mean image, correlation mask, and processed mask
|
|
315
|
+
2. Applies temporal filtering to the input data
|
|
316
|
+
3. Performs GLM regression using delayed sLFO regressors
|
|
317
|
+
4. Refines delay if requested using temporal derivatives
|
|
318
|
+
5. Saves output files including filtered data, regressors, and timing information
|
|
319
|
+
|
|
320
|
+
Examples
|
|
321
|
+
--------
|
|
322
|
+
>>> import argparse
|
|
323
|
+
>>> args = argparse.Namespace(
|
|
324
|
+
... data_root='path/to/data',
|
|
325
|
+
... output_prefix='output',
|
|
326
|
+
... filter_type='bandpass',
|
|
327
|
+
... filter_low=0.01,
|
|
328
|
+
... filter_high=0.1,
|
|
329
|
+
... regress_derivs=2,
|
|
330
|
+
... refinedelay=True,
|
|
331
|
+
... refinecorr=False,
|
|
332
|
+
... savemovingsignal=True,
|
|
333
|
+
... savenormalsLFOfiltfiles=True,
|
|
334
|
+
... saveminimumsLFOfiltfiles=True,
|
|
335
|
+
... saveallsLFOfiltfiles=False,
|
|
336
|
+
... makepseudofile=False,
|
|
337
|
+
... nprocs=4,
|
|
338
|
+
... debug=False,
|
|
339
|
+
... focaldebug=False
|
|
340
|
+
... )
|
|
341
|
+
>>> retroregress(args)
|
|
342
|
+
"""
|
|
343
|
+
# get the pid of the parent process
|
|
344
|
+
args.pid = os.getpid()
|
|
345
|
+
|
|
346
|
+
# specify the output name
|
|
347
|
+
if args.alternateoutput is None:
|
|
348
|
+
outputname = args.datafileroot
|
|
349
|
+
else:
|
|
350
|
+
outputname = args.alternateoutput
|
|
351
|
+
|
|
352
|
+
# start the loggers low that we know the output name
|
|
353
|
+
sh = logging.StreamHandler()
|
|
354
|
+
if args.debug:
|
|
355
|
+
logging.basicConfig(level=logging.DEBUG, handlers=[sh])
|
|
356
|
+
else:
|
|
357
|
+
logging.basicConfig(level=logging.INFO, handlers=[sh])
|
|
358
|
+
# Set up loggers for workflow
|
|
359
|
+
setup_logger(
|
|
360
|
+
logger_filename=f"{outputname}_retrolog.txt",
|
|
361
|
+
timing_filename=f"{outputname}_retroruntimings.tsv",
|
|
362
|
+
error_filename=f"{outputname}_retroerrorlog.txt",
|
|
363
|
+
isverbose=False,
|
|
364
|
+
debug=args.debug,
|
|
365
|
+
)
|
|
366
|
+
TimingLGR.info("Start")
|
|
367
|
+
LGR.info(f"starting retroregress")
|
|
368
|
+
|
|
369
|
+
# set some global values
|
|
370
|
+
args.mindelay = DEFAULT_REFINEDELAYMINDELAY
|
|
371
|
+
args.maxdelay = DEFAULT_REFINEDELAYMAXDELAY
|
|
372
|
+
args.numpoints = DEFAULT_REFINEDELAYNUMPOINTS
|
|
373
|
+
|
|
374
|
+
if args.outputlevel == "min":
|
|
375
|
+
args.saveminimumsLFOfiltfiles = False
|
|
376
|
+
args.savenormalsLFOfiltfiles = False
|
|
377
|
+
args.savemovingsignal = False
|
|
378
|
+
args.saveallsLFOfiltfiles = False
|
|
379
|
+
args.saveEVsandquit = False
|
|
380
|
+
elif args.outputlevel == "less":
|
|
381
|
+
args.saveminimumsLFOfiltfiles = True
|
|
382
|
+
args.savenormalsLFOfiltfiles = False
|
|
383
|
+
args.savemovingsignal = False
|
|
384
|
+
args.saveallsLFOfiltfiles = False
|
|
385
|
+
args.saveEVsandquit = False
|
|
386
|
+
elif args.outputlevel == "normal":
|
|
387
|
+
args.saveminimumsLFOfiltfiles = True
|
|
388
|
+
args.savenormalsLFOfiltfiles = True
|
|
389
|
+
args.savemovingsignal = False
|
|
390
|
+
args.saveallsLFOfiltfiles = False
|
|
391
|
+
args.saveEVsandquit = False
|
|
392
|
+
elif args.outputlevel == "more":
|
|
393
|
+
args.saveminimumsLFOfiltfiles = True
|
|
394
|
+
args.savenormalsLFOfiltfiles = True
|
|
395
|
+
args.savemovingsignal = True
|
|
396
|
+
args.saveallsLFOfiltfiles = False
|
|
397
|
+
args.saveEVsandquit = False
|
|
398
|
+
elif args.outputlevel == "max":
|
|
399
|
+
args.saveminimumsLFOfiltfiles = True
|
|
400
|
+
args.savenormalsLFOfiltfiles = True
|
|
401
|
+
args.savemovingsignal = True
|
|
402
|
+
args.saveallsLFOfiltfiles = True
|
|
403
|
+
args.saveEVsandquit = False
|
|
404
|
+
elif args.outputlevel == "onlyregressors":
|
|
405
|
+
args.saveminimumsLFOfiltfiles = False
|
|
406
|
+
args.savenormalsLFOfiltfiles = False
|
|
407
|
+
args.savemovingsignal = False
|
|
408
|
+
args.saveallsLFOfiltfiles = False
|
|
409
|
+
args.saveEVsandquit = True
|
|
410
|
+
else:
|
|
411
|
+
print(f"illegal output level {args.outputlevel}")
|
|
412
|
+
sys.exit()
|
|
413
|
+
|
|
414
|
+
# save the raw and formatted command lines
|
|
415
|
+
argstowrite = sys.argv
|
|
416
|
+
thecommandline = " ".join(sys.argv[1:])
|
|
417
|
+
tide_io.writevec(np.asarray([thecommandline]), f"{outputname}_retrocommandline.txt")
|
|
418
|
+
formattedcommandline = []
|
|
419
|
+
for thetoken in argstowrite[0:3]:
|
|
420
|
+
formattedcommandline.append(thetoken)
|
|
421
|
+
for thetoken in argstowrite[3:]:
|
|
422
|
+
if thetoken[0:2] == "--":
|
|
423
|
+
formattedcommandline.append(thetoken)
|
|
424
|
+
else:
|
|
425
|
+
formattedcommandline[-1] += " " + thetoken
|
|
426
|
+
for i in range(len(formattedcommandline)):
|
|
427
|
+
if i > 0:
|
|
428
|
+
prefix = " "
|
|
429
|
+
else:
|
|
430
|
+
prefix = ""
|
|
431
|
+
if i < len(formattedcommandline) - 1:
|
|
432
|
+
suffix = " \\"
|
|
433
|
+
else:
|
|
434
|
+
suffix = ""
|
|
435
|
+
formattedcommandline[i] = prefix + formattedcommandline[i] + suffix
|
|
436
|
+
tide_io.writevec(
|
|
437
|
+
np.asarray(formattedcommandline), f"{outputname}_retroformattedcommandline.txt"
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
if args.nprocs < 1:
|
|
441
|
+
args.nprocs = tide_multiproc.maxcpus()
|
|
442
|
+
# don't use shared memory if there is only one process
|
|
443
|
+
if args.nprocs == 1:
|
|
444
|
+
usesharedmem = False
|
|
445
|
+
else:
|
|
446
|
+
usesharedmem = True
|
|
447
|
+
|
|
448
|
+
# read the runoptions file, update if necessary
|
|
449
|
+
print("reading runoptions")
|
|
450
|
+
runoptionsfile = f"{args.datafileroot}_desc-runoptions_info"
|
|
451
|
+
therunoptions = tide_io.readoptionsfile(runoptionsfile)
|
|
452
|
+
sublist = (
|
|
453
|
+
("retroglmcompatible", "retroregresscompatible"),
|
|
454
|
+
("glmthreshval", "regressfiltthreshval"),
|
|
455
|
+
)
|
|
456
|
+
therunoptions["singleproc_regressionfilt"] = False
|
|
457
|
+
therunoptions["nprocs_regressionfilt"] = args.nprocs
|
|
458
|
+
for subpair in sublist:
|
|
459
|
+
try:
|
|
460
|
+
therunoptions[subpair[1]] = therunoptions[subpair[0]]
|
|
461
|
+
print(f"substituting {subpair[1]} for {subpair[0]} in runoptions")
|
|
462
|
+
except KeyError:
|
|
463
|
+
pass
|
|
464
|
+
|
|
465
|
+
try:
|
|
466
|
+
candoretroregress = therunoptions["retroregresscompatible"]
|
|
467
|
+
except KeyError:
|
|
468
|
+
print(
|
|
469
|
+
f"based on {runoptionsfile}, this rapidtide dataset does not support retrospective GLM calculation"
|
|
470
|
+
)
|
|
471
|
+
sys.exit()
|
|
472
|
+
|
|
473
|
+
if therunoptions["internalprecision"] == "double":
|
|
474
|
+
rt_floattype = np.dtype(np.float64)
|
|
475
|
+
else:
|
|
476
|
+
rt_floattype = np.dtype(np.float32)
|
|
477
|
+
|
|
478
|
+
# set the output precision
|
|
479
|
+
if therunoptions["outputprecision"] == "double":
|
|
480
|
+
rt_outfloattype = np.dtype(np.float64)
|
|
481
|
+
else:
|
|
482
|
+
rt_outfloattype = np.dtype(np.float32)
|
|
483
|
+
therunoptions["saveminimumsLFOfiltfiles"] = args.saveminimumsLFOfiltfiles
|
|
484
|
+
|
|
485
|
+
# read the fmri input files
|
|
486
|
+
print("reading fmrifile")
|
|
487
|
+
theinputdata = tide_voxelData.VoxelData(args.fmrifile)
|
|
488
|
+
xsize, ysize, numslices, timepoints = theinputdata.getdims()
|
|
489
|
+
xdim, ydim, slicethickness, fmritr = theinputdata.getsizes()
|
|
490
|
+
fmri_header = theinputdata.copyheader()
|
|
491
|
+
fmri_data = theinputdata.byvol()
|
|
492
|
+
numspatiallocs = theinputdata.numspatiallocs
|
|
493
|
+
|
|
494
|
+
# create the canary file
|
|
495
|
+
Path(f"{outputname}_RETROISRUNNING.txt").touch()
|
|
496
|
+
|
|
497
|
+
if args.debug:
|
|
498
|
+
print(f"{fmri_data.shape=}")
|
|
499
|
+
fmri_data_spacebytime = theinputdata.byvoxel()
|
|
500
|
+
if args.debug:
|
|
501
|
+
print(f"{fmri_data_spacebytime.shape=}")
|
|
502
|
+
|
|
503
|
+
# read the processed mask
|
|
504
|
+
print("reading procfit maskfile")
|
|
505
|
+
procmaskfile = f"{args.datafileroot}_desc-processed_mask.nii.gz"
|
|
506
|
+
(
|
|
507
|
+
procmask_input,
|
|
508
|
+
procmask,
|
|
509
|
+
procmask_header,
|
|
510
|
+
procmask_dims,
|
|
511
|
+
procmask_sizes,
|
|
512
|
+
) = tide_io.readfromnifti(procmaskfile)
|
|
513
|
+
if not tide_io.checkspacematch(fmri_header, procmask_header):
|
|
514
|
+
raise ValueError("procmask dimensions do not match fmri dimensions")
|
|
515
|
+
procmask_spacebytime = procmask.reshape((numspatiallocs))
|
|
516
|
+
if args.debug:
|
|
517
|
+
print(f"{procmask_spacebytime.shape=}")
|
|
518
|
+
print(f"{tide_stats.getmasksize(procmask_spacebytime)=}")
|
|
519
|
+
|
|
520
|
+
# read the corrfit mask
|
|
521
|
+
print("reading corrfit maskfile")
|
|
522
|
+
corrmaskfile = f"{args.datafileroot}_desc-corrfit_mask.nii.gz"
|
|
523
|
+
(
|
|
524
|
+
corrmask_input,
|
|
525
|
+
corrmask,
|
|
526
|
+
corrmask_header,
|
|
527
|
+
corrmask_dims,
|
|
528
|
+
corrmask_sizes,
|
|
529
|
+
) = tide_io.readfromnifti(corrmaskfile)
|
|
530
|
+
if not tide_io.checkspacematch(fmri_header, corrmask_header):
|
|
531
|
+
raise ValueError("corrmask dimensions do not match fmri dimensions")
|
|
532
|
+
corrmask_spacebytime = corrmask.reshape((numspatiallocs))
|
|
533
|
+
if args.debug:
|
|
534
|
+
print(f"{corrmask_spacebytime.shape=}")
|
|
535
|
+
print(f"{tide_stats.getmasksize(corrmask_spacebytime)=}")
|
|
536
|
+
|
|
537
|
+
print("reading lagtimes")
|
|
538
|
+
lagtimesfile = f"{args.datafileroot}_desc-maxtime_map.nii.gz"
|
|
539
|
+
(
|
|
540
|
+
lagtimes_input,
|
|
541
|
+
lagtimes,
|
|
542
|
+
lagtimes_header,
|
|
543
|
+
lagtimes_dims,
|
|
544
|
+
lagtimes_sizes,
|
|
545
|
+
) = tide_io.readfromnifti(lagtimesfile)
|
|
546
|
+
if not tide_io.checkspacematch(fmri_header, lagtimes_header):
|
|
547
|
+
raise ValueError("lagtimes dimensions do not match fmri dimensions")
|
|
548
|
+
if args.debug:
|
|
549
|
+
print(f"{lagtimes.shape=}")
|
|
550
|
+
lagtimes_spacebytime = lagtimes.reshape((numspatiallocs))
|
|
551
|
+
if args.debug:
|
|
552
|
+
print(f"{lagtimes_spacebytime.shape=}")
|
|
553
|
+
|
|
554
|
+
startpt = args.numskip
|
|
555
|
+
endpt = timepoints - 1
|
|
556
|
+
validtimepoints = endpt - startpt + 1
|
|
557
|
+
skiptime = startpt * fmritr
|
|
558
|
+
initial_fmri_x = (
|
|
559
|
+
np.linspace(0.0, validtimepoints * fmritr, num=validtimepoints, endpoint=False) + skiptime
|
|
560
|
+
)
|
|
561
|
+
|
|
562
|
+
if therunoptions["arbvec"] is not None:
|
|
563
|
+
# NOTE - this vector is LOWERPASS, UPPERPASS, LOWERSTOP, UPPERSTOP
|
|
564
|
+
# setfreqs expects LOWERSTOP, LOWERPASS, UPPERPASS, UPPERSTOP
|
|
565
|
+
theprefilter = tide_filt.NoncausalFilter(
|
|
566
|
+
"arb",
|
|
567
|
+
transferfunc=therunoptions["filtertype"],
|
|
568
|
+
)
|
|
569
|
+
theprefilter.setfreqs(
|
|
570
|
+
therunoptions["arbvec"][2],
|
|
571
|
+
therunoptions["arbvec"][0],
|
|
572
|
+
therunoptions["arbvec"][1],
|
|
573
|
+
therunoptions["arbvec"][3],
|
|
574
|
+
)
|
|
575
|
+
else:
|
|
576
|
+
theprefilter = tide_filt.NoncausalFilter(
|
|
577
|
+
therunoptions["filterband"],
|
|
578
|
+
transferfunc=therunoptions["filtertype"],
|
|
579
|
+
padtime=therunoptions["padseconds"],
|
|
580
|
+
)
|
|
581
|
+
|
|
582
|
+
# read the lagtc generator file
|
|
583
|
+
print("reading lagtc generator")
|
|
584
|
+
lagtcgeneratorfile = f"{args.datafileroot}_desc-lagtcgenerator_timeseries"
|
|
585
|
+
try:
|
|
586
|
+
thepadtime = therunoptions["fastresamplerpadtime"]
|
|
587
|
+
except KeyError:
|
|
588
|
+
thepadtime = therunoptions["padseconds"]
|
|
589
|
+
genlagtc = tide_resample.FastResamplerFromFile(lagtcgeneratorfile, padtime=thepadtime)
|
|
590
|
+
|
|
591
|
+
# select the voxels in the mask
|
|
592
|
+
print("figuring out valid voxels")
|
|
593
|
+
validvoxels = np.where(procmask_spacebytime > 0)[0]
|
|
594
|
+
numvalidspatiallocs = np.shape(validvoxels)[0]
|
|
595
|
+
if args.debug:
|
|
596
|
+
print(f"{numvalidspatiallocs=}")
|
|
597
|
+
internalvalidspaceshape = numvalidspatiallocs
|
|
598
|
+
if args.refinedelay:
|
|
599
|
+
derivaxissize = np.max([2, args.regressderivs + 1])
|
|
600
|
+
else:
|
|
601
|
+
derivaxissize = args.regressderivs + 1
|
|
602
|
+
internalvalidspaceshapederivs = (
|
|
603
|
+
internalvalidspaceshape,
|
|
604
|
+
derivaxissize,
|
|
605
|
+
)
|
|
606
|
+
internalvalidfmrishape = (numvalidspatiallocs, np.shape(initial_fmri_x)[0])
|
|
607
|
+
if args.debug:
|
|
608
|
+
print(f"validvoxels shape = {numvalidspatiallocs}")
|
|
609
|
+
print(f"internalvalidfmrishape shape = {internalvalidfmrishape}")
|
|
610
|
+
|
|
611
|
+
# slicing to valid voxels
|
|
612
|
+
print("selecting valid voxels")
|
|
613
|
+
fmri_data_valid = fmri_data_spacebytime[validvoxels, :]
|
|
614
|
+
lagtimes_valid = lagtimes_spacebytime[validvoxels]
|
|
615
|
+
corrmask_valid = corrmask_spacebytime[validvoxels]
|
|
616
|
+
procmask_valid = procmask_spacebytime[validvoxels]
|
|
617
|
+
if args.sLFOfiltmask:
|
|
618
|
+
sLFOfiltmask_valid = corrmask_spacebytime[validvoxels] + 0.0
|
|
619
|
+
else:
|
|
620
|
+
sLFOfiltmask_valid = np.ones_like(corrmask_spacebytime[validvoxels])
|
|
621
|
+
if args.debug:
|
|
622
|
+
print(f"{fmri_data_valid.shape=}")
|
|
623
|
+
|
|
624
|
+
sLFOfitmean, sLFOfitmean_shm = tide_util.allocarray(
|
|
625
|
+
internalvalidspaceshape, rt_outfloattype, shared=usesharedmem
|
|
626
|
+
)
|
|
627
|
+
rvalue, rvalue_shm = tide_util.allocarray(
|
|
628
|
+
internalvalidspaceshape, rt_outfloattype, shared=usesharedmem
|
|
629
|
+
)
|
|
630
|
+
r2value, r2value_shm = tide_util.allocarray(
|
|
631
|
+
internalvalidspaceshape, rt_outfloattype, shared=usesharedmem
|
|
632
|
+
)
|
|
633
|
+
fitNorm, fitNorm_shm = tide_util.allocarray(
|
|
634
|
+
internalvalidspaceshapederivs, rt_outfloattype, shared=usesharedmem
|
|
635
|
+
)
|
|
636
|
+
fitcoeff, fitcoeff_shm = tide_util.allocarray(
|
|
637
|
+
internalvalidspaceshapederivs, rt_outfloattype, shared=usesharedmem
|
|
638
|
+
)
|
|
639
|
+
movingsignal, movingsignal_shm = tide_util.allocarray(
|
|
640
|
+
internalvalidfmrishape, rt_outfloattype, shared=usesharedmem
|
|
641
|
+
)
|
|
642
|
+
lagtc, lagtc_shm = tide_util.allocarray(
|
|
643
|
+
internalvalidfmrishape, rt_floattype, shared=usesharedmem
|
|
644
|
+
)
|
|
645
|
+
filtereddata, filtereddata_shm = tide_util.allocarray(
|
|
646
|
+
internalvalidfmrishape, rt_outfloattype, shared=usesharedmem
|
|
647
|
+
)
|
|
648
|
+
if usesharedmem:
|
|
649
|
+
if args.debug:
|
|
650
|
+
print("allocating shared memory")
|
|
651
|
+
ramlocation = "in shared memory"
|
|
652
|
+
else:
|
|
653
|
+
if args.debug:
|
|
654
|
+
print("allocating memory")
|
|
655
|
+
ramlocation = "locally"
|
|
656
|
+
|
|
657
|
+
totalbytes = (
|
|
658
|
+
sLFOfitmean.nbytes
|
|
659
|
+
+ rvalue.nbytes
|
|
660
|
+
+ r2value.nbytes
|
|
661
|
+
+ fitNorm.nbytes
|
|
662
|
+
+ fitcoeff.nbytes
|
|
663
|
+
+ movingsignal.nbytes
|
|
664
|
+
+ lagtc.nbytes
|
|
665
|
+
+ filtereddata.nbytes
|
|
666
|
+
)
|
|
667
|
+
thesize, theunit = tide_util.format_bytes(totalbytes)
|
|
668
|
+
ramstring = f"allocated {thesize:.3f} {theunit} {ramlocation}"
|
|
669
|
+
print(ramstring)
|
|
670
|
+
therunoptions["totalretrobytes"] = totalbytes
|
|
671
|
+
|
|
672
|
+
oversampfactor = int(therunoptions["oversampfactor"])
|
|
673
|
+
if args.debug:
|
|
674
|
+
print(f"{outputname=}")
|
|
675
|
+
oversamptr = fmritr / oversampfactor
|
|
676
|
+
try:
|
|
677
|
+
threshval = therunoptions["regressfiltthreshval"]
|
|
678
|
+
except KeyError:
|
|
679
|
+
threshval = 0.0
|
|
680
|
+
therunoptions["regressfiltthreshval"] = threshval
|
|
681
|
+
mode = "glm"
|
|
682
|
+
|
|
683
|
+
if args.debug:
|
|
684
|
+
print(f"{validvoxels.shape=}")
|
|
685
|
+
np.savetxt(f"{outputname}_validvoxels.txt", validvoxels)
|
|
686
|
+
|
|
687
|
+
outputpath = os.path.dirname(outputname)
|
|
688
|
+
rawsources = [
|
|
689
|
+
os.path.relpath(args.fmrifile, start=outputpath),
|
|
690
|
+
os.path.relpath(lagtimesfile, start=outputpath),
|
|
691
|
+
os.path.relpath(corrmaskfile, start=outputpath),
|
|
692
|
+
os.path.relpath(procmaskfile, start=outputpath),
|
|
693
|
+
os.path.relpath(runoptionsfile, start=outputpath),
|
|
694
|
+
os.path.relpath(lagtcgeneratorfile, start=outputpath),
|
|
695
|
+
]
|
|
696
|
+
|
|
697
|
+
bidsbasedict = {
|
|
698
|
+
"RawSources": rawsources,
|
|
699
|
+
"Units": "arbitrary",
|
|
700
|
+
"CommandLineArgs": thecommandline,
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
if args.debug:
|
|
704
|
+
# dump the fmri input file going to glm
|
|
705
|
+
theheader = theinputdata.copyheader(numtimepoints=validtimepoints, tr=fmritr)
|
|
706
|
+
|
|
707
|
+
maplist = [
|
|
708
|
+
(
|
|
709
|
+
fmri_data_valid,
|
|
710
|
+
"inputdata",
|
|
711
|
+
"bold",
|
|
712
|
+
None,
|
|
713
|
+
"fMRI data that will be subjected to sLFO filtering",
|
|
714
|
+
),
|
|
715
|
+
]
|
|
716
|
+
tide_io.savemaplist(
|
|
717
|
+
outputname,
|
|
718
|
+
maplist,
|
|
719
|
+
validvoxels,
|
|
720
|
+
(xsize, ysize, numslices, validtimepoints),
|
|
721
|
+
theheader,
|
|
722
|
+
bidsbasedict,
|
|
723
|
+
filetype=theinputdata.filetype,
|
|
724
|
+
rt_floattype=rt_floattype,
|
|
725
|
+
cifti_hdr=None,
|
|
726
|
+
)
|
|
727
|
+
|
|
728
|
+
# refine the delay value prior to calculating the GLM
|
|
729
|
+
if args.refinedelay:
|
|
730
|
+
print("\n\nDelay refinement")
|
|
731
|
+
TimingLGR.info("Delay refinement start")
|
|
732
|
+
LGR.info("\n\nDelay refinement")
|
|
733
|
+
|
|
734
|
+
if args.delayoffsetgausssigma < 0.0:
|
|
735
|
+
# set gausssigma automatically
|
|
736
|
+
args.delayoffsetgausssigma = np.mean([xdim, ydim, slicethickness]) / 2.0
|
|
737
|
+
|
|
738
|
+
(
|
|
739
|
+
delayoffset,
|
|
740
|
+
regressderivratios,
|
|
741
|
+
medfiltregressderivratios,
|
|
742
|
+
filteredregressderivratios,
|
|
743
|
+
delayoffsetMAD,
|
|
744
|
+
) = tide_refineDelayMap.refineDelay(
|
|
745
|
+
fmri_data_valid,
|
|
746
|
+
initial_fmri_x,
|
|
747
|
+
xdim,
|
|
748
|
+
ydim,
|
|
749
|
+
slicethickness,
|
|
750
|
+
sLFOfiltmask_valid,
|
|
751
|
+
genlagtc,
|
|
752
|
+
oversamptr,
|
|
753
|
+
sLFOfitmean,
|
|
754
|
+
rvalue,
|
|
755
|
+
r2value,
|
|
756
|
+
fitNorm,
|
|
757
|
+
fitcoeff,
|
|
758
|
+
lagtc,
|
|
759
|
+
outputname,
|
|
760
|
+
validvoxels,
|
|
761
|
+
theinputdata.nativespaceshape,
|
|
762
|
+
theinputdata,
|
|
763
|
+
lagtimes_valid,
|
|
764
|
+
therunoptions,
|
|
765
|
+
LGR,
|
|
766
|
+
TimingLGR,
|
|
767
|
+
outputlevel=args.outputlevel,
|
|
768
|
+
gausssigma=args.delayoffsetgausssigma,
|
|
769
|
+
patchthresh=args.delaypatchthresh,
|
|
770
|
+
mindelay=args.mindelay,
|
|
771
|
+
maxdelay=args.maxdelay,
|
|
772
|
+
numpoints=args.numpoints,
|
|
773
|
+
histlen=therunoptions["histlen"],
|
|
774
|
+
rt_floattype=rt_floattype,
|
|
775
|
+
debug=args.debug,
|
|
776
|
+
)
|
|
777
|
+
|
|
778
|
+
refinedvoxelstoreport = filteredregressderivratios.shape[0]
|
|
779
|
+
|
|
780
|
+
lagtimesrefined_valid = lagtimes_valid + delayoffset
|
|
781
|
+
|
|
782
|
+
TimingLGR.info(
|
|
783
|
+
"Delay offset calculation done",
|
|
784
|
+
{
|
|
785
|
+
"message2": refinedvoxelstoreport,
|
|
786
|
+
"message3": "voxels",
|
|
787
|
+
},
|
|
788
|
+
)
|
|
789
|
+
####################################################
|
|
790
|
+
# Delay refinement end
|
|
791
|
+
####################################################
|
|
792
|
+
|
|
793
|
+
initialvariance = tide_math.imagevariance(fmri_data_valid, theprefilter, 1.0 / fmritr)
|
|
794
|
+
|
|
795
|
+
print("calling regressfrommaps")
|
|
796
|
+
TimingLGR.info("Starting sLFO filtering")
|
|
797
|
+
if args.refinedelay and args.filterwithrefineddelay:
|
|
798
|
+
lagstouse_valid = lagtimesrefined_valid
|
|
799
|
+
else:
|
|
800
|
+
lagstouse_valid = lagtimes_valid
|
|
801
|
+
voxelsprocessed_regressionfilt, regressorset, evset = tide_regressfrommaps.regressfrommaps(
|
|
802
|
+
fmri_data_valid,
|
|
803
|
+
validvoxels,
|
|
804
|
+
initial_fmri_x,
|
|
805
|
+
lagstouse_valid,
|
|
806
|
+
sLFOfiltmask_valid,
|
|
807
|
+
genlagtc,
|
|
808
|
+
mode,
|
|
809
|
+
outputname,
|
|
810
|
+
oversamptr,
|
|
811
|
+
sLFOfitmean,
|
|
812
|
+
rvalue,
|
|
813
|
+
r2value,
|
|
814
|
+
fitNorm[:, : args.regressderivs + 1],
|
|
815
|
+
fitcoeff[:, : args.regressderivs + 1],
|
|
816
|
+
movingsignal,
|
|
817
|
+
lagtc,
|
|
818
|
+
filtereddata,
|
|
819
|
+
LGR,
|
|
820
|
+
TimingLGR,
|
|
821
|
+
threshval,
|
|
822
|
+
args.saveminimumsLFOfiltfiles,
|
|
823
|
+
nprocs_makelaggedtcs=args.nprocs,
|
|
824
|
+
nprocs_regressionfilt=args.nprocs,
|
|
825
|
+
regressderivs=args.regressderivs,
|
|
826
|
+
showprogressbar=args.showprogressbar,
|
|
827
|
+
saveEVsandquit=args.saveEVsandquit,
|
|
828
|
+
debug=args.debug,
|
|
829
|
+
)
|
|
830
|
+
|
|
831
|
+
if not args.saveEVsandquit:
|
|
832
|
+
print(f"filtered {voxelsprocessed_regressionfilt} voxels")
|
|
833
|
+
TimingLGR.info(
|
|
834
|
+
"sLFO filtering done",
|
|
835
|
+
{
|
|
836
|
+
"message2": voxelsprocessed_regressionfilt,
|
|
837
|
+
"message3": "voxels",
|
|
838
|
+
},
|
|
839
|
+
)
|
|
840
|
+
finalvariance = tide_math.imagevariance(filtereddata, theprefilter, 1.0 / fmritr)
|
|
841
|
+
|
|
842
|
+
divlocs = np.where(finalvariance > 0.0)
|
|
843
|
+
varchange = np.zeros_like(initialvariance)
|
|
844
|
+
varchange[divlocs] = 100.0 * (finalvariance[divlocs] / initialvariance[divlocs] - 1.0)
|
|
845
|
+
|
|
846
|
+
# calculate the voxelwise mean of the filtered data
|
|
847
|
+
lfofilteredmeanvalue = np.mean(
|
|
848
|
+
filtereddata,
|
|
849
|
+
axis=1,
|
|
850
|
+
)
|
|
851
|
+
|
|
852
|
+
# save regional timecourses if masks are defined
|
|
853
|
+
# read in the anatomic masks
|
|
854
|
+
anatomiclist = [
|
|
855
|
+
["brainmaskincludename", "brainmaskincludevals", "brainmask"],
|
|
856
|
+
["graymatterincludename", "graymatterincludevals", "graymattermask"],
|
|
857
|
+
["whitematterincludename", "whitematterincludevals", "whitemattermask"],
|
|
858
|
+
["csfincludename", "csfincludevals", "csfmask"],
|
|
859
|
+
]
|
|
860
|
+
anatomicmasks = []
|
|
861
|
+
for thisanatomic in anatomiclist:
|
|
862
|
+
try:
|
|
863
|
+
thename = therunoptions[thisanatomic[0]]
|
|
864
|
+
except KeyError:
|
|
865
|
+
therunoptions[thisanatomic[0]] = None
|
|
866
|
+
if therunoptions[thisanatomic[0]] is not None:
|
|
867
|
+
anatomicmasks.append(
|
|
868
|
+
tide_mask.readamask(
|
|
869
|
+
therunoptions[thisanatomic[0]],
|
|
870
|
+
theinputdata.nim_hdr,
|
|
871
|
+
xsize,
|
|
872
|
+
istext=(theinputdata.filetype == "text"),
|
|
873
|
+
valslist=therunoptions[thisanatomic[1]],
|
|
874
|
+
maskname=thisanatomic[2],
|
|
875
|
+
tolerance=therunoptions["spatialtolerance"],
|
|
876
|
+
debug=args.focaldebug,
|
|
877
|
+
)
|
|
878
|
+
)
|
|
879
|
+
anatomicmasks[-1] = np.uint16(np.where(anatomicmasks[-1] > 0.1, 1, 0))
|
|
880
|
+
else:
|
|
881
|
+
anatomicmasks.append(None)
|
|
882
|
+
brainmask = anatomicmasks[0]
|
|
883
|
+
graymask = anatomicmasks[1]
|
|
884
|
+
whitemask = anatomicmasks[2]
|
|
885
|
+
csfmask = anatomicmasks[3]
|
|
886
|
+
|
|
887
|
+
"""if internalinitregressorincludemask is not None:
|
|
888
|
+
thisincludemask = internalinitregressorincludemask[validvoxels]
|
|
889
|
+
else:
|
|
890
|
+
thisincludemask = None
|
|
891
|
+
if internalinitregressorexcludemask is not None:
|
|
892
|
+
thisexcludemask = internalinitregressorexcludemask[validvoxels]
|
|
893
|
+
else:
|
|
894
|
+
thisexcludemask = None
|
|
895
|
+
|
|
896
|
+
meanvec, meanmask = tide_mask.saveregionaltimeseries(
|
|
897
|
+
"initial regressor",
|
|
898
|
+
"startregressormask",
|
|
899
|
+
filtereddata,
|
|
900
|
+
thisincludemask,
|
|
901
|
+
1.0 / fmritr,
|
|
902
|
+
outputname,
|
|
903
|
+
initfile=True,
|
|
904
|
+
excludemask=thisexcludemask,
|
|
905
|
+
filedesc="regionalpostfilter",
|
|
906
|
+
suffix="",
|
|
907
|
+
debug=args.debug,
|
|
908
|
+
)"""
|
|
909
|
+
# reformat the anatomic masks, if they exist
|
|
910
|
+
if brainmask is None:
|
|
911
|
+
invbrainmask = None
|
|
912
|
+
|
|
913
|
+
internalbrainmask = None
|
|
914
|
+
internalinvbrainmask = None
|
|
915
|
+
else:
|
|
916
|
+
invbrainmask = 1 - brainmask
|
|
917
|
+
internalbrainmask = brainmask.reshape((numspatiallocs))
|
|
918
|
+
internalinvbrainmask = invbrainmask.reshape((numspatiallocs))
|
|
919
|
+
if graymask is None:
|
|
920
|
+
internalgraymask = None
|
|
921
|
+
else:
|
|
922
|
+
internalgraymask = graymask.reshape((numspatiallocs))
|
|
923
|
+
if whitemask is None:
|
|
924
|
+
internalwhitemask = None
|
|
925
|
+
else:
|
|
926
|
+
internalwhitemask = whitemask.reshape((numspatiallocs))
|
|
927
|
+
if csfmask is None:
|
|
928
|
+
internalcsfmask = None
|
|
929
|
+
else:
|
|
930
|
+
internalcsfmask = csfmask.reshape((numspatiallocs))
|
|
931
|
+
if brainmask is not None:
|
|
932
|
+
brainvec, dummy = tide_mask.saveregionaltimeseries(
|
|
933
|
+
"whole brain",
|
|
934
|
+
"brain",
|
|
935
|
+
filtereddata,
|
|
936
|
+
internalbrainmask[validvoxels],
|
|
937
|
+
1.0 / fmritr,
|
|
938
|
+
outputname,
|
|
939
|
+
filedesc="regionalpostfilter",
|
|
940
|
+
suffix="",
|
|
941
|
+
debug=args.debug,
|
|
942
|
+
)
|
|
943
|
+
if graymask is not None:
|
|
944
|
+
grayvec, dummy = tide_mask.saveregionaltimeseries(
|
|
945
|
+
"gray matter",
|
|
946
|
+
"GM",
|
|
947
|
+
filtereddata,
|
|
948
|
+
internalgraymask[validvoxels],
|
|
949
|
+
1.0 / fmritr,
|
|
950
|
+
outputname,
|
|
951
|
+
excludemask=internalinvbrainmask[validvoxels],
|
|
952
|
+
filedesc="regionalpostfilter",
|
|
953
|
+
suffix="",
|
|
954
|
+
debug=args.debug,
|
|
955
|
+
)
|
|
956
|
+
if whitemask is not None:
|
|
957
|
+
whitevec, dummy = tide_mask.saveregionaltimeseries(
|
|
958
|
+
"white matter",
|
|
959
|
+
"WM",
|
|
960
|
+
filtereddata,
|
|
961
|
+
internalwhitemask[validvoxels],
|
|
962
|
+
1.0 / fmritr,
|
|
963
|
+
outputname,
|
|
964
|
+
excludemask=internalinvbrainmask[validvoxels],
|
|
965
|
+
filedesc="regionalpostfilter",
|
|
966
|
+
suffix="",
|
|
967
|
+
debug=args.debug,
|
|
968
|
+
)
|
|
969
|
+
if csfmask is not None:
|
|
970
|
+
grayvec, dummy = tide_mask.saveregionaltimeseries(
|
|
971
|
+
"CSF",
|
|
972
|
+
"CSF",
|
|
973
|
+
filtereddata,
|
|
974
|
+
internalcsfmask[validvoxels],
|
|
975
|
+
1.0 / fmritr,
|
|
976
|
+
outputname,
|
|
977
|
+
excludemask=internalinvbrainmask[validvoxels],
|
|
978
|
+
filedesc="regionalpostfilter",
|
|
979
|
+
suffix="",
|
|
980
|
+
debug=args.debug,
|
|
981
|
+
)
|
|
982
|
+
|
|
983
|
+
# save outputs
|
|
984
|
+
TimingLGR.info("Starting output save")
|
|
985
|
+
theheader = copy.deepcopy(lagtimes_header)
|
|
986
|
+
if mode == "glm":
|
|
987
|
+
maplist = [
|
|
988
|
+
(
|
|
989
|
+
initialvariance,
|
|
990
|
+
"lfofilterInbandVarianceBefore",
|
|
991
|
+
"map",
|
|
992
|
+
None,
|
|
993
|
+
"Inband variance prior to filtering",
|
|
994
|
+
),
|
|
995
|
+
(
|
|
996
|
+
finalvariance,
|
|
997
|
+
"lfofilterInbandVarianceAfter",
|
|
998
|
+
"map",
|
|
999
|
+
None,
|
|
1000
|
+
"Inband variance after filtering",
|
|
1001
|
+
),
|
|
1002
|
+
(
|
|
1003
|
+
varchange,
|
|
1004
|
+
"lfofilterInbandVarianceChange",
|
|
1005
|
+
"map",
|
|
1006
|
+
"percent",
|
|
1007
|
+
"Change in inband variance after filtering, in percent",
|
|
1008
|
+
),
|
|
1009
|
+
# (
|
|
1010
|
+
# lfofilteredmeanvalue,
|
|
1011
|
+
# "lfofilterMean",
|
|
1012
|
+
# "map",
|
|
1013
|
+
# None,
|
|
1014
|
+
# "Voxelwise mean of the sLFO filtered data",
|
|
1015
|
+
# )
|
|
1016
|
+
# (
|
|
1017
|
+
# initialrawvariance,
|
|
1018
|
+
# "lfofilterTotalVarianceBefore",
|
|
1019
|
+
# "map",
|
|
1020
|
+
# None,
|
|
1021
|
+
# "Total variance prior to filtering",
|
|
1022
|
+
# ),
|
|
1023
|
+
# (
|
|
1024
|
+
# finalrawvariance,
|
|
1025
|
+
# "lfofilterTotalVarianceAfter",
|
|
1026
|
+
# "map",
|
|
1027
|
+
# None,
|
|
1028
|
+
# "Total variance after filtering",
|
|
1029
|
+
# ),
|
|
1030
|
+
# (
|
|
1031
|
+
# rawvarchange,
|
|
1032
|
+
# "lfofilterTotalVarianceChange",
|
|
1033
|
+
# "map",
|
|
1034
|
+
# "percent",
|
|
1035
|
+
# "Change in total variance after filtering, in percent",
|
|
1036
|
+
# ),
|
|
1037
|
+
]
|
|
1038
|
+
if args.saveminimumsLFOfiltfiles:
|
|
1039
|
+
maplist += [
|
|
1040
|
+
(
|
|
1041
|
+
r2value,
|
|
1042
|
+
"lfofilterR2",
|
|
1043
|
+
"map",
|
|
1044
|
+
None,
|
|
1045
|
+
"Squared R value of the GLM fit (proportion of variance explained)",
|
|
1046
|
+
),
|
|
1047
|
+
]
|
|
1048
|
+
if args.savenormalsLFOfiltfiles:
|
|
1049
|
+
maplist += [
|
|
1050
|
+
(rvalue, "lfofilterR", "map", None, "R value of the GLM fit"),
|
|
1051
|
+
(sLFOfitmean, "lfofilterMean", "map", None, "Intercept from GLM fit"),
|
|
1052
|
+
]
|
|
1053
|
+
else:
|
|
1054
|
+
maplist = [
|
|
1055
|
+
(initialvariance, "lfofilterInbandVarianceBefore", "map", None),
|
|
1056
|
+
(finalvariance, "lfofilterInbandVarianceAfter", "map", None),
|
|
1057
|
+
(varchange, "CVRVariance", "map", None),
|
|
1058
|
+
(rvalue, "CVRR", "map", None),
|
|
1059
|
+
(r2value, "CVRR2", "map", None),
|
|
1060
|
+
(fitcoeff[:, 0], "CVR", "map", "percent"),
|
|
1061
|
+
]
|
|
1062
|
+
bidsdict = bidsbasedict.copy()
|
|
1063
|
+
|
|
1064
|
+
if args.debug or args.focaldebug:
|
|
1065
|
+
maplist += [
|
|
1066
|
+
(
|
|
1067
|
+
lagtimes_valid,
|
|
1068
|
+
"maxtimeREAD",
|
|
1069
|
+
"map",
|
|
1070
|
+
"second",
|
|
1071
|
+
"Lag time in seconds used for calculation",
|
|
1072
|
+
),
|
|
1073
|
+
(
|
|
1074
|
+
corrmask_valid,
|
|
1075
|
+
"corrfitREAD",
|
|
1076
|
+
"mask",
|
|
1077
|
+
None,
|
|
1078
|
+
"Correlation mask read for calculation",
|
|
1079
|
+
),
|
|
1080
|
+
(
|
|
1081
|
+
sLFOfiltmask_valid,
|
|
1082
|
+
"corrfitUSED",
|
|
1083
|
+
"mask",
|
|
1084
|
+
None,
|
|
1085
|
+
"Correlation mask used for calculation",
|
|
1086
|
+
),
|
|
1087
|
+
(
|
|
1088
|
+
procmask_valid,
|
|
1089
|
+
"processedREAD",
|
|
1090
|
+
"mask",
|
|
1091
|
+
None,
|
|
1092
|
+
"Processed mask used for calculation",
|
|
1093
|
+
),
|
|
1094
|
+
]
|
|
1095
|
+
if args.savenormalsLFOfiltfiles:
|
|
1096
|
+
if args.regressderivs > 0 or args.refinedelay:
|
|
1097
|
+
maplist += [
|
|
1098
|
+
(fitcoeff[:, 0], "lfofilterCoeff", "map", None, "Fit coefficient"),
|
|
1099
|
+
(fitNorm[:, 0], "lfofilterNorm", "map", None, "Normalized fit coefficient"),
|
|
1100
|
+
]
|
|
1101
|
+
for thederiv in range(1, args.regressderivs + 1):
|
|
1102
|
+
maplist += [
|
|
1103
|
+
(
|
|
1104
|
+
fitcoeff[:, thederiv],
|
|
1105
|
+
f"lfofilterCoeffDeriv{thederiv}",
|
|
1106
|
+
"map",
|
|
1107
|
+
None,
|
|
1108
|
+
f"Fit coefficient for temporal derivative {thederiv}",
|
|
1109
|
+
),
|
|
1110
|
+
(
|
|
1111
|
+
fitNorm[:, thederiv],
|
|
1112
|
+
f"lfofilterNormDeriv{thederiv}",
|
|
1113
|
+
"map",
|
|
1114
|
+
None,
|
|
1115
|
+
f"Normalized fit coefficient for temporal derivative {thederiv}",
|
|
1116
|
+
),
|
|
1117
|
+
]
|
|
1118
|
+
else:
|
|
1119
|
+
maplist += [
|
|
1120
|
+
(fitcoeff, "lfofilterCoeff", "map", None, "Fit coefficient"),
|
|
1121
|
+
(fitNorm, "lfofilterNorm", "map", None, "Normalized fit coefficient"),
|
|
1122
|
+
]
|
|
1123
|
+
|
|
1124
|
+
if args.refinedelay:
|
|
1125
|
+
maplist += [
|
|
1126
|
+
(
|
|
1127
|
+
regressderivratios,
|
|
1128
|
+
"regressderivratios",
|
|
1129
|
+
"map",
|
|
1130
|
+
None,
|
|
1131
|
+
"Ratio of the first derivative of delayed sLFO to the delayed sLFO",
|
|
1132
|
+
),
|
|
1133
|
+
(
|
|
1134
|
+
medfiltregressderivratios,
|
|
1135
|
+
"medfiltregressderivratios",
|
|
1136
|
+
"map",
|
|
1137
|
+
None,
|
|
1138
|
+
"Median filtered version of the regressderivratios map",
|
|
1139
|
+
),
|
|
1140
|
+
(
|
|
1141
|
+
filteredregressderivratios,
|
|
1142
|
+
"filteredregressderivratios",
|
|
1143
|
+
"map",
|
|
1144
|
+
None,
|
|
1145
|
+
"regressderivratios, with outliers patched using median filtered data",
|
|
1146
|
+
),
|
|
1147
|
+
(
|
|
1148
|
+
delayoffset,
|
|
1149
|
+
"delayoffset",
|
|
1150
|
+
"map",
|
|
1151
|
+
"second",
|
|
1152
|
+
"Delay offset correction from delay refinement",
|
|
1153
|
+
),
|
|
1154
|
+
(
|
|
1155
|
+
lagtimesrefined_valid,
|
|
1156
|
+
"maxtimerefined",
|
|
1157
|
+
"map",
|
|
1158
|
+
"second",
|
|
1159
|
+
"Lag time in seconds, refined",
|
|
1160
|
+
),
|
|
1161
|
+
]
|
|
1162
|
+
|
|
1163
|
+
# write the 3D maps
|
|
1164
|
+
tide_io.savemaplist(
|
|
1165
|
+
outputname,
|
|
1166
|
+
maplist,
|
|
1167
|
+
validvoxels,
|
|
1168
|
+
(xsize, ysize, numslices),
|
|
1169
|
+
theheader,
|
|
1170
|
+
bidsdict,
|
|
1171
|
+
debug=args.debug,
|
|
1172
|
+
)
|
|
1173
|
+
|
|
1174
|
+
# write the 4D maps
|
|
1175
|
+
theheader = theinputdata.copyheader()
|
|
1176
|
+
maplist = []
|
|
1177
|
+
if args.saveminimumsLFOfiltfiles:
|
|
1178
|
+
maplist = [
|
|
1179
|
+
(
|
|
1180
|
+
filtereddata,
|
|
1181
|
+
"lfofilterCleaned",
|
|
1182
|
+
"bold",
|
|
1183
|
+
None,
|
|
1184
|
+
"fMRI data with sLFO signal filtered out",
|
|
1185
|
+
),
|
|
1186
|
+
]
|
|
1187
|
+
if args.savemovingsignal:
|
|
1188
|
+
maplist += [
|
|
1189
|
+
(
|
|
1190
|
+
movingsignal,
|
|
1191
|
+
"lfofilterRemoved",
|
|
1192
|
+
"bold",
|
|
1193
|
+
None,
|
|
1194
|
+
"sLFO signal filtered out of this voxel",
|
|
1195
|
+
)
|
|
1196
|
+
]
|
|
1197
|
+
|
|
1198
|
+
if args.saveallsLFOfiltfiles:
|
|
1199
|
+
if args.regressderivs > 0:
|
|
1200
|
+
if args.debug:
|
|
1201
|
+
print("going down the multiple EV path")
|
|
1202
|
+
print(f"{regressorset[:, :, 0].shape=}")
|
|
1203
|
+
maplist += [
|
|
1204
|
+
(
|
|
1205
|
+
regressorset[:, :, 0],
|
|
1206
|
+
"lfofilterEV",
|
|
1207
|
+
"bold",
|
|
1208
|
+
None,
|
|
1209
|
+
"Shifted sLFO regressor to filter",
|
|
1210
|
+
),
|
|
1211
|
+
]
|
|
1212
|
+
for thederiv in range(1, args.regressderivs + 1):
|
|
1213
|
+
if args.debug:
|
|
1214
|
+
print(f"{regressorset[:, :, thederiv].shape=}")
|
|
1215
|
+
maplist += [
|
|
1216
|
+
(
|
|
1217
|
+
regressorset[:, :, thederiv],
|
|
1218
|
+
f"lfofilterEVDeriv{thederiv}",
|
|
1219
|
+
"bold",
|
|
1220
|
+
None,
|
|
1221
|
+
f"Time derivative {thederiv} of shifted sLFO regressor",
|
|
1222
|
+
),
|
|
1223
|
+
]
|
|
1224
|
+
else:
|
|
1225
|
+
if args.debug:
|
|
1226
|
+
print("going down the single EV path")
|
|
1227
|
+
maplist += [
|
|
1228
|
+
(
|
|
1229
|
+
regressorset,
|
|
1230
|
+
"lfofilterEV",
|
|
1231
|
+
"bold",
|
|
1232
|
+
None,
|
|
1233
|
+
"Shifted sLFO regressor to filter",
|
|
1234
|
+
),
|
|
1235
|
+
]
|
|
1236
|
+
if args.makepseudofile:
|
|
1237
|
+
print("reading mean image")
|
|
1238
|
+
meanfile = f"{args.datafileroot}_desc-mean_map.nii.gz"
|
|
1239
|
+
(
|
|
1240
|
+
mean_input,
|
|
1241
|
+
mean,
|
|
1242
|
+
mean_header,
|
|
1243
|
+
mean_dims,
|
|
1244
|
+
mean_sizes,
|
|
1245
|
+
) = tide_io.readfromnifti(meanfile)
|
|
1246
|
+
if not tide_io.checkspacematch(fmri_header, mean_header):
|
|
1247
|
+
raise ValueError("mean dimensions do not match fmri dimensions")
|
|
1248
|
+
if args.debug:
|
|
1249
|
+
print(f"{mean.shape=}")
|
|
1250
|
+
mean_spacebytime = mean.reshape((numspatiallocs))
|
|
1251
|
+
if args.debug:
|
|
1252
|
+
print(f"{mean_spacebytime.shape=}")
|
|
1253
|
+
pseudofile = mean_spacebytime[validvoxels, None] + movingsignal[:, :]
|
|
1254
|
+
maplist.append((pseudofile, "pseudofile", "bold", None, None))
|
|
1255
|
+
tide_io.savemaplist(
|
|
1256
|
+
outputname,
|
|
1257
|
+
maplist,
|
|
1258
|
+
validvoxels,
|
|
1259
|
+
(xsize, ysize, numslices, validtimepoints),
|
|
1260
|
+
theheader,
|
|
1261
|
+
bidsdict,
|
|
1262
|
+
debug=args.debug,
|
|
1263
|
+
)
|
|
1264
|
+
TimingLGR.info("Finishing output save")
|
|
1265
|
+
|
|
1266
|
+
if args.refinecorr:
|
|
1267
|
+
TimingLGR.info("Filtering for maxcorrrefined calculation start")
|
|
1268
|
+
for thevoxel in range(fmri_data_valid.shape[0]):
|
|
1269
|
+
fmri_data_valid[thevoxel, :] = theprefilter.apply(
|
|
1270
|
+
1.0 / fmritr, fmri_data_valid[thevoxel, :]
|
|
1271
|
+
)
|
|
1272
|
+
TimingLGR.info("Filtering for maxcorrrefined calculation complete")
|
|
1273
|
+
TimingLGR.info("GLM for maxcorrrefined calculation start")
|
|
1274
|
+
voxelsprocessed_regressionfilt, regressorset, evset = (
|
|
1275
|
+
tide_regressfrommaps.regressfrommaps(
|
|
1276
|
+
fmri_data_valid,
|
|
1277
|
+
validvoxels,
|
|
1278
|
+
initial_fmri_x,
|
|
1279
|
+
lagstouse_valid,
|
|
1280
|
+
sLFOfiltmask_valid,
|
|
1281
|
+
genlagtc,
|
|
1282
|
+
mode,
|
|
1283
|
+
outputname,
|
|
1284
|
+
oversamptr,
|
|
1285
|
+
sLFOfitmean,
|
|
1286
|
+
rvalue,
|
|
1287
|
+
r2value,
|
|
1288
|
+
fitNorm[:, : args.regressderivs + 1],
|
|
1289
|
+
fitcoeff[:, : args.regressderivs + 1],
|
|
1290
|
+
movingsignal,
|
|
1291
|
+
lagtc,
|
|
1292
|
+
filtereddata,
|
|
1293
|
+
LGR,
|
|
1294
|
+
TimingLGR,
|
|
1295
|
+
threshval,
|
|
1296
|
+
args.saveminimumsLFOfiltfiles,
|
|
1297
|
+
nprocs_makelaggedtcs=args.nprocs,
|
|
1298
|
+
nprocs_regressionfilt=args.nprocs,
|
|
1299
|
+
regressderivs=args.regressderivs,
|
|
1300
|
+
showprogressbar=args.showprogressbar,
|
|
1301
|
+
debug=args.debug,
|
|
1302
|
+
)
|
|
1303
|
+
)
|
|
1304
|
+
TimingLGR.info(
|
|
1305
|
+
"GLM for maxcorrrefined calculation done",
|
|
1306
|
+
{
|
|
1307
|
+
"message2": voxelsprocessed_regressionfilt,
|
|
1308
|
+
"message3": "voxels",
|
|
1309
|
+
},
|
|
1310
|
+
)
|
|
1311
|
+
|
|
1312
|
+
maplist = [
|
|
1313
|
+
(
|
|
1314
|
+
rvalue,
|
|
1315
|
+
"maxcorrrefined",
|
|
1316
|
+
"map",
|
|
1317
|
+
None,
|
|
1318
|
+
"R value for the lfo component of the delayed regressor, with sign",
|
|
1319
|
+
),
|
|
1320
|
+
]
|
|
1321
|
+
theheader = copy.deepcopy(lagtimes_header)
|
|
1322
|
+
tide_io.savemaplist(
|
|
1323
|
+
outputname,
|
|
1324
|
+
maplist,
|
|
1325
|
+
validvoxels,
|
|
1326
|
+
(xsize, ysize, numslices),
|
|
1327
|
+
theheader,
|
|
1328
|
+
bidsdict,
|
|
1329
|
+
debug=args.debug,
|
|
1330
|
+
)
|
|
1331
|
+
if args.debug:
|
|
1332
|
+
# dump the fmri input file going to glm
|
|
1333
|
+
theheader = theinputdata.copyheader(numtimepoints=validtimepoints, tr=fmritr)
|
|
1334
|
+
|
|
1335
|
+
maplist = [
|
|
1336
|
+
(
|
|
1337
|
+
fmri_data_valid,
|
|
1338
|
+
"prefilteredinputdata",
|
|
1339
|
+
"bold",
|
|
1340
|
+
None,
|
|
1341
|
+
"fMRI data after temporal filtering",
|
|
1342
|
+
),
|
|
1343
|
+
]
|
|
1344
|
+
tide_io.savemaplist(
|
|
1345
|
+
outputname,
|
|
1346
|
+
maplist,
|
|
1347
|
+
validvoxels,
|
|
1348
|
+
(xsize, ysize, numslices, validtimepoints),
|
|
1349
|
+
theheader,
|
|
1350
|
+
bidsbasedict,
|
|
1351
|
+
filetype=theinputdata.filetype,
|
|
1352
|
+
rt_floattype=rt_floattype,
|
|
1353
|
+
cifti_hdr=None,
|
|
1354
|
+
)
|
|
1355
|
+
else:
|
|
1356
|
+
# We are terminating early because we only want the regressors
|
|
1357
|
+
# write the EVs
|
|
1358
|
+
theheader = theinputdata.copyheader()
|
|
1359
|
+
maplist = []
|
|
1360
|
+
if args.regressderivs > 0:
|
|
1361
|
+
if args.debug:
|
|
1362
|
+
print("going down the multiple EV path")
|
|
1363
|
+
print(f"{regressorset[:, :, 0].shape=}")
|
|
1364
|
+
maplist += [
|
|
1365
|
+
(
|
|
1366
|
+
regressorset[:, :, 0],
|
|
1367
|
+
"lfofilterEV",
|
|
1368
|
+
"bold",
|
|
1369
|
+
None,
|
|
1370
|
+
"Shifted sLFO regressor to filter",
|
|
1371
|
+
),
|
|
1372
|
+
]
|
|
1373
|
+
for thederiv in range(1, args.regressderivs + 1):
|
|
1374
|
+
if args.debug:
|
|
1375
|
+
print(f"{regressorset[:, :, thederiv].shape=}")
|
|
1376
|
+
maplist += [
|
|
1377
|
+
(
|
|
1378
|
+
regressorset[:, :, thederiv],
|
|
1379
|
+
f"lfofilterEVDeriv{thederiv}",
|
|
1380
|
+
"bold",
|
|
1381
|
+
None,
|
|
1382
|
+
f"Time derivative {thederiv} of shifted sLFO regressor",
|
|
1383
|
+
),
|
|
1384
|
+
]
|
|
1385
|
+
else:
|
|
1386
|
+
if args.debug:
|
|
1387
|
+
print("going down the single EV path")
|
|
1388
|
+
maplist += [
|
|
1389
|
+
(
|
|
1390
|
+
regressorset,
|
|
1391
|
+
"lfofilterEV",
|
|
1392
|
+
"bold",
|
|
1393
|
+
None,
|
|
1394
|
+
"Shifted sLFO regressor to filter",
|
|
1395
|
+
),
|
|
1396
|
+
]
|
|
1397
|
+
bidsdict = bidsbasedict.copy()
|
|
1398
|
+
tide_io.savemaplist(
|
|
1399
|
+
outputname,
|
|
1400
|
+
maplist,
|
|
1401
|
+
validvoxels,
|
|
1402
|
+
(xsize, ysize, numslices, validtimepoints),
|
|
1403
|
+
theheader,
|
|
1404
|
+
bidsdict,
|
|
1405
|
+
debug=args.debug,
|
|
1406
|
+
)
|
|
1407
|
+
|
|
1408
|
+
# write the runoptions file
|
|
1409
|
+
print("writing runoptions")
|
|
1410
|
+
if args.refinedelay:
|
|
1411
|
+
therunoptions["retroregress_delayoffsetMAD"] = delayoffsetMAD
|
|
1412
|
+
therunoptions["retroregress_runtime"] = time.strftime(
|
|
1413
|
+
"%a, %d %b %Y %H:%M:%S %Z", time.localtime(time.time())
|
|
1414
|
+
)
|
|
1415
|
+
(
|
|
1416
|
+
therunoptions["retroregress_release_version"],
|
|
1417
|
+
therunoptions["retroregress_git_sha"],
|
|
1418
|
+
therunoptions["retroregress_git_date"],
|
|
1419
|
+
therunoptions["retroregress_git_isdirty"],
|
|
1420
|
+
) = tide_util.version()
|
|
1421
|
+
therunoptions["retroregress_python_version"] = str(sys.version_info)
|
|
1422
|
+
therunoptions["retroregress_nodename"] = platform.node()
|
|
1423
|
+
|
|
1424
|
+
# clean up shared memory
|
|
1425
|
+
if usesharedmem:
|
|
1426
|
+
TimingLGR.info("Shared memory cleanup start")
|
|
1427
|
+
tide_util.cleanup_shm(sLFOfitmean_shm)
|
|
1428
|
+
tide_util.cleanup_shm(rvalue_shm)
|
|
1429
|
+
tide_util.cleanup_shm(r2value_shm)
|
|
1430
|
+
tide_util.cleanup_shm(fitNorm_shm)
|
|
1431
|
+
tide_util.cleanup_shm(fitcoeff_shm)
|
|
1432
|
+
tide_util.cleanup_shm(movingsignal_shm)
|
|
1433
|
+
tide_util.cleanup_shm(lagtc_shm)
|
|
1434
|
+
tide_util.cleanup_shm(filtereddata_shm)
|
|
1435
|
+
TimingLGR.info("Shared memory cleanup complete")
|
|
1436
|
+
|
|
1437
|
+
# shut down logging
|
|
1438
|
+
TimingLGR.info("Done")
|
|
1439
|
+
logging.shutdown()
|
|
1440
|
+
|
|
1441
|
+
# reformat timing information and delete the unformatted version
|
|
1442
|
+
timingdata, therunoptions["totalretroruntime"] = tide_util.proctiminglogfile(
|
|
1443
|
+
f"{outputname}_retroruntimings.tsv"
|
|
1444
|
+
)
|
|
1445
|
+
tide_io.writevec(
|
|
1446
|
+
np.asarray(timingdata),
|
|
1447
|
+
f"{outputname}_desc-formattedretroruntimings_info.tsv",
|
|
1448
|
+
)
|
|
1449
|
+
Path(f"{outputname}_retroruntimings.tsv").unlink(missing_ok=True)
|
|
1450
|
+
|
|
1451
|
+
# save the modified runoptions file
|
|
1452
|
+
tide_io.writedicttojson(therunoptions, f"{outputname}_desc-runoptions_info.json")
|
|
1453
|
+
|
|
1454
|
+
# shut down the loggers
|
|
1455
|
+
for thelogger in [LGR, ErrorLGR, TimingLGR]:
|
|
1456
|
+
handlers = thelogger.handlers[:]
|
|
1457
|
+
for handler in handlers:
|
|
1458
|
+
thelogger.removeHandler(handler)
|
|
1459
|
+
handler.close()
|
|
1460
|
+
|
|
1461
|
+
# delete the canary file
|
|
1462
|
+
Path(f"{outputname}_RETROISRUNNING.txt").unlink()
|
|
1463
|
+
|
|
1464
|
+
# create the finished file
|
|
1465
|
+
Path(f"{outputname}_RETRODONE.txt").touch()
|
|
1466
|
+
|
|
1467
|
+
|
|
1468
|
+
def process_args(inputargs: Optional[Any] = None) -> argparse.Namespace:
|
|
1469
|
+
"""
|
|
1470
|
+
Compile arguments for retroregress workflow.
|
|
1471
|
+
|
|
1472
|
+
This function processes input arguments for the retroregress workflow by parsing
|
|
1473
|
+
command line arguments or provided input arguments using a predefined parser.
|
|
1474
|
+
|
|
1475
|
+
Parameters
|
|
1476
|
+
----------
|
|
1477
|
+
inputargs : Any, optional
|
|
1478
|
+
Input arguments to be processed. Can be None (default), a list of strings,
|
|
1479
|
+
or other argument formats supported by the underlying parser. Default is None.
|
|
1480
|
+
|
|
1481
|
+
Returns
|
|
1482
|
+
-------
|
|
1483
|
+
argparse.Namespace
|
|
1484
|
+
Parsed arguments namespace containing all processed arguments for the workflow.
|
|
1485
|
+
|
|
1486
|
+
Notes
|
|
1487
|
+
-----
|
|
1488
|
+
The function relies on `pf.setargs` and `_get_parser` which should be defined
|
|
1489
|
+
in the module's scope. The returned arguments can be used directly in the
|
|
1490
|
+
retroregress workflow pipeline.
|
|
1491
|
+
|
|
1492
|
+
Examples
|
|
1493
|
+
--------
|
|
1494
|
+
>>> # Using default arguments
|
|
1495
|
+
>>> args = process_args()
|
|
1496
|
+
|
|
1497
|
+
>>> # Using custom input arguments
|
|
1498
|
+
>>> args = process_args(['--input', 'data.csv', '--output', 'results.txt'])
|
|
1499
|
+
"""
|
|
1500
|
+
args, argstowrite = pf.setargs(_get_parser, inputargs=inputargs)
|
|
1501
|
+
return args
|