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
rapidtide/resample.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
#
|
|
4
|
-
# Copyright 2016-
|
|
4
|
+
# Copyright 2016-2025 Blaise Frederick
|
|
5
5
|
#
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
# you may not use this file except in compliance with the License.
|
|
@@ -31,14 +31,18 @@ with warnings.catch_warnings():
|
|
|
31
31
|
else:
|
|
32
32
|
pyfftwpresent = True
|
|
33
33
|
|
|
34
|
-
import
|
|
34
|
+
from typing import Any, Callable, Optional, Tuple, Union
|
|
35
|
+
|
|
36
|
+
import matplotlib.pyplot as plt
|
|
35
37
|
import scipy as sp
|
|
38
|
+
from numpy.typing import ArrayLike, NDArray
|
|
36
39
|
from scipy import fftpack, signal
|
|
37
40
|
|
|
38
41
|
import rapidtide.filter as tide_filt
|
|
39
42
|
import rapidtide.fit as tide_fit
|
|
40
43
|
import rapidtide.io as tide_io
|
|
41
44
|
import rapidtide.util as tide_util
|
|
45
|
+
from rapidtide.decorators import conditionaljit, conditionaljit2
|
|
42
46
|
|
|
43
47
|
if pyfftwpresent:
|
|
44
48
|
fftpack = pyfftw.interfaces.scipy_fftpack
|
|
@@ -50,124 +54,86 @@ import warnings
|
|
|
50
54
|
|
|
51
55
|
warnings.simplefilter(action="ignore", category=RuntimeWarning)
|
|
52
56
|
|
|
53
|
-
# ---------------------------------------- Global constants -------------------------------------------
|
|
54
|
-
donotbeaggressive = True
|
|
55
|
-
|
|
56
|
-
# ----------------------------------------- Conditional imports ---------------------------------------
|
|
57
|
-
try:
|
|
58
|
-
from numba import jit
|
|
59
|
-
except ImportError:
|
|
60
|
-
donotusenumba = True
|
|
61
|
-
else:
|
|
62
|
-
donotusenumba = False
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def conditionaljit():
|
|
66
|
-
def resdec(f):
|
|
67
|
-
if donotusenumba:
|
|
68
|
-
return f
|
|
69
|
-
return jit(f, nopython=True)
|
|
70
|
-
|
|
71
|
-
return resdec
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def conditionaljit2():
|
|
75
|
-
def resdec(f):
|
|
76
|
-
if donotusenumba or donotbeaggressive:
|
|
77
|
-
return f
|
|
78
|
-
return jit(f, nopython=True)
|
|
79
|
-
|
|
80
|
-
return resdec
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def disablenumba():
|
|
84
|
-
global donotusenumba
|
|
85
|
-
donotusenumba = True
|
|
86
|
-
|
|
87
|
-
|
|
88
57
|
# --------------------------- Resampling and time shifting functions -------------------------------------------
|
|
89
|
-
|
|
90
|
-
class ConvolutionGridder:
|
|
91
|
-
def __init__(self, timeaxis, width, method='gauss', circular=True, upsampleratio=100, doplot=False, debug=False):
|
|
92
|
-
self.upsampleratio = upsampleratio
|
|
93
|
-
self.initstep = timeaxis[1] - timeaxis[0]
|
|
94
|
-
self.initstart = timeaxis[0]
|
|
95
|
-
self.initend = timeaxis[-1]
|
|
96
|
-
self.hiresstep = self.initstep / np.float64(self.upsampleratio)
|
|
97
|
-
if method == 'gauss':
|
|
98
|
-
fullwidth = 2.355 * width
|
|
99
|
-
fullwidthpts = int(np.round(fullwidth / self.hiresstep, 0))
|
|
100
|
-
fullwidthpts += ((fullwidthpts % 2) - 1)
|
|
101
|
-
self.hires_x = np.linspace(-fullwidth / 2.0, fullwidth / 2.0, numpts = fullwidthpts, endpoint=True)
|
|
102
|
-
if method == 'gauss':
|
|
103
|
-
self.hires_y = tide_fit.gauss_eval(self.hires_x, np.array([1.0, 0.0, width])
|
|
104
|
-
if debug:
|
|
105
|
-
print(self.hires_x)
|
|
106
|
-
if doplot:
|
|
107
|
-
fig = pl.figure()
|
|
108
|
-
ax = fig.add_subplot(111)
|
|
109
|
-
ax.set_title('congrid convolution function')
|
|
110
|
-
pl.plot(self.hires_x, self.hires_y)
|
|
111
|
-
pl.legend(('input', 'hires'))
|
|
112
|
-
pl.show()
|
|
113
|
-
|
|
114
|
-
def gridded(xvals, yvals):
|
|
115
|
-
if len(xvals) != len(yvals):
|
|
116
|
-
print('x and y vectors do not match - aborting')
|
|
117
|
-
return None
|
|
118
|
-
for i in range(len(xvals)):
|
|
119
|
-
outindices = ((newtimeaxis - self.hiresstart) // self.hiresstep).astype(int)
|
|
120
|
-
"""
|
|
121
|
-
|
|
122
|
-
congridyvals = {}
|
|
58
|
+
congridyvals: dict = {}
|
|
123
59
|
congridyvals["kernel"] = "kaiser"
|
|
124
60
|
congridyvals["width"] = 3.0
|
|
125
61
|
|
|
126
62
|
|
|
127
|
-
def congrid(
|
|
63
|
+
def congrid(
|
|
64
|
+
xaxis: NDArray[np.floating[Any]],
|
|
65
|
+
loc: float,
|
|
66
|
+
val: float,
|
|
67
|
+
width: float,
|
|
68
|
+
kernel: str = "kaiser",
|
|
69
|
+
cache: bool = True,
|
|
70
|
+
cyclic: bool = True,
|
|
71
|
+
debug: bool = False,
|
|
72
|
+
onlykeynotices: bool = True,
|
|
73
|
+
) -> Tuple[NDArray[np.floating[Any]], NDArray[np.floating[Any]], NDArray[np.floating[Any]]]:
|
|
128
74
|
"""
|
|
129
|
-
Perform a convolution gridding operation with a Kaiser-Bessel or Gaussian kernel
|
|
130
|
-
|
|
75
|
+
Perform a convolution gridding operation with a Kaiser-Bessel or Gaussian kernel.
|
|
76
|
+
|
|
77
|
+
This function convolves a given value with a specified gridding kernel and projects
|
|
78
|
+
the result onto a target axis. It supports both cyclic and non-cyclic boundary
|
|
79
|
+
conditions and caches kernel values for performance optimization.
|
|
131
80
|
|
|
132
81
|
Parameters
|
|
133
82
|
----------
|
|
134
|
-
xaxis:
|
|
135
|
-
The target axis for resampling
|
|
136
|
-
loc: float
|
|
137
|
-
The location, in x-axis units, of the sample to be gridded
|
|
138
|
-
val: float
|
|
139
|
-
The value to be gridded
|
|
140
|
-
width: float
|
|
141
|
-
The width of the gridding kernel in target bins
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
83
|
+
xaxis : NDArray[np.floating[Any]]
|
|
84
|
+
The target axis for resampling. Should be a 1D array of evenly spaced points.
|
|
85
|
+
loc : float
|
|
86
|
+
The location, in x-axis units, of the sample to be gridded.
|
|
87
|
+
val : float
|
|
88
|
+
The value to be gridded.
|
|
89
|
+
width : float
|
|
90
|
+
The width of the gridding kernel in target bins. Must be a half-integral value
|
|
91
|
+
between 1.5 and 5.0 inclusive.
|
|
92
|
+
kernel : {'old', 'gauss', 'kaiser'}, optional
|
|
93
|
+
The type of convolution gridding kernel. Default is 'kaiser'.
|
|
94
|
+
- 'old': Uses a Gaussian kernel with fixed width.
|
|
95
|
+
- 'gauss': Uses a Gaussian kernel with optimized sigma.
|
|
96
|
+
- 'kaiser': Uses a Kaiser-Bessel kernel with optimized beta.
|
|
97
|
+
cache : bool, optional
|
|
98
|
+
If True, caches kernel values for performance. Default is True.
|
|
99
|
+
cyclic : bool, optional
|
|
100
|
+
When True, gridding wraps around the endpoints of xaxis. Default is True.
|
|
101
|
+
debug : bool, optional
|
|
102
|
+
When True, outputs additional information about the gridding process.
|
|
103
|
+
Default is False.
|
|
104
|
+
onlykeynotices : bool, optional
|
|
105
|
+
When True, suppresses certain debug messages. Default is True.
|
|
148
106
|
|
|
149
107
|
Returns
|
|
150
108
|
-------
|
|
151
|
-
vals:
|
|
152
|
-
The input value, convolved with the gridding kernel, projected
|
|
153
|
-
weights:
|
|
154
|
-
The values of convolution kernel, projected
|
|
155
|
-
indices:
|
|
156
|
-
The indices along the x
|
|
109
|
+
vals : NDArray[np.floating[Any]]
|
|
110
|
+
The input value, convolved with the gridding kernel, projected onto x-axis points.
|
|
111
|
+
weights : NDArray[np.floating[Any]]
|
|
112
|
+
The values of the convolution kernel, projected onto x-axis points (used for normalization).
|
|
113
|
+
indices : NDArray[int[Any]]
|
|
114
|
+
The indices along the x-axis where the vals and weights fall.
|
|
157
115
|
|
|
158
116
|
Notes
|
|
159
117
|
-----
|
|
160
|
-
|
|
161
|
-
|
|
118
|
+
This implementation is based on the method described in:
|
|
119
|
+
IEEE TRANSACTIONS ON MEDICAL IMAGING. VOL. 10, NO. 3, SEPTEMBER 1991
|
|
120
|
+
|
|
121
|
+
Examples
|
|
122
|
+
--------
|
|
123
|
+
>>> import numpy as np
|
|
124
|
+
>>> xaxis = np.linspace(0, 10, 100)
|
|
125
|
+
>>> vals, weights, indices = congrid(xaxis, 5.5, 1.0, 2.0)
|
|
126
|
+
>>> print(vals.shape)
|
|
127
|
+
(100,)
|
|
162
128
|
"""
|
|
163
129
|
global congridyvals
|
|
164
130
|
|
|
165
131
|
if (congridyvals["kernel"] != kernel) or (congridyvals["width"] != width):
|
|
166
132
|
if congridyvals["kernel"] != kernel:
|
|
167
|
-
if debug:
|
|
133
|
+
if debug and not onlykeynotices:
|
|
168
134
|
print(congridyvals["kernel"], "!=", kernel)
|
|
169
135
|
if congridyvals["width"] != width:
|
|
170
|
-
if debug:
|
|
136
|
+
if debug and not onlykeynotices:
|
|
171
137
|
print(congridyvals["width"], "!=", width)
|
|
172
138
|
if debug:
|
|
173
139
|
print("(re)initializing congridyvals")
|
|
@@ -191,7 +157,7 @@ def congrid(xaxis, loc, val, width, kernel="kaiser", cyclic=True, debug=False):
|
|
|
191
157
|
|
|
192
158
|
# find the closest grid point to the target location, calculate relative offsets from this point
|
|
193
159
|
center = tide_util.valtoindex(xaxis, loc)
|
|
194
|
-
offset = np.fmod(np.round((loc - xaxis[center]) / xstep,
|
|
160
|
+
offset = np.fmod(np.round((loc - xaxis[center]) / xstep, 4), 1.0) # will vary from -0.5 to 0.5
|
|
195
161
|
if cyclic:
|
|
196
162
|
if center == len(xaxis) - 1 and offset > 0.5:
|
|
197
163
|
center = 0
|
|
@@ -224,19 +190,20 @@ def congrid(xaxis, loc, val, width, kernel="kaiser", cyclic=True, debug=False):
|
|
|
224
190
|
)
|
|
225
191
|
+ offset
|
|
226
192
|
)
|
|
227
|
-
|
|
228
|
-
|
|
193
|
+
yvals = tide_fit.gauss_eval(xvals, np.array([1.0, 0.0, width]))
|
|
194
|
+
if cache:
|
|
195
|
+
congridyvals[offsetkey] = 1.0 * yvals
|
|
229
196
|
startpt = int(center - widthinpts // 2)
|
|
230
197
|
indices = range(startpt, startpt + widthinpts)
|
|
231
198
|
indices = np.remainder(indices, len(xaxis))
|
|
232
|
-
if debug:
|
|
199
|
+
if debug and not onlykeynotices:
|
|
233
200
|
print("center, offset, indices, yvals", center, offset, indices, yvals)
|
|
234
201
|
return val * yvals, yvals, indices
|
|
235
202
|
else:
|
|
236
203
|
offsetinpts = center + offset
|
|
237
204
|
startpt = int(np.ceil(offsetinpts - width / 2.0))
|
|
238
205
|
endpt = int(np.floor(offsetinpts + width / 2.0))
|
|
239
|
-
indices = np.remainder(range(startpt, endpt + 1), len(xaxis))
|
|
206
|
+
indices = np.remainder(np.array(list(range(startpt, endpt + 1))), len(xaxis))
|
|
240
207
|
try:
|
|
241
208
|
yvals = congridyvals[offsetkey]
|
|
242
209
|
except KeyError:
|
|
@@ -245,19 +212,18 @@ def congrid(xaxis, loc, val, width, kernel="kaiser", cyclic=True, debug=False):
|
|
|
245
212
|
xvals = indices - center + offset
|
|
246
213
|
if kernel == "gauss":
|
|
247
214
|
sigma = optsigma[kernelindex]
|
|
248
|
-
|
|
215
|
+
yvals = tide_fit.gauss_eval(xvals, np.array([1.0, 0.0, sigma]))
|
|
249
216
|
elif kernel == "kaiser":
|
|
250
217
|
beta = optbeta[kernelindex]
|
|
251
|
-
|
|
252
|
-
xvals, np.array([beta, width / 2.0])
|
|
253
|
-
)
|
|
218
|
+
yvals = tide_fit.kaiserbessel_eval(xvals, np.array([beta, width / 2.0]))
|
|
254
219
|
else:
|
|
255
220
|
print("illegal kernel value in congrid - exiting")
|
|
256
221
|
sys.exit()
|
|
257
|
-
|
|
258
|
-
|
|
222
|
+
if cache:
|
|
223
|
+
congridyvals[offsetkey] = 1.0 * yvals
|
|
224
|
+
if debug and not onlykeynotices:
|
|
259
225
|
print("xvals, yvals", xvals, yvals)
|
|
260
|
-
if debug:
|
|
226
|
+
if debug and not onlykeynotices:
|
|
261
227
|
print("center, offset, indices, yvals", center, offset, indices, yvals)
|
|
262
228
|
return val * yvals, yvals, indices
|
|
263
229
|
|
|
@@ -273,6 +239,53 @@ class FastResampler:
|
|
|
273
239
|
debug=False,
|
|
274
240
|
method="univariate",
|
|
275
241
|
):
|
|
242
|
+
"""
|
|
243
|
+
Initialize the FastResampler with given time axis and time course data.
|
|
244
|
+
|
|
245
|
+
This constructor prepares high-resolution time series data by resampling the input
|
|
246
|
+
time course using one of several methods, with optional padding and plotting.
|
|
247
|
+
|
|
248
|
+
Parameters
|
|
249
|
+
----------
|
|
250
|
+
timeaxis : array-like
|
|
251
|
+
The time axis of the input data. Should be a 1D array of time points.
|
|
252
|
+
timecourse : array-like
|
|
253
|
+
The time course data corresponding to `timeaxis`. Should be a 1D array of values.
|
|
254
|
+
padtime : float, optional
|
|
255
|
+
Padding time in seconds to extend the resampled time axis on both ends.
|
|
256
|
+
Default is 30.0.
|
|
257
|
+
upsampleratio : int, optional
|
|
258
|
+
The upsampling ratio used for resampling. Default is 100.
|
|
259
|
+
doplot : bool, optional
|
|
260
|
+
If True, plot the original and high-resolution time courses. Default is False.
|
|
261
|
+
debug : bool, optional
|
|
262
|
+
If True, print debug information during initialization. Default is False.
|
|
263
|
+
method : str, optional
|
|
264
|
+
Resampling method to use. Options are:
|
|
265
|
+
- "univariate": Uses custom resampling logic.
|
|
266
|
+
- "poly": Uses `scipy.signal.resample_poly`.
|
|
267
|
+
- "fourier": Uses `scipy.signal.resample`.
|
|
268
|
+
Default is "univariate".
|
|
269
|
+
|
|
270
|
+
Returns
|
|
271
|
+
-------
|
|
272
|
+
None
|
|
273
|
+
This method initializes instance attributes and does not return a value.
|
|
274
|
+
|
|
275
|
+
Notes
|
|
276
|
+
-----
|
|
277
|
+
The resampled time axis (`hires_x`) is generated by extending the original time axis
|
|
278
|
+
by `padtime` on each side, using a step size that is `1 / upsampleratio` of the
|
|
279
|
+
original step size. The `hires_y` array contains the resampled time course values.
|
|
280
|
+
|
|
281
|
+
Examples
|
|
282
|
+
--------
|
|
283
|
+
>>> import numpy as np
|
|
284
|
+
>>> from scipy import signal
|
|
285
|
+
>>> timeaxis = np.linspace(0, 10, 100)
|
|
286
|
+
>>> timecourse = np.sin(timeaxis)
|
|
287
|
+
>>> resampler = FastResampler(timeaxis, timecourse, padtime=5.0, method="poly")
|
|
288
|
+
"""
|
|
276
289
|
self.timeaxis = timeaxis
|
|
277
290
|
self.timecourse = timecourse
|
|
278
291
|
self.upsampleratio = upsampleratio
|
|
@@ -288,13 +301,14 @@ class FastResampler:
|
|
|
288
301
|
)
|
|
289
302
|
self.hiresstart = self.hires_x[0]
|
|
290
303
|
self.hiresend = self.hires_x[-1]
|
|
291
|
-
|
|
304
|
+
self.method = method
|
|
305
|
+
if self.method == "poly":
|
|
292
306
|
self.hires_y = 0.0 * self.hires_x
|
|
293
307
|
self.hires_y[
|
|
294
308
|
int(self.padtime // self.hiresstep)
|
|
295
309
|
+ 1 : -(int(self.padtime // self.hiresstep) + 1)
|
|
296
310
|
] = signal.resample_poly(timecourse, int(self.upsampleratio * 10), 10)
|
|
297
|
-
elif method == "fourier":
|
|
311
|
+
elif self.method == "fourier":
|
|
298
312
|
self.hires_y = 0.0 * self.hires_x
|
|
299
313
|
self.hires_y[
|
|
300
314
|
int(self.padtime // self.hiresstep)
|
|
@@ -320,14 +334,144 @@ class FastResampler:
|
|
|
320
334
|
if doplot:
|
|
321
335
|
import matplolib.pyplot as pl
|
|
322
336
|
|
|
323
|
-
fig =
|
|
337
|
+
fig = plt.figure()
|
|
324
338
|
ax = fig.add_subplot(111)
|
|
325
339
|
ax.set_title("FastResampler initial timecourses")
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
340
|
+
plt.plot(timeaxis, timecourse, self.hires_x, self.hires_y)
|
|
341
|
+
plt.legend(("input", "hires"))
|
|
342
|
+
plt.show()
|
|
343
|
+
|
|
344
|
+
def getdata(self):
|
|
345
|
+
"""
|
|
346
|
+
Retrieve time series data and related parameters.
|
|
347
|
+
|
|
348
|
+
Returns
|
|
349
|
+
-------
|
|
350
|
+
tuple
|
|
351
|
+
A tuple containing:
|
|
352
|
+
- timeaxis : array_like
|
|
353
|
+
Time axis values
|
|
354
|
+
- timecourse : array_like
|
|
355
|
+
Time course data values
|
|
356
|
+
- hires_x : array_like
|
|
357
|
+
High resolution x-axis data
|
|
358
|
+
- hires_y : array_like
|
|
359
|
+
High resolution y-axis data
|
|
360
|
+
- inverse_initstep : float
|
|
361
|
+
Reciprocal of the initial step size (1.0 / self.initstep)
|
|
362
|
+
|
|
363
|
+
Notes
|
|
364
|
+
-----
|
|
365
|
+
This function provides access to all time series data and associated
|
|
366
|
+
high resolution parameters stored in the object instance. The returned
|
|
367
|
+
inverse_initstep value is commonly used for normalization or scaling
|
|
368
|
+
operations in time series analysis.
|
|
369
|
+
|
|
370
|
+
Examples
|
|
371
|
+
--------
|
|
372
|
+
>>> data = obj.getdata()
|
|
373
|
+
>>> time_axis, time_course, hires_x, hires_y, inv_step = data
|
|
374
|
+
>>> print(f"Time course shape: {time_course.shape}")
|
|
375
|
+
"""
|
|
376
|
+
return self.timeaxis, self.timecourse, self.hires_x, self.hires_y, 1.0 / self.initstep
|
|
377
|
+
|
|
378
|
+
def info(self, prefix=""):
|
|
379
|
+
"""
|
|
380
|
+
Print information about the object's time and sampling parameters.
|
|
381
|
+
|
|
382
|
+
This method displays various time-related attributes and sampling parameters
|
|
383
|
+
of the object, with optional prefix for better formatting in output.
|
|
384
|
+
|
|
385
|
+
Parameters
|
|
386
|
+
----------
|
|
387
|
+
prefix : str, optional
|
|
388
|
+
String to prepend to each printed line, useful for indentation or
|
|
389
|
+
grouping related output. Default is empty string.
|
|
390
|
+
|
|
391
|
+
Returns
|
|
392
|
+
-------
|
|
393
|
+
None
|
|
394
|
+
This method prints information to stdout and does not return any value.
|
|
395
|
+
|
|
396
|
+
Notes
|
|
397
|
+
-----
|
|
398
|
+
The method prints the following attributes:
|
|
399
|
+
- timeaxis: Time axis values
|
|
400
|
+
- timecourse: Time course data
|
|
401
|
+
- upsampleratio: Upsampling ratio
|
|
402
|
+
- padtime: Padding time
|
|
403
|
+
- initstep: Initial step size
|
|
404
|
+
- initstart: Initial start time
|
|
405
|
+
- initend: Initial end time
|
|
406
|
+
- hiresstep: High-resolution step size
|
|
407
|
+
- hires_x[0]: First value of high-resolution x-axis
|
|
408
|
+
- hires_x[-1]: Last value of high-resolution x-axis
|
|
409
|
+
- hiresstart: High-resolution start time
|
|
410
|
+
- hiresend: High-resolution end time
|
|
411
|
+
- method: Interpolation/processing method used
|
|
412
|
+
- hires_y[0]: First value of high-resolution y-axis
|
|
413
|
+
- hires_y[-1]: Last value of high-resolution y-axis
|
|
414
|
+
|
|
415
|
+
Examples
|
|
416
|
+
--------
|
|
417
|
+
>>> obj.info()
|
|
418
|
+
timeaxis=100
|
|
419
|
+
timecourse=200
|
|
420
|
+
upsampleratio=4
|
|
421
|
+
...
|
|
422
|
+
|
|
423
|
+
>>> obj.info(prefix=" ")
|
|
424
|
+
timeaxis=100
|
|
425
|
+
timecourse=200
|
|
426
|
+
upsampleratio=4
|
|
427
|
+
...
|
|
428
|
+
"""
|
|
429
|
+
print(f"{prefix}{self.timeaxis=}")
|
|
430
|
+
print(f"{prefix}{self.timecourse=}")
|
|
431
|
+
print(f"{prefix}{self.upsampleratio=}")
|
|
432
|
+
print(f"{prefix}{self.padtime=}")
|
|
433
|
+
print(f"{prefix}{self.initstep=}")
|
|
434
|
+
print(f"{prefix}{self.initstart=}")
|
|
435
|
+
print(f"{prefix}{self.initend=}")
|
|
436
|
+
print(f"{prefix}{self.hiresstep=}")
|
|
437
|
+
print(f"{prefix}{self.hires_x[0]=}")
|
|
438
|
+
print(f"{prefix}{self.hires_x[-1]=}")
|
|
439
|
+
print(f"{prefix}{self.hiresstart=}")
|
|
440
|
+
print(f"{prefix}{self.hiresend=}")
|
|
441
|
+
print(f"{prefix}{self.method=}")
|
|
442
|
+
print(f"{prefix}{self.hires_y[0]=}")
|
|
443
|
+
print(f"{prefix}{self.hires_y[-1]=}")
|
|
329
444
|
|
|
330
445
|
def save(self, outputname):
|
|
446
|
+
"""
|
|
447
|
+
Save the timecourse data to a TSV file.
|
|
448
|
+
|
|
449
|
+
This method writes the internal timecourse data to a tab-separated values file
|
|
450
|
+
with additional metadata in the header. The output includes the timecourse data
|
|
451
|
+
along with timing information derived from the object's initialization parameters.
|
|
452
|
+
|
|
453
|
+
Parameters
|
|
454
|
+
----------
|
|
455
|
+
outputname : str
|
|
456
|
+
The path and filename where the TSV output will be saved.
|
|
457
|
+
|
|
458
|
+
Returns
|
|
459
|
+
-------
|
|
460
|
+
None
|
|
461
|
+
This method does not return any value.
|
|
462
|
+
|
|
463
|
+
Notes
|
|
464
|
+
-----
|
|
465
|
+
The method uses the `tide_io.writebidstsv` function to perform the actual file writing.
|
|
466
|
+
The time step is calculated as 1.0 divided by `self.initstep`, and the start time
|
|
467
|
+
is taken from `self.initstart`. The output file includes a header with description
|
|
468
|
+
metadata indicating this is a lagged timecourse generator.
|
|
469
|
+
|
|
470
|
+
Examples
|
|
471
|
+
--------
|
|
472
|
+
>>> obj.save("output_timecourse.tsv")
|
|
473
|
+
>>> # Creates a TSV file with the timecourse data and metadata
|
|
474
|
+
"""
|
|
331
475
|
tide_io.writebidstsv(
|
|
332
476
|
outputname,
|
|
333
477
|
self.timecourse,
|
|
@@ -339,6 +483,41 @@ class FastResampler:
|
|
|
339
483
|
)
|
|
340
484
|
|
|
341
485
|
def yfromx(self, newtimeaxis, doplot=False, debug=False):
|
|
486
|
+
"""
|
|
487
|
+
Resample y-values from a high-resolution time axis to a new time axis.
|
|
488
|
+
|
|
489
|
+
This method maps values from a high-resolution y-array (`self.hires_y`) to a
|
|
490
|
+
new time axis (`newtimeaxis`) by linear interpolation based on the step size
|
|
491
|
+
and start of the high-resolution axis.
|
|
492
|
+
|
|
493
|
+
Parameters
|
|
494
|
+
----------
|
|
495
|
+
newtimeaxis : array-like
|
|
496
|
+
The new time axis to which the y-values will be resampled.
|
|
497
|
+
doplot : bool, optional
|
|
498
|
+
If True, plot the original high-resolution y-values and the resampled
|
|
499
|
+
values for comparison. Default is False.
|
|
500
|
+
debug : bool, optional
|
|
501
|
+
If True, print debug information including internal parameters and
|
|
502
|
+
bounds checking. Default is False.
|
|
503
|
+
|
|
504
|
+
Returns
|
|
505
|
+
-------
|
|
506
|
+
out_y : ndarray
|
|
507
|
+
The resampled y-values corresponding to `newtimeaxis`.
|
|
508
|
+
|
|
509
|
+
Notes
|
|
510
|
+
-----
|
|
511
|
+
This function assumes that `self.hires_y` has been precomputed and that
|
|
512
|
+
the internal parameters (`self.hiresstart`, `self.hiresstep`) are valid.
|
|
513
|
+
An IndexError is raised if any index in `outindices` is out of bounds.
|
|
514
|
+
|
|
515
|
+
Examples
|
|
516
|
+
--------
|
|
517
|
+
>>> resampler = FastResampler()
|
|
518
|
+
>>> new_times = np.linspace(0, 10, 100)
|
|
519
|
+
>>> y_vals = resampler.yfromx(new_times, doplot=True)
|
|
520
|
+
"""
|
|
342
521
|
if debug:
|
|
343
522
|
print("FastResampler: yfromx called with following parameters")
|
|
344
523
|
print(" padtime:, ", self.padtime)
|
|
@@ -361,16 +540,59 @@ class FastResampler:
|
|
|
361
540
|
print(" requested axis limits:", newtimeaxis[0], newtimeaxis[-1])
|
|
362
541
|
sys.exit()
|
|
363
542
|
if doplot:
|
|
364
|
-
fig =
|
|
543
|
+
fig = plt.figure()
|
|
365
544
|
ax = fig.add_subplot(111)
|
|
366
545
|
ax.set_title("FastResampler timecourses")
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
546
|
+
plt.plot(self.hires_x, self.hires_y, newtimeaxis, out_y)
|
|
547
|
+
plt.legend(("hires", "output"))
|
|
548
|
+
plt.show()
|
|
370
549
|
return out_y
|
|
371
550
|
|
|
372
551
|
|
|
373
|
-
def FastResamplerFromFile(
|
|
552
|
+
def FastResamplerFromFile(
|
|
553
|
+
inputname: str, colspec: Optional[str] = None, debug: bool = False, **kwargs
|
|
554
|
+
) -> FastResampler:
|
|
555
|
+
"""
|
|
556
|
+
Create a FastResampler from a BIDS TSV file.
|
|
557
|
+
|
|
558
|
+
This function reads data from a BIDS TSV file and creates a FastResampler object
|
|
559
|
+
for efficient time series resampling operations. The input file must contain
|
|
560
|
+
exactly one column of data.
|
|
561
|
+
|
|
562
|
+
Parameters
|
|
563
|
+
----------
|
|
564
|
+
inputname : str
|
|
565
|
+
Path to the input BIDS TSV file containing the time series data
|
|
566
|
+
colspec : str, optional
|
|
567
|
+
Column specification for selecting specific columns from the TSV file.
|
|
568
|
+
If None, all columns are read (default: None)
|
|
569
|
+
debug : bool, optional
|
|
570
|
+
Enable debug output printing (default: False)
|
|
571
|
+
**kwargs
|
|
572
|
+
Additional keyword arguments passed to the FastResampler constructor
|
|
573
|
+
|
|
574
|
+
Returns
|
|
575
|
+
-------
|
|
576
|
+
FastResampler
|
|
577
|
+
A FastResampler object initialized with the time axis and data from the input file
|
|
578
|
+
|
|
579
|
+
Raises
|
|
580
|
+
------
|
|
581
|
+
ValueError
|
|
582
|
+
If the input file contains multiple columns of data
|
|
583
|
+
|
|
584
|
+
Notes
|
|
585
|
+
-----
|
|
586
|
+
The function internally calls `tide_io.readbidstsv` to read the input file and
|
|
587
|
+
constructs a time axis using `np.linspace` based on the sampling rate and
|
|
588
|
+
start time from the input file.
|
|
589
|
+
|
|
590
|
+
Examples
|
|
591
|
+
--------
|
|
592
|
+
>>> resampler = FastResamplerFromFile('data.tsv')
|
|
593
|
+
>>> resampler = FastResamplerFromFile('data.tsv', colspec='column1')
|
|
594
|
+
>>> resampler = FastResamplerFromFile('data.tsv', debug=True)
|
|
595
|
+
"""
|
|
374
596
|
(
|
|
375
597
|
insamplerate,
|
|
376
598
|
instarttime,
|
|
@@ -378,9 +600,13 @@ def FastResamplerFromFile(inputname, colspec=None, debug=False, **kwargs):
|
|
|
378
600
|
indata,
|
|
379
601
|
incompressed,
|
|
380
602
|
incolsource,
|
|
603
|
+
inextrainfo,
|
|
381
604
|
) = tide_io.readbidstsv(inputname, colspec=colspec, debug=debug)
|
|
382
|
-
if
|
|
383
|
-
|
|
605
|
+
if incolumns is not None:
|
|
606
|
+
if len(incolumns) > 1:
|
|
607
|
+
raise ValueError("Multiple columns in input file")
|
|
608
|
+
else:
|
|
609
|
+
raise ValueError("No column names in file")
|
|
384
610
|
intimecourse = indata[0, :]
|
|
385
611
|
intimeaxis = np.linspace(
|
|
386
612
|
instarttime,
|
|
@@ -394,29 +620,65 @@ def FastResamplerFromFile(inputname, colspec=None, debug=False, **kwargs):
|
|
|
394
620
|
|
|
395
621
|
|
|
396
622
|
def doresample(
|
|
397
|
-
orig_x,
|
|
398
|
-
orig_y,
|
|
399
|
-
new_x,
|
|
400
|
-
method="cubic",
|
|
401
|
-
padlen=0,
|
|
402
|
-
padtype="reflect",
|
|
403
|
-
antialias=False,
|
|
404
|
-
debug=False,
|
|
405
|
-
):
|
|
623
|
+
orig_x: NDArray,
|
|
624
|
+
orig_y: NDArray,
|
|
625
|
+
new_x: NDArray,
|
|
626
|
+
method: str = "cubic",
|
|
627
|
+
padlen: int = 0,
|
|
628
|
+
padtype: str = "reflect",
|
|
629
|
+
antialias: bool = False,
|
|
630
|
+
debug: bool = False,
|
|
631
|
+
) -> NDArray:
|
|
406
632
|
"""
|
|
407
|
-
Resample data from one spacing to another.
|
|
633
|
+
Resample data from one spacing to another.
|
|
634
|
+
|
|
635
|
+
By default, does not apply any antialiasing filter.
|
|
408
636
|
|
|
409
637
|
Parameters
|
|
410
638
|
----------
|
|
411
|
-
orig_x
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
639
|
+
orig_x : NDArray
|
|
640
|
+
Original x-coordinates of the data to be resampled.
|
|
641
|
+
orig_y : NDArray
|
|
642
|
+
Original y-values corresponding to `orig_x`.
|
|
643
|
+
new_x : NDArray
|
|
644
|
+
New x-coordinates at which to evaluate the resampled data.
|
|
645
|
+
method : str, optional
|
|
646
|
+
Interpolation method to use. Options are:
|
|
647
|
+
- "cubic": cubic spline interpolation (default)
|
|
648
|
+
- "quadratic": quadratic spline interpolation
|
|
649
|
+
- "univariate": univariate spline interpolation using `scipy.interpolate.UnivariateSpline`
|
|
650
|
+
padlen : int, optional
|
|
651
|
+
Number of elements to pad the input data at both ends. Default is 0.
|
|
652
|
+
padtype : str, optional
|
|
653
|
+
Type of padding to use when `padlen > 0`. Default is "reflect".
|
|
654
|
+
Passed to `tide_filt.padvec`.
|
|
655
|
+
antialias : bool, optional
|
|
656
|
+
If True, apply an antialiasing filter before resampling if the original
|
|
657
|
+
sampling frequency is higher than the target frequency. Default is False.
|
|
658
|
+
debug : bool, optional
|
|
659
|
+
If True, print debug information and display a plot of the original and
|
|
660
|
+
padded data. Default is False.
|
|
416
661
|
|
|
417
662
|
Returns
|
|
418
663
|
-------
|
|
664
|
+
ndarray
|
|
665
|
+
Resampled y-values at coordinates specified by `new_x`. If an invalid
|
|
666
|
+
interpolation method is specified, returns None.
|
|
419
667
|
|
|
668
|
+
Notes
|
|
669
|
+
-----
|
|
670
|
+
- The function uses padding to handle edge effects during interpolation.
|
|
671
|
+
- When `antialias=True`, a non-causal filter is applied to reduce aliasing
|
|
672
|
+
artifacts when downsampling.
|
|
673
|
+
- The `tide_filt` module is used for padding and filtering operations.
|
|
674
|
+
|
|
675
|
+
Examples
|
|
676
|
+
--------
|
|
677
|
+
>>> import numpy as np
|
|
678
|
+
>>> x = np.linspace(0, 10, 100)
|
|
679
|
+
>>> y = np.sin(x)
|
|
680
|
+
>>> new_x = np.linspace(0, 10, 200)
|
|
681
|
+
>>> y_resampled = doresample(x, y, new_x, method="cubic")
|
|
420
682
|
"""
|
|
421
683
|
tstep = orig_x[1] - orig_x[0]
|
|
422
684
|
if padlen > 0:
|
|
@@ -435,11 +697,11 @@ def doresample(
|
|
|
435
697
|
print("lens:", len(pad_x), len(pad_y))
|
|
436
698
|
print(pad_x)
|
|
437
699
|
print(pad_y)
|
|
438
|
-
fig =
|
|
700
|
+
fig = plt.figure()
|
|
439
701
|
ax = fig.add_subplot(111)
|
|
440
702
|
ax.set_title("Original and padded vector")
|
|
441
|
-
|
|
442
|
-
|
|
703
|
+
plt.plot(orig_x, orig_y + 1.0, pad_x, pad_y)
|
|
704
|
+
plt.show()
|
|
443
705
|
|
|
444
706
|
# antialias and ringstop filter
|
|
445
707
|
init_freq = len(pad_x) / (pad_x[-1] - pad_x[0])
|
|
@@ -463,38 +725,82 @@ def doresample(
|
|
|
463
725
|
elif method == "univariate":
|
|
464
726
|
interpolator = sp.interpolate.UnivariateSpline(pad_x, pad_y, k=3, s=0) # s=0 interpolates
|
|
465
727
|
# return tide_filt.unpadvec(np.float64(interpolator(new_x)), padlen=padlen)
|
|
466
|
-
return
|
|
728
|
+
return (interpolator(new_x)).astype(np.float64)
|
|
467
729
|
else:
|
|
468
730
|
print("invalid interpolation method")
|
|
469
731
|
return None
|
|
470
732
|
|
|
471
733
|
|
|
472
734
|
def arbresample(
|
|
473
|
-
inputdata,
|
|
474
|
-
init_freq,
|
|
475
|
-
final_freq,
|
|
476
|
-
intermed_freq=0.0,
|
|
477
|
-
method="univariate",
|
|
478
|
-
antialias=True,
|
|
479
|
-
decimate=False,
|
|
480
|
-
debug=False,
|
|
481
|
-
):
|
|
735
|
+
inputdata: NDArray,
|
|
736
|
+
init_freq: float,
|
|
737
|
+
final_freq: float,
|
|
738
|
+
intermed_freq: float = 0.0,
|
|
739
|
+
method: str = "univariate",
|
|
740
|
+
antialias: bool = True,
|
|
741
|
+
decimate: bool = False,
|
|
742
|
+
debug: bool = False,
|
|
743
|
+
) -> NDArray:
|
|
482
744
|
"""
|
|
745
|
+
Resample input data from an initial frequency to a final frequency using either
|
|
746
|
+
direct resampling or a two-step process with intermediate frequency.
|
|
747
|
+
|
|
748
|
+
This function supports both upsampling and downsampling, with optional anti-aliasing
|
|
749
|
+
and decimation. It can operate in debug mode to print intermediate steps and
|
|
750
|
+
statistics.
|
|
483
751
|
|
|
484
752
|
Parameters
|
|
485
753
|
----------
|
|
486
|
-
inputdata
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
754
|
+
inputdata : NDArray
|
|
755
|
+
Input signal or data to be resampled. Should be a 1-D array-like object.
|
|
756
|
+
init_freq : float
|
|
757
|
+
Initial sampling frequency of the input data in Hz.
|
|
758
|
+
final_freq : float
|
|
759
|
+
Target sampling frequency of the output data in Hz.
|
|
760
|
+
intermed_freq : float, optional
|
|
761
|
+
Intermediate sampling frequency used in the two-step resampling process.
|
|
762
|
+
If not specified (default: 0.0), it is automatically set to the maximum of
|
|
763
|
+
2 * init_freq and 2 * final_freq.
|
|
764
|
+
method : str, optional
|
|
765
|
+
Interpolation method to use for resampling. Default is "univariate".
|
|
766
|
+
Other options may be supported depending on the underlying implementation.
|
|
767
|
+
antialias : bool, optional
|
|
768
|
+
If True (default), apply anti-aliasing filter during downsampling using
|
|
769
|
+
`scipy.signal.decimate`. If False, use simple interpolation for downsampling.
|
|
770
|
+
decimate : bool, optional
|
|
771
|
+
If True, perform upsampling followed by decimation for downsampling.
|
|
772
|
+
If False, use a two-step resampling approach with `dotwostepresample`.
|
|
773
|
+
Default is False.
|
|
774
|
+
debug : bool, optional
|
|
775
|
+
If True, print debug information including number of points before and after
|
|
776
|
+
resampling, and intermediate steps. Default is False.
|
|
494
777
|
|
|
495
778
|
Returns
|
|
496
779
|
-------
|
|
780
|
+
NDArray
|
|
781
|
+
Resampled data as a NumPy array with length adjusted according to `final_freq`.
|
|
497
782
|
|
|
783
|
+
Notes
|
|
784
|
+
-----
|
|
785
|
+
- When `decimate=True`, the function uses integer decimation for efficient downsampling.
|
|
786
|
+
- For downsampling, if `antialias=False`, the function uses linear interpolation
|
|
787
|
+
instead of filtering to reduce computational cost.
|
|
788
|
+
- The `intermed_freq` is automatically calculated when `decimate=True` and
|
|
789
|
+
`final_freq < init_freq`.
|
|
790
|
+
|
|
791
|
+
Examples
|
|
792
|
+
--------
|
|
793
|
+
>>> import numpy as np
|
|
794
|
+
>>> data = np.random.rand(100)
|
|
795
|
+
>>> resampled = arbresample(data, init_freq=100, final_freq=50, decimate=True)
|
|
796
|
+
>>> print(len(resampled))
|
|
797
|
+
50
|
|
798
|
+
|
|
799
|
+
See Also
|
|
800
|
+
--------
|
|
801
|
+
upsample : Function used for upsampling when `decimate=True`.
|
|
802
|
+
dotwostepresample : Function used for two-step resampling when `decimate=False`.
|
|
803
|
+
scipy.signal.decimate : Anti-aliasing filter used when `antialias=True`.
|
|
498
804
|
"""
|
|
499
805
|
if debug:
|
|
500
806
|
print("arbresample - initial points:", len(inputdata))
|
|
@@ -566,7 +872,62 @@ def arbresample(
|
|
|
566
872
|
return resampled
|
|
567
873
|
|
|
568
874
|
|
|
569
|
-
def upsample(
|
|
875
|
+
def upsample(
|
|
876
|
+
inputdata: NDArray,
|
|
877
|
+
Fs_init: float,
|
|
878
|
+
Fs_higher: float,
|
|
879
|
+
method: str = "univariate",
|
|
880
|
+
intfac: bool = False,
|
|
881
|
+
dofilt: bool = True,
|
|
882
|
+
debug: bool = False,
|
|
883
|
+
) -> NDArray:
|
|
884
|
+
"""
|
|
885
|
+
Upsample input data to a higher sampling frequency.
|
|
886
|
+
|
|
887
|
+
This function increases the sampling rate of the input data using interpolation
|
|
888
|
+
and optional filtering. It supports different interpolation methods and allows
|
|
889
|
+
for control over the resampling factor and filtering behavior.
|
|
890
|
+
|
|
891
|
+
Parameters
|
|
892
|
+
----------
|
|
893
|
+
inputdata : NDArray
|
|
894
|
+
Input time series data to be upsampled.
|
|
895
|
+
Fs_init : float
|
|
896
|
+
Initial sampling frequency of the input data (Hz).
|
|
897
|
+
Fs_higher : float
|
|
898
|
+
Target sampling frequency to upsample to (Hz). Must be greater than `Fs_init`.
|
|
899
|
+
method : str, optional
|
|
900
|
+
Interpolation method to use. Default is "univariate". Other options depend
|
|
901
|
+
on the implementation of `doresample`.
|
|
902
|
+
intfac : bool, optional
|
|
903
|
+
If True, use integer resampling factor based on `Fs_higher // Fs_init`.
|
|
904
|
+
If False, compute resampled points based on time duration. Default is False.
|
|
905
|
+
dofilt : bool, optional
|
|
906
|
+
If True, apply a non-causal filter to prevent aliasing. Default is True.
|
|
907
|
+
debug : bool, optional
|
|
908
|
+
If True, print timing information. Default is False.
|
|
909
|
+
|
|
910
|
+
Returns
|
|
911
|
+
-------
|
|
912
|
+
NDArray
|
|
913
|
+
Upsampled time series data with the new sampling frequency.
|
|
914
|
+
|
|
915
|
+
Notes
|
|
916
|
+
-----
|
|
917
|
+
- The function uses linear interpolation by default, but the actual method
|
|
918
|
+
depends on the `doresample` function implementation.
|
|
919
|
+
- If `dofilt` is True, a trapezoidal non-causal filter is applied with a
|
|
920
|
+
stop frequency set to the minimum of 1.1 * Fs_init / 2.0 and Fs_higher / 2.0.
|
|
921
|
+
- The function will terminate if `Fs_higher` is not greater than `Fs_init`.
|
|
922
|
+
|
|
923
|
+
Examples
|
|
924
|
+
--------
|
|
925
|
+
>>> import numpy as np
|
|
926
|
+
>>> data = np.sin(np.linspace(0, 4*np.pi, 100))
|
|
927
|
+
>>> upsampled = upsample(data, Fs_init=10.0, Fs_higher=20.0)
|
|
928
|
+
>>> print(len(upsampled))
|
|
929
|
+
200
|
|
930
|
+
"""
|
|
570
931
|
starttime = time.time()
|
|
571
932
|
if Fs_higher <= Fs_init:
|
|
572
933
|
print("upsample: target frequency must be higher than initial frequency")
|
|
@@ -576,48 +937,79 @@ def upsample(inputdata, Fs_init, Fs_higher, method="univariate", intfac=False, d
|
|
|
576
937
|
orig_x = np.linspace(0.0, (1.0 / Fs_init) * len(inputdata), num=len(inputdata), endpoint=False)
|
|
577
938
|
endpoint = orig_x[-1] - orig_x[0]
|
|
578
939
|
ts_higher = 1.0 / Fs_higher
|
|
579
|
-
numresamppts = int(endpoint // ts_higher + 1)
|
|
580
940
|
if intfac:
|
|
581
941
|
numresamppts = int(Fs_higher // Fs_init) * len(inputdata)
|
|
582
942
|
else:
|
|
583
943
|
numresamppts = int(endpoint // ts_higher + 1)
|
|
584
944
|
upsampled_x = np.arange(0.0, ts_higher * numresamppts, ts_higher)
|
|
585
945
|
upsampled_y = doresample(orig_x, inputdata, upsampled_x, method=method)
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
946
|
+
if dofilt:
|
|
947
|
+
initfilter = tide_filt.NoncausalFilter(
|
|
948
|
+
filtertype="arb", transferfunc="trapezoidal", debug=debug
|
|
949
|
+
)
|
|
950
|
+
stopfreq = np.min([1.1 * Fs_init / 2.0, Fs_higher / 2.0])
|
|
951
|
+
initfilter.setfreqs(0.0, 0.0, Fs_init / 2.0, stopfreq)
|
|
952
|
+
upsampled_y = initfilter.apply(Fs_higher, upsampled_y)
|
|
592
953
|
if debug:
|
|
593
954
|
print("upsampling took", time.time() - starttime, "seconds")
|
|
594
955
|
return upsampled_y
|
|
595
956
|
|
|
596
957
|
|
|
597
958
|
def dotwostepresample(
|
|
598
|
-
orig_x,
|
|
599
|
-
orig_y,
|
|
600
|
-
intermed_freq,
|
|
601
|
-
final_freq,
|
|
602
|
-
method="univariate",
|
|
603
|
-
antialias=True,
|
|
604
|
-
debug=False,
|
|
605
|
-
):
|
|
959
|
+
orig_x: NDArray,
|
|
960
|
+
orig_y: NDArray,
|
|
961
|
+
intermed_freq: float,
|
|
962
|
+
final_freq: float,
|
|
963
|
+
method: str = "univariate",
|
|
964
|
+
antialias: bool = True,
|
|
965
|
+
debug: bool = False,
|
|
966
|
+
) -> NDArray:
|
|
606
967
|
"""
|
|
968
|
+
Resample a signal from original frequency to final frequency using a two-step process:
|
|
969
|
+
first upsampling to an intermediate frequency, then downsampling to the final frequency.
|
|
970
|
+
|
|
971
|
+
This function performs resampling by first interpolating the input signal to an
|
|
972
|
+
intermediate frequency that is higher than the final desired frequency, followed by
|
|
973
|
+
downsampling to the target frequency. Optional antialiasing filtering is applied
|
|
974
|
+
during the upsampling step.
|
|
607
975
|
|
|
608
976
|
Parameters
|
|
609
977
|
----------
|
|
610
|
-
orig_x
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
978
|
+
orig_x : NDArray
|
|
979
|
+
Original time axis values (must be monotonically increasing).
|
|
980
|
+
orig_y : NDArray
|
|
981
|
+
Original signal values corresponding to `orig_x`.
|
|
982
|
+
intermed_freq : float
|
|
983
|
+
Intermediate frequency to which the signal is upsampled.
|
|
984
|
+
Must be greater than `final_freq`.
|
|
985
|
+
final_freq : float
|
|
986
|
+
Target frequency to which the signal is downsampled.
|
|
987
|
+
method : str, optional
|
|
988
|
+
Interpolation method used for resampling. Default is "univariate".
|
|
989
|
+
Should be compatible with the `doresample` function.
|
|
990
|
+
antialias : bool, optional
|
|
991
|
+
If True, apply an antialiasing filter during upsampling. Default is True.
|
|
992
|
+
debug : bool, optional
|
|
993
|
+
If True, print timing and intermediate information. Default is False.
|
|
616
994
|
|
|
617
995
|
Returns
|
|
618
996
|
-------
|
|
619
|
-
|
|
997
|
+
ndarray
|
|
998
|
+
Resampled signal values at the final frequency.
|
|
620
999
|
|
|
1000
|
+
Notes
|
|
1001
|
+
-----
|
|
1002
|
+
- The intermediate frequency must be strictly greater than the final frequency.
|
|
1003
|
+
- The function uses `doresample` for interpolation and `tide_filt.NoncausalFilter`
|
|
1004
|
+
for antialiasing if enabled.
|
|
1005
|
+
- Timing information is printed when `debug=True`.
|
|
1006
|
+
|
|
1007
|
+
Examples
|
|
1008
|
+
--------
|
|
1009
|
+
>>> import numpy as np
|
|
1010
|
+
>>> x = np.linspace(0, 10, 100)
|
|
1011
|
+
>>> y = np.sin(x)
|
|
1012
|
+
>>> resampled = dotwostepresample(x, y, intermed_freq=50.0, final_freq=10.0)
|
|
621
1013
|
"""
|
|
622
1014
|
if intermed_freq <= final_freq:
|
|
623
1015
|
print("intermediate frequency must be higher than final frequency")
|
|
@@ -667,20 +1059,56 @@ def dotwostepresample(
|
|
|
667
1059
|
return resampled_y
|
|
668
1060
|
|
|
669
1061
|
|
|
670
|
-
def calcsliceoffset(
|
|
1062
|
+
def calcsliceoffset(
|
|
1063
|
+
sotype: int, slicenum: int, numslices: int, tr: float, multiband: int = 1
|
|
1064
|
+
) -> float:
|
|
671
1065
|
"""
|
|
1066
|
+
Calculate slice timing offset for slice timing correction.
|
|
1067
|
+
|
|
1068
|
+
This function computes the timing offset (in seconds) for a given slice
|
|
1069
|
+
based on the slice timing correction method specified by `sotype`. The
|
|
1070
|
+
offset is used to align slice acquisition times for functional MRI data
|
|
1071
|
+
preprocessing.
|
|
672
1072
|
|
|
673
1073
|
Parameters
|
|
674
1074
|
----------
|
|
675
|
-
sotype
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
1075
|
+
sotype : int
|
|
1076
|
+
Slice timing correction method:
|
|
1077
|
+
- 0: None
|
|
1078
|
+
- 1: Regular up (0, 1, 2, 3, ...)
|
|
1079
|
+
- 2: Regular down
|
|
1080
|
+
- 3: Use slice order file (not supported)
|
|
1081
|
+
- 4: Use slice timings file (not supported)
|
|
1082
|
+
- 5: Standard interleaved (0, 2, 4, ..., 1, 3, 5, ...)
|
|
1083
|
+
- 6: Siemens interleaved
|
|
1084
|
+
- 7: Siemens multiband interleaved
|
|
1085
|
+
slicenum : int
|
|
1086
|
+
The index of the slice for which to compute the timing offset.
|
|
1087
|
+
numslices : int
|
|
1088
|
+
Total number of slices in the volume.
|
|
1089
|
+
tr : float
|
|
1090
|
+
Repetition time (TR) in seconds.
|
|
1091
|
+
multiband : int, optional
|
|
1092
|
+
Multiband factor (default is 1). Used only for sotype 7 (Siemens
|
|
1093
|
+
multiband interleaved).
|
|
680
1094
|
|
|
681
1095
|
Returns
|
|
682
1096
|
-------
|
|
1097
|
+
float
|
|
1098
|
+
Slice timing offset in seconds.
|
|
1099
|
+
|
|
1100
|
+
Notes
|
|
1101
|
+
-----
|
|
1102
|
+
For sotypes 3 and 4, the function returns 0.0 as these methods are not
|
|
1103
|
+
implemented.
|
|
1104
|
+
|
|
1105
|
+
Examples
|
|
1106
|
+
--------
|
|
1107
|
+
>>> calcsliceoffset(1, 5, 32, 2.0)
|
|
1108
|
+
0.3125
|
|
683
1109
|
|
|
1110
|
+
>>> calcsliceoffset(5, 3, 16, 1.5)
|
|
1111
|
+
0.28125
|
|
684
1112
|
"""
|
|
685
1113
|
# Slice timing correction
|
|
686
1114
|
# 0 : None
|
|
@@ -771,19 +1199,61 @@ def calcsliceoffset(sotype, slicenum, numslices, tr, multiband=1):
|
|
|
771
1199
|
|
|
772
1200
|
# NB: a positive value of shifttrs delays the signal, a negative value advances it
|
|
773
1201
|
# timeshift using fourier phase multiplication
|
|
774
|
-
def timeshift(
|
|
1202
|
+
def timeshift(
|
|
1203
|
+
inputtc: ArrayLike, shifttrs: float, padtrs: int, doplot: bool = False, debug: bool = False
|
|
1204
|
+
) -> Tuple[NDArray, NDArray, NDArray, NDArray]:
|
|
775
1205
|
"""
|
|
1206
|
+
Apply a time shift to a signal using FFT-based modulation and padding.
|
|
1207
|
+
|
|
1208
|
+
This function performs a time shift on an input time course by applying
|
|
1209
|
+
phase modulation in the frequency domain, followed by inverse FFT. It uses
|
|
1210
|
+
padding and reflection to avoid edge discontinuities. The function also
|
|
1211
|
+
returns the corresponding shifted weights and the full padded results.
|
|
776
1212
|
|
|
777
1213
|
Parameters
|
|
778
1214
|
----------
|
|
779
|
-
inputtc
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
1215
|
+
inputtc : array-like
|
|
1216
|
+
Input time course to be shifted. Should be a 1D array of real values.
|
|
1217
|
+
shifttrs : float
|
|
1218
|
+
Time shift in units of samples. Positive values shift the signal forward,
|
|
1219
|
+
negative values shift it backward.
|
|
1220
|
+
padtrs : int
|
|
1221
|
+
Number of samples to pad the input signal on each side before shifting.
|
|
1222
|
+
This helps reduce edge effects.
|
|
1223
|
+
doplot : bool, optional
|
|
1224
|
+
If True, plots the original and shifted signals. Default is False.
|
|
1225
|
+
debug : bool, optional
|
|
1226
|
+
If True, prints debug information during execution. Default is False.
|
|
783
1227
|
|
|
784
1228
|
Returns
|
|
785
1229
|
-------
|
|
1230
|
+
tuple of ndarray
|
|
1231
|
+
A tuple containing:
|
|
1232
|
+
- shifted_y : ndarray
|
|
1233
|
+
The time-shifted signal, cropped to the original length.
|
|
1234
|
+
- shifted_weights : ndarray
|
|
1235
|
+
The corresponding shifted weights, cropped to the original length.
|
|
1236
|
+
- shifted_y_full : ndarray
|
|
1237
|
+
The full time-shifted signal including padding.
|
|
1238
|
+
- shifted_weights_full : ndarray
|
|
1239
|
+
The full shifted weights including padding.
|
|
786
1240
|
|
|
1241
|
+
Notes
|
|
1242
|
+
-----
|
|
1243
|
+
The function uses reflection padding to minimize edge artifacts. The phase
|
|
1244
|
+
modulation is applied in the frequency domain using FFT and inverse FFT.
|
|
1245
|
+
The shift is implemented as a complex exponential modulation.
|
|
1246
|
+
|
|
1247
|
+
Examples
|
|
1248
|
+
--------
|
|
1249
|
+
>>> import numpy as np
|
|
1250
|
+
>>> from scipy import fftpack
|
|
1251
|
+
>>> input_signal = np.sin(np.linspace(0, 4*np.pi, 100))
|
|
1252
|
+
>>> shifted_sig, weights, full_shifted, full_weights = timeshift(
|
|
1253
|
+
... input_signal, shifttrs=5.0, padtrs=10, doplot=False
|
|
1254
|
+
... )
|
|
1255
|
+
>>> print(shifted_sig.shape)
|
|
1256
|
+
(100,)
|
|
787
1257
|
"""
|
|
788
1258
|
# set up useful parameters
|
|
789
1259
|
thelen = np.shape(inputtc)[0]
|
|
@@ -830,36 +1300,87 @@ def timeshift(inputtc, shifttrs, padtrs, doplot=False, debug=False):
|
|
|
830
1300
|
print("thelen:", thelen)
|
|
831
1301
|
print("thepaddedlen:", thepaddedlen)
|
|
832
1302
|
|
|
833
|
-
fig =
|
|
1303
|
+
fig = plt.figure()
|
|
834
1304
|
ax = fig.add_subplot(111)
|
|
835
1305
|
ax.set_title("Initial vector")
|
|
836
|
-
|
|
1306
|
+
plt.plot(xvec, preshifted_y)
|
|
837
1307
|
|
|
838
|
-
fig =
|
|
1308
|
+
fig = plt.figure()
|
|
839
1309
|
ax = fig.add_subplot(111)
|
|
840
1310
|
ax.set_title("Initial and shifted vector")
|
|
841
|
-
|
|
1311
|
+
plt.plot(xvec, preshifted_y, xvec, shifted_y)
|
|
842
1312
|
|
|
843
|
-
|
|
1313
|
+
plt.show()
|
|
844
1314
|
|
|
845
|
-
return
|
|
1315
|
+
return (
|
|
846
1316
|
shifted_y[padtrs : padtrs + thelen],
|
|
847
1317
|
shifted_weights[padtrs : padtrs + thelen],
|
|
848
1318
|
shifted_y,
|
|
849
1319
|
shifted_weights,
|
|
850
|
-
|
|
1320
|
+
)
|
|
1321
|
+
|
|
851
1322
|
|
|
1323
|
+
def timewarp(
|
|
1324
|
+
orig_x: NDArray,
|
|
1325
|
+
orig_y: NDArray,
|
|
1326
|
+
timeoffset: NDArray,
|
|
1327
|
+
demean: bool = True,
|
|
1328
|
+
method: str = "univariate",
|
|
1329
|
+
debug: bool = False,
|
|
1330
|
+
) -> NDArray:
|
|
1331
|
+
"""
|
|
1332
|
+
Apply time warping to align time series data based on time offsets.
|
|
1333
|
+
|
|
1334
|
+
This function performs time warping by resampling input data according to
|
|
1335
|
+
provided time offsets. It can optionally remove the mean of the time offsets
|
|
1336
|
+
before resampling to center the data around zero.
|
|
1337
|
+
|
|
1338
|
+
Parameters
|
|
1339
|
+
----------
|
|
1340
|
+
orig_x : NDArray
|
|
1341
|
+
Original time axis values (x-coordinates) for the data to be warped.
|
|
1342
|
+
orig_y : NDArray
|
|
1343
|
+
Original signal values (y-coordinates) corresponding to orig_x.
|
|
1344
|
+
timeoffset : NDArray
|
|
1345
|
+
Time offsets to be applied to each point in the time axis. Positive values
|
|
1346
|
+
shift data forward in time, negative values shift backward.
|
|
1347
|
+
demean : bool, optional
|
|
1348
|
+
If True, remove the mean of timeoffset before resampling. Default is True.
|
|
1349
|
+
method : str, optional
|
|
1350
|
+
Resampling method to use. Options are 'univariate' or other methods
|
|
1351
|
+
supported by the underlying doresample function. Default is 'univariate'.
|
|
1352
|
+
debug : bool, optional
|
|
1353
|
+
If True, print debugging information about the warping process.
|
|
1354
|
+
Default is False.
|
|
852
1355
|
|
|
853
|
-
|
|
1356
|
+
Returns
|
|
1357
|
+
-------
|
|
1358
|
+
NDArray
|
|
1359
|
+
Warped time series data after applying the time offsets and resampling.
|
|
1360
|
+
|
|
1361
|
+
Notes
|
|
1362
|
+
-----
|
|
1363
|
+
The function calculates the maximum deviation in samples and uses half the
|
|
1364
|
+
length of the input data (or 30 seconds worth of samples, whichever is smaller)
|
|
1365
|
+
as padding length for the resampling operation.
|
|
1366
|
+
|
|
1367
|
+
Examples
|
|
1368
|
+
--------
|
|
1369
|
+
>>> import numpy as np
|
|
1370
|
+
>>> x = np.linspace(0, 10, 100)
|
|
1371
|
+
>>> y = np.sin(x)
|
|
1372
|
+
>>> offsets = np.random.normal(0, 0.1, 100)
|
|
1373
|
+
>>> warped_y = timewarp(x, y, offsets)
|
|
1374
|
+
"""
|
|
854
1375
|
if demean:
|
|
855
1376
|
demeanedoffset = timeoffset - np.mean(timeoffset)
|
|
856
1377
|
if debug:
|
|
857
1378
|
print("mean delay of ", np.mean(timeoffset), "seconds removed prior to resampling")
|
|
858
1379
|
else:
|
|
859
1380
|
demeanedoffset = timeoffset
|
|
860
|
-
sampletime = orig_x[1] - orig_x[0]
|
|
861
|
-
maxdevs = (np.min(demeanedoffset), np.max(demeanedoffset))
|
|
862
|
-
maxsamps = maxdevs / sampletime
|
|
1381
|
+
sampletime = float(orig_x[1] - orig_x[0])
|
|
1382
|
+
maxdevs = (float(np.min(demeanedoffset)), float(np.max(demeanedoffset)))
|
|
1383
|
+
maxsamps = (maxdevs[0] / sampletime, maxdevs[1] / sampletime)
|
|
863
1384
|
padlen = np.min([int(len(orig_x) // 2), int(30.0 / sampletime)])
|
|
864
1385
|
if debug:
|
|
865
1386
|
print("maximum deviation in samples:", maxsamps)
|