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/RapidtideDataset.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.
|
|
@@ -19,9 +19,11 @@
|
|
|
19
19
|
import copy
|
|
20
20
|
import os
|
|
21
21
|
import sys
|
|
22
|
+
from typing import Any, Callable
|
|
22
23
|
|
|
23
24
|
import nibabel as nib
|
|
24
25
|
import numpy as np
|
|
26
|
+
from numpy.typing import NDArray
|
|
25
27
|
|
|
26
28
|
import rapidtide.filter as tide_filt
|
|
27
29
|
import rapidtide.io as tide_io
|
|
@@ -29,31 +31,150 @@ import rapidtide.miscmath as tide_math
|
|
|
29
31
|
import rapidtide.stats as tide_stats
|
|
30
32
|
import rapidtide.util as tide_util
|
|
31
33
|
from rapidtide.Colortables import *
|
|
34
|
+
from rapidtide.stats import neglogpfromr_interpolator
|
|
32
35
|
|
|
33
36
|
atlases = {
|
|
34
37
|
"ASPECTS": {"atlasname": "ASPECTS"},
|
|
35
38
|
"ATT": {"atlasname": "ATTbasedFlowTerritories_split"},
|
|
36
|
-
"JHU1": {"atlasname": "JHU-ArterialTerritoriesNoVent-
|
|
37
|
-
"JHU2": {"atlasname": "JHU-ArterialTerritoriesNoVent-
|
|
39
|
+
"JHU1": {"atlasname": "JHU-ArterialTerritoriesNoVent-LVL1"},
|
|
40
|
+
"JHU2": {"atlasname": "JHU-ArterialTerritoriesNoVent-LVL2"},
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
|
|
44
|
+
def check_rt_spatialmatch(dataset1: Any, dataset2: Any) -> tuple[bool, bool, bool, bool]:
|
|
45
|
+
"""
|
|
46
|
+
Check spatial matching between two datasets for dimension, size, space, and affine properties.
|
|
47
|
+
|
|
48
|
+
This function compares four key spatial attributes between two datasets to determine
|
|
49
|
+
if they are spatially compatible for further processing or analysis.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
dataset1 : Any
|
|
54
|
+
First dataset object containing spatial attributes xdim, ydim, zdim, xsize, ysize,
|
|
55
|
+
zsize, space, and affine.
|
|
56
|
+
dataset2 : Any
|
|
57
|
+
Second dataset object containing the same spatial attributes as dataset1.
|
|
58
|
+
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
tuple[bool, bool, bool, bool]
|
|
62
|
+
A tuple of four boolean values representing:
|
|
63
|
+
- dimmatch: True if all spatial dimensions (xdim, ydim, zdim) match
|
|
64
|
+
- sizematch: True if all spatial sizes (xsize, ysize, zsize) match
|
|
65
|
+
- spacematch: True if spatial coordinate systems (space) match
|
|
66
|
+
- affinematch: True if affine transformation matrices (affine) match
|
|
67
|
+
|
|
68
|
+
Notes
|
|
69
|
+
-----
|
|
70
|
+
The function performs element-wise comparison of spatial attributes. For affine matrices,
|
|
71
|
+
the comparison uses Python's default equality operator, which may be sensitive to
|
|
72
|
+
floating-point precision differences.
|
|
73
|
+
|
|
74
|
+
Examples
|
|
75
|
+
--------
|
|
76
|
+
>>> dimmatch, sizematch, spacematch, affinematch = check_rt_spatialmatch(dataset1, dataset2)
|
|
77
|
+
>>> if dimmatch and sizematch:
|
|
78
|
+
... print("Datasets have matching dimensions and sizes")
|
|
79
|
+
"""
|
|
80
|
+
if (
|
|
81
|
+
(dataset1.xdim == dataset2.xdim)
|
|
82
|
+
and (dataset1.ydim == dataset2.ydim)
|
|
83
|
+
and (dataset1.zdim == dataset2.zdim)
|
|
84
|
+
):
|
|
85
|
+
dimmatch = True
|
|
86
|
+
else:
|
|
87
|
+
dimmatch = False
|
|
88
|
+
if (
|
|
89
|
+
(dataset1.xsize == dataset2.xsize)
|
|
90
|
+
and (dataset1.ysize == dataset2.ysize)
|
|
91
|
+
and (dataset1.zsize == dataset2.zsize)
|
|
92
|
+
):
|
|
93
|
+
sizematch = True
|
|
94
|
+
else:
|
|
95
|
+
sizematch = False
|
|
96
|
+
if dataset1.space == dataset2.space:
|
|
97
|
+
spacematch = True
|
|
98
|
+
else:
|
|
99
|
+
spacematch = False
|
|
100
|
+
if dataset1.affine == dataset2.affine:
|
|
101
|
+
affinematch = True
|
|
102
|
+
else:
|
|
103
|
+
affinematch = False
|
|
104
|
+
return dimmatch, sizematch, spacematch, affinematch
|
|
105
|
+
|
|
106
|
+
|
|
41
107
|
class Timecourse:
|
|
42
108
|
"Store a timecourse and some information about it"
|
|
43
109
|
|
|
44
110
|
def __init__(
|
|
45
111
|
self,
|
|
46
|
-
name,
|
|
47
|
-
filename,
|
|
48
|
-
namebase,
|
|
49
|
-
samplerate,
|
|
50
|
-
displaysamplerate,
|
|
51
|
-
starttime=0.0,
|
|
52
|
-
label=None,
|
|
53
|
-
report=False,
|
|
54
|
-
isbids=False,
|
|
55
|
-
|
|
56
|
-
|
|
112
|
+
name: str,
|
|
113
|
+
filename: str,
|
|
114
|
+
namebase: str,
|
|
115
|
+
samplerate: float,
|
|
116
|
+
displaysamplerate: float,
|
|
117
|
+
starttime: float = 0.0,
|
|
118
|
+
label: str | None = None,
|
|
119
|
+
report: bool = False,
|
|
120
|
+
isbids: bool = False,
|
|
121
|
+
limits: tuple[float, float] | None = None,
|
|
122
|
+
verbose: int = 0,
|
|
123
|
+
) -> None:
|
|
124
|
+
"""
|
|
125
|
+
Initialize a Timecourse object for reading and managing time series data.
|
|
126
|
+
|
|
127
|
+
This constructor sets up the basic properties of a timecourse and reads the
|
|
128
|
+
time series data from the specified file.
|
|
129
|
+
|
|
130
|
+
Parameters
|
|
131
|
+
----------
|
|
132
|
+
name : str
|
|
133
|
+
The name of the timecourse, used for identification
|
|
134
|
+
filename : str
|
|
135
|
+
The full path to the data file containing the time series
|
|
136
|
+
namebase : str
|
|
137
|
+
The base name of the file (without path)
|
|
138
|
+
samplerate : float
|
|
139
|
+
The sampling rate of the time series data in Hz
|
|
140
|
+
displaysamplerate : float
|
|
141
|
+
The sampling rate used for display purposes in Hz
|
|
142
|
+
starttime : float, default=0.0
|
|
143
|
+
The start time of the time series in seconds
|
|
144
|
+
label : str, optional
|
|
145
|
+
The label to use for display. If None, defaults to the name parameter
|
|
146
|
+
report : bool, default=False
|
|
147
|
+
Whether to generate a report during initialization
|
|
148
|
+
isbids : bool, default=False
|
|
149
|
+
Whether the data follows BIDS (Brain Imaging Data Structure) format
|
|
150
|
+
limits : tuple of float, optional
|
|
151
|
+
The (min, max) value limits for the time series data
|
|
152
|
+
verbose : int, default=0
|
|
153
|
+
Verbosity level for logging output (0 = quiet, higher values = more verbose)
|
|
154
|
+
|
|
155
|
+
Returns
|
|
156
|
+
-------
|
|
157
|
+
None
|
|
158
|
+
This method initializes the object and does not return any value
|
|
159
|
+
|
|
160
|
+
Notes
|
|
161
|
+
-----
|
|
162
|
+
The method automatically reads the time series data using the readTimeData method
|
|
163
|
+
after setting all the internal attributes. If verbose level is greater than 1,
|
|
164
|
+
a message is printed indicating the file being read.
|
|
165
|
+
|
|
166
|
+
Examples
|
|
167
|
+
--------
|
|
168
|
+
>>> tc = Timecourse(
|
|
169
|
+
... name="ECG",
|
|
170
|
+
... filename="/data/ecg_data.dat",
|
|
171
|
+
... namebase="ecg_data",
|
|
172
|
+
... samplerate=1000.0,
|
|
173
|
+
... displaysamplerate=100.0,
|
|
174
|
+
... starttime=0.0,
|
|
175
|
+
... label="Electrocardiogram"
|
|
176
|
+
... )
|
|
177
|
+
"""
|
|
57
178
|
self.verbose = verbose
|
|
58
179
|
self.name = name
|
|
59
180
|
self.filename = filename
|
|
@@ -62,6 +183,7 @@ class Timecourse:
|
|
|
62
183
|
self.displaysamplerate = displaysamplerate
|
|
63
184
|
self.starttime = starttime
|
|
64
185
|
self.isbids = isbids
|
|
186
|
+
self.limits = limits
|
|
65
187
|
|
|
66
188
|
if label is None:
|
|
67
189
|
self.label = name
|
|
@@ -72,9 +194,47 @@ class Timecourse:
|
|
|
72
194
|
print("reading Timecourse ", self.name, " from ", self.filename, "...")
|
|
73
195
|
self.readTimeData(self.label)
|
|
74
196
|
|
|
75
|
-
def readTimeData(self, thename):
|
|
197
|
+
def readTimeData(self, thename: str) -> None:
|
|
198
|
+
"""
|
|
199
|
+
Read time series data from a file and compute associated statistics and spectral properties.
|
|
200
|
+
|
|
201
|
+
This function reads time series data either from a BIDS-compatible TSV file or a vector file,
|
|
202
|
+
depending on whether the object is configured to use BIDS format. It computes the time axis,
|
|
203
|
+
spectral data, and statistical measures (kurtosis and skewness) for the selected column or
|
|
204
|
+
the entire dataset.
|
|
205
|
+
|
|
206
|
+
Parameters
|
|
207
|
+
----------
|
|
208
|
+
thename : str
|
|
209
|
+
The name of the column to extract from the BIDS TSV file. Ignored if not using BIDS format.
|
|
210
|
+
|
|
211
|
+
Returns
|
|
212
|
+
-------
|
|
213
|
+
None
|
|
214
|
+
This function does not return a value but updates the following attributes of the object:
|
|
215
|
+
- `timedata`: The time series data as a numpy array.
|
|
216
|
+
- `length`: The length of the time series.
|
|
217
|
+
- `timeaxis`: The time axis corresponding to the data.
|
|
218
|
+
- `specaxis`: The frequency axis for the power spectrum.
|
|
219
|
+
- `specdata`: The power spectrum of the time series.
|
|
220
|
+
- `kurtosis`, `kurtosis_z`, `kurtosis_p`: Kurtosis statistics.
|
|
221
|
+
- `skewness`, `skewness_z`, `skewness_p`: Skewness statistics.
|
|
222
|
+
|
|
223
|
+
Notes
|
|
224
|
+
-----
|
|
225
|
+
If the `thename` column is not found in a BIDS TSV file, the function sets `timedata` to `None`
|
|
226
|
+
and returns early. The function uses `tide_io.readbidstsv` for BIDS files and `tide_io.readvec`
|
|
227
|
+
for non-BIDS files. Spectral analysis and statistical computations are performed using
|
|
228
|
+
`tide_filt.spectrum`, `tide_math.corrnormalize`, and `tide_stats.kurtosisstats`/`skewnessstats`.
|
|
229
|
+
|
|
230
|
+
Examples
|
|
231
|
+
--------
|
|
232
|
+
>>> obj.readTimeData('signal')
|
|
233
|
+
>>> print(obj.timedata)
|
|
234
|
+
>>> print(obj.specdata)
|
|
235
|
+
"""
|
|
76
236
|
if self.isbids:
|
|
77
|
-
dummy, dummy, columns, indata, dummy, dummy = tide_io.readbidstsv(self.filename)
|
|
237
|
+
dummy, dummy, columns, indata, dummy, dummy, dummy = tide_io.readbidstsv(self.filename)
|
|
78
238
|
try:
|
|
79
239
|
self.timedata = indata[columns.index(thename), :]
|
|
80
240
|
except ValueError:
|
|
@@ -88,11 +248,21 @@ class Timecourse:
|
|
|
88
248
|
self.timeaxis = (
|
|
89
249
|
np.linspace(0.0, self.length, num=self.length, endpoint=False) / self.samplerate
|
|
90
250
|
) - self.starttime
|
|
251
|
+
if self.limits is not None:
|
|
252
|
+
startpoint = np.max((int(np.round(self.limits[0] * self.samplerate, 0)), 0))
|
|
253
|
+
endpoint = np.min((int(np.round(self.limits[1] * self.samplerate, 0)), self.length))
|
|
254
|
+
else:
|
|
255
|
+
startpoint = 0
|
|
256
|
+
endpoint = self.length
|
|
91
257
|
self.specaxis, self.specdata = tide_filt.spectrum(
|
|
92
|
-
tide_math.corrnormalize(self.timedata), self.samplerate
|
|
258
|
+
tide_math.corrnormalize(self.timedata[startpoint:endpoint]), self.samplerate
|
|
259
|
+
)
|
|
260
|
+
self.kurtosis, self.kurtosis_z, self.kurtosis_p = tide_stats.kurtosisstats(
|
|
261
|
+
self.timedata[startpoint:endpoint]
|
|
262
|
+
)
|
|
263
|
+
self.skewness, self.skewness_z, self.skewness_p = tide_stats.skewnessstats(
|
|
264
|
+
self.timedata[startpoint:endpoint]
|
|
93
265
|
)
|
|
94
|
-
self.kurtosis, self.kurtosis_z, self.kurtosis_p = tide_stats.kurtosisstats(self.timedata)
|
|
95
|
-
self.skewness, self.skewness_z, self.skewness_p = tide_stats.skewnessstats(self.timedata)
|
|
96
266
|
|
|
97
267
|
if self.verbose > 1:
|
|
98
268
|
print("Timecourse data range:", np.min(self.timedata), np.max(self.timedata))
|
|
@@ -105,7 +275,54 @@ class Timecourse:
|
|
|
105
275
|
|
|
106
276
|
print()
|
|
107
277
|
|
|
108
|
-
def summarize(self):
|
|
278
|
+
def summarize(self) -> None:
|
|
279
|
+
"""
|
|
280
|
+
Print a summary of the timecourse properties.
|
|
281
|
+
|
|
282
|
+
This method outputs a formatted summary of various properties associated with
|
|
283
|
+
the timecourse object, including name, label, file information, sampling rate,
|
|
284
|
+
length, and statistical measures.
|
|
285
|
+
|
|
286
|
+
Parameters
|
|
287
|
+
----------
|
|
288
|
+
self : object
|
|
289
|
+
The timecourse object instance containing the properties to be summarized.
|
|
290
|
+
Expected attributes include:
|
|
291
|
+
- name: str, the name of the timecourse
|
|
292
|
+
- label: str, the label associated with the timecourse
|
|
293
|
+
- filename: str, the filename of the timecourse data
|
|
294
|
+
- namebase: str, the base name of the file
|
|
295
|
+
- samplerate: float, the sampling rate of the timecourse
|
|
296
|
+
- length: int, the length of the timecourse
|
|
297
|
+
- kurtosis: float, the kurtosis value of the timecourse
|
|
298
|
+
- kurtosis_z: float, the z-score of the kurtosis
|
|
299
|
+
- kurtosis_p: float, the p-value of the kurtosis
|
|
300
|
+
|
|
301
|
+
Returns
|
|
302
|
+
-------
|
|
303
|
+
None
|
|
304
|
+
This method prints the summary information to stdout and does not return any value.
|
|
305
|
+
|
|
306
|
+
Notes
|
|
307
|
+
-----
|
|
308
|
+
The output is formatted for readability with consistent indentation and
|
|
309
|
+
descriptive labels for each property. This method is typically used for
|
|
310
|
+
debugging and quick inspection of timecourse properties.
|
|
311
|
+
|
|
312
|
+
Examples
|
|
313
|
+
--------
|
|
314
|
+
>>> timecourse = Timecourse(name="test_signal", label="test", filename="test.csv")
|
|
315
|
+
>>> timecourse.summarize()
|
|
316
|
+
Timecourse name: test_signal
|
|
317
|
+
label: test
|
|
318
|
+
filename: test.csv
|
|
319
|
+
namebase: test
|
|
320
|
+
samplerate: 100.0
|
|
321
|
+
length: 1000
|
|
322
|
+
kurtosis: 0.5
|
|
323
|
+
kurtosis_z: 1.2
|
|
324
|
+
kurtosis_p: 0.23
|
|
325
|
+
"""
|
|
109
326
|
print()
|
|
110
327
|
print("Timecourse name: ", self.name)
|
|
111
328
|
print(" label: ", self.label)
|
|
@@ -121,23 +338,90 @@ class Timecourse:
|
|
|
121
338
|
class Overlay:
|
|
122
339
|
"Store a data overlay and some information about it"
|
|
123
340
|
|
|
341
|
+
LUTname = None
|
|
342
|
+
|
|
124
343
|
def __init__(
|
|
125
344
|
self,
|
|
126
|
-
name,
|
|
127
|
-
filespec,
|
|
128
|
-
namebase,
|
|
129
|
-
funcmask=None,
|
|
130
|
-
geommask=None,
|
|
131
|
-
label=None,
|
|
132
|
-
report=False,
|
|
133
|
-
lut_state=gen_gray_state(),
|
|
134
|
-
alpha=128,
|
|
135
|
-
endalpha=0,
|
|
136
|
-
display_state=True,
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
345
|
+
name: str,
|
|
346
|
+
filespec: str,
|
|
347
|
+
namebase: str,
|
|
348
|
+
funcmask: NDArray | None = None,
|
|
349
|
+
geommask: NDArray | None = None,
|
|
350
|
+
label: str | None = None,
|
|
351
|
+
report: bool = False,
|
|
352
|
+
lut_state: dict = gen_gray_state(),
|
|
353
|
+
alpha: int = 128,
|
|
354
|
+
endalpha: int = 0,
|
|
355
|
+
display_state: bool = True,
|
|
356
|
+
invertonload: bool = False,
|
|
357
|
+
isaMask: bool = False,
|
|
358
|
+
init_LUT: bool = True,
|
|
359
|
+
verbose: int = 1,
|
|
360
|
+
) -> None:
|
|
361
|
+
"""
|
|
362
|
+
Initialize an overlay object for rapidtide image data visualization.
|
|
363
|
+
|
|
364
|
+
This constructor initializes an overlay by loading image data from a file,
|
|
365
|
+
applying functional and geometric masks, and setting up display properties
|
|
366
|
+
including lookup tables and affine transformations.
|
|
367
|
+
|
|
368
|
+
Parameters
|
|
369
|
+
----------
|
|
370
|
+
name : str
|
|
371
|
+
Name of the overlay.
|
|
372
|
+
filespec : str
|
|
373
|
+
File specification string used to locate and load the image data.
|
|
374
|
+
namebase : str
|
|
375
|
+
Base name for the overlay, used in file naming and labeling.
|
|
376
|
+
funcmask : NDArray | None, optional
|
|
377
|
+
Functional mask to apply to the data. Default is None.
|
|
378
|
+
geommask : NDArray | None, optional
|
|
379
|
+
Geometric mask to apply to the data. Default is None.
|
|
380
|
+
label : str | None, optional
|
|
381
|
+
Label for the overlay. If None, defaults to the value of `name`. Default is None.
|
|
382
|
+
report : bool, optional
|
|
383
|
+
If True, enables reporting mode. Default is False.
|
|
384
|
+
lut_state : dict, optional
|
|
385
|
+
Lookup table state dictionary. Default is ``gen_gray_state()``.
|
|
386
|
+
alpha : int, optional
|
|
387
|
+
Initial alpha value for display. Default is 128.
|
|
388
|
+
endalpha : int, optional
|
|
389
|
+
End alpha value for display. Default is 0.
|
|
390
|
+
display_state : bool, optional
|
|
391
|
+
If True, initializes display state. Default is True.
|
|
392
|
+
invertonload : bool, optional
|
|
393
|
+
If True, inverts the data on load. Default is False.
|
|
394
|
+
isaMask : bool, optional
|
|
395
|
+
If True, treats the data as a mask. Default is False.
|
|
396
|
+
init_LUT : bool, optional
|
|
397
|
+
If True, initializes the lookup table. Default is True.
|
|
398
|
+
verbose : int, optional
|
|
399
|
+
Verbosity level. Default is 1.
|
|
400
|
+
|
|
401
|
+
Returns
|
|
402
|
+
-------
|
|
403
|
+
None
|
|
404
|
+
This method initializes the object in-place and does not return a value.
|
|
405
|
+
|
|
406
|
+
Notes
|
|
407
|
+
-----
|
|
408
|
+
The constructor performs the following steps:
|
|
409
|
+
1. Loads image data using `tide_io.processnamespec`.
|
|
410
|
+
2. Applies functional and geometric masks.
|
|
411
|
+
3. Sets up display parameters such as `dispmin` and `dispmax`.
|
|
412
|
+
4. Initializes lookup table if `init_LUT` is True.
|
|
413
|
+
5. Determines the spatial coordinate system and affine transformation matrix.
|
|
414
|
+
6. Determines the orientation (neurological or radiological) based on the affine matrix.
|
|
415
|
+
|
|
416
|
+
Examples
|
|
417
|
+
--------
|
|
418
|
+
>>> overlay = Overlay(
|
|
419
|
+
... name="my_overlay",
|
|
420
|
+
... filespec="/path/to/image.nii",
|
|
421
|
+
... namebase="overlay_base",
|
|
422
|
+
... verbose=2
|
|
423
|
+
... )
|
|
424
|
+
"""
|
|
141
425
|
self.verbose = verbose
|
|
142
426
|
self.name = name
|
|
143
427
|
if label is None:
|
|
@@ -151,6 +435,8 @@ class Overlay:
|
|
|
151
435
|
self.namebase = namebase
|
|
152
436
|
if self.verbose > 1:
|
|
153
437
|
print("reading map ", self.name, " from ", self.filename, "...")
|
|
438
|
+
self.maskhash = 0
|
|
439
|
+
self.invertonload = invertonload
|
|
154
440
|
self.readImageData(isaMask=isaMask)
|
|
155
441
|
self.mask = None
|
|
156
442
|
self.maskeddata = None
|
|
@@ -158,6 +444,8 @@ class Overlay:
|
|
|
158
444
|
self.setGeomMask(geommask, maskdata=False)
|
|
159
445
|
self.maskData()
|
|
160
446
|
self.updateStats()
|
|
447
|
+
self.dispmin = self.robustmin
|
|
448
|
+
self.dispmax = self.robustmax
|
|
161
449
|
if init_LUT:
|
|
162
450
|
self.gradient = getagradient()
|
|
163
451
|
self.lut_state = lut_state
|
|
@@ -218,7 +506,41 @@ class Overlay:
|
|
|
218
506
|
if self.verbose > 0:
|
|
219
507
|
self.summarize()
|
|
220
508
|
|
|
221
|
-
def duplicate(self, newname, newlabel):
|
|
509
|
+
def duplicate(self, newname: str, newlabel: str, init_LUT: bool = True) -> Any:
|
|
510
|
+
"""
|
|
511
|
+
Create a duplicate of the current overlay with new name and label.
|
|
512
|
+
|
|
513
|
+
Parameters
|
|
514
|
+
----------
|
|
515
|
+
newname : str
|
|
516
|
+
The name for the new overlay instance.
|
|
517
|
+
newlabel : str
|
|
518
|
+
The label for the new overlay instance.
|
|
519
|
+
init_LUT : bool, optional
|
|
520
|
+
Whether to initialize the lookup table for the new overlay.
|
|
521
|
+
Default is True.
|
|
522
|
+
|
|
523
|
+
Returns
|
|
524
|
+
-------
|
|
525
|
+
Any
|
|
526
|
+
A new Overlay instance with the specified name and label,
|
|
527
|
+
inheriting all properties from the current overlay.
|
|
528
|
+
|
|
529
|
+
Notes
|
|
530
|
+
-----
|
|
531
|
+
This method creates a shallow copy of the current overlay with
|
|
532
|
+
updated name and label attributes. The new overlay maintains
|
|
533
|
+
references to the original data files and masks.
|
|
534
|
+
|
|
535
|
+
Examples
|
|
536
|
+
--------
|
|
537
|
+
>>> overlay = Overlay("original", "file.nii", "base")
|
|
538
|
+
>>> new_overlay = overlay.duplicate("copy", "Copy Label")
|
|
539
|
+
>>> print(new_overlay.name)
|
|
540
|
+
'copy'
|
|
541
|
+
>>> print(new_overlay.label)
|
|
542
|
+
'Copy Label'
|
|
543
|
+
"""
|
|
222
544
|
return Overlay(
|
|
223
545
|
newname,
|
|
224
546
|
self.filename,
|
|
@@ -227,12 +549,45 @@ class Overlay:
|
|
|
227
549
|
geommask=self.geommask,
|
|
228
550
|
label=newlabel,
|
|
229
551
|
report=self.report,
|
|
230
|
-
init_LUT=
|
|
231
|
-
|
|
552
|
+
init_LUT=init_LUT,
|
|
553
|
+
verbose=self.verbose,
|
|
232
554
|
)
|
|
233
555
|
|
|
234
|
-
def updateStats(self):
|
|
556
|
+
def updateStats(self) -> None:
|
|
557
|
+
"""
|
|
558
|
+
Update statistical properties of the masked data.
|
|
559
|
+
|
|
560
|
+
This method calculates various statistical measures from the masked data,
|
|
561
|
+
including min/max values, quartiles, robust statistics, and histogram data.
|
|
562
|
+
The results are stored as instance attributes for later use.
|
|
563
|
+
|
|
564
|
+
Parameters
|
|
565
|
+
----------
|
|
566
|
+
None
|
|
567
|
+
|
|
568
|
+
Returns
|
|
569
|
+
-------
|
|
570
|
+
None
|
|
571
|
+
This method does not return a value but updates instance attributes
|
|
572
|
+
with statistical calculations.
|
|
573
|
+
|
|
574
|
+
Notes
|
|
575
|
+
-----
|
|
576
|
+
The method uses the mask to filter data points where mask != 0.
|
|
577
|
+
Statistical calculations include:
|
|
578
|
+
- Minimum and maximum values
|
|
579
|
+
- Robust statistics (0.02, 0.25, 0.5, 0.75, 0.98 percentiles)
|
|
580
|
+
- Histogram data with 200 bins
|
|
581
|
+
- Quartiles (25th, 50th, 75th percentiles)
|
|
582
|
+
|
|
583
|
+
Examples
|
|
584
|
+
--------
|
|
585
|
+
>>> obj.updateStats()
|
|
586
|
+
>>> print(obj.minval, obj.maxval)
|
|
587
|
+
>>> print(obj.quartiles)
|
|
588
|
+
"""
|
|
235
589
|
calcmaskeddata = self.data[np.where(self.mask != 0)]
|
|
590
|
+
|
|
236
591
|
self.minval = calcmaskeddata.min()
|
|
237
592
|
self.maxval = calcmaskeddata.max()
|
|
238
593
|
(
|
|
@@ -242,12 +597,11 @@ class Overlay:
|
|
|
242
597
|
self.pct75,
|
|
243
598
|
self.robustmax,
|
|
244
599
|
) = tide_stats.getfracvals(calcmaskeddata, [0.02, 0.25, 0.5, 0.75, 0.98], nozero=False)
|
|
245
|
-
self.dispmin = self.robustmin
|
|
246
|
-
self.dispmax = self.robustmax
|
|
247
600
|
self.histy, self.histx = np.histogram(
|
|
248
601
|
calcmaskeddata, bins=np.linspace(self.minval, self.maxval, 200)
|
|
249
602
|
)
|
|
250
603
|
self.quartiles = [self.pct25, self.pct50, self.pct75]
|
|
604
|
+
|
|
251
605
|
if self.verbose > 1:
|
|
252
606
|
print(
|
|
253
607
|
self.name,
|
|
@@ -259,17 +613,92 @@ class Overlay:
|
|
|
259
613
|
self.quartiles,
|
|
260
614
|
)
|
|
261
615
|
|
|
262
|
-
def setData(self, data, isaMask=False):
|
|
616
|
+
def setData(self, data: NDArray, isaMask: bool = False) -> None:
|
|
617
|
+
"""
|
|
618
|
+
Set the data array and optionally convert it to a binary mask.
|
|
619
|
+
|
|
620
|
+
This method assigns the provided data array to the internal data attribute
|
|
621
|
+
and optionally converts it to a binary mask where values less than 0.5
|
|
622
|
+
are set to 0.0 and values greater than 0.5 are set to 1.0.
|
|
623
|
+
|
|
624
|
+
Parameters
|
|
625
|
+
----------
|
|
626
|
+
data : NDArray
|
|
627
|
+
The input data array to be set. A copy of this array is stored internally.
|
|
628
|
+
isaMask : bool, optional
|
|
629
|
+
If True, converts the data to a binary mask. Values less than 0.5 become 0.0,
|
|
630
|
+
and values greater than 0.5 become 1.0. Default is False.
|
|
631
|
+
|
|
632
|
+
Returns
|
|
633
|
+
-------
|
|
634
|
+
None
|
|
635
|
+
This method does not return any value.
|
|
636
|
+
|
|
637
|
+
Notes
|
|
638
|
+
-----
|
|
639
|
+
The data is stored as a copy to prevent external modifications from affecting
|
|
640
|
+
the internal state. The mask conversion is performed using numpy's where function
|
|
641
|
+
for efficient element-wise operations.
|
|
642
|
+
|
|
643
|
+
Examples
|
|
644
|
+
--------
|
|
645
|
+
>>> obj.setData(np.array([0.2, 0.7, 0.3, 0.8]))
|
|
646
|
+
>>> obj.setData(np.array([0.2, 0.7, 0.3, 0.8]), isaMask=True)
|
|
647
|
+
"""
|
|
263
648
|
self.data = data.copy()
|
|
264
649
|
if isaMask:
|
|
265
650
|
self.data[np.where(self.data < 0.5)] = 0.0
|
|
266
651
|
self.data[np.where(self.data > 0.5)] = 1.0
|
|
267
652
|
self.updateStats()
|
|
268
653
|
|
|
269
|
-
def readImageData(self, isaMask=False):
|
|
654
|
+
def readImageData(self, isaMask: bool = False) -> None:
|
|
655
|
+
"""
|
|
656
|
+
Read image data from a NIfTI file and process it based on specified flags.
|
|
657
|
+
|
|
658
|
+
This function loads image data from a NIfTI file using `tide_io.readfromnifti`,
|
|
659
|
+
applies optional inversion and masking operations, and extracts dimension and
|
|
660
|
+
spacing information from the header.
|
|
661
|
+
|
|
662
|
+
Parameters
|
|
663
|
+
----------
|
|
664
|
+
isaMask : bool, optional
|
|
665
|
+
If True, process the data as a binary mask. For non-mask files, values
|
|
666
|
+
less than 0.5 are set to 0, and values greater than 0.5 are set to 1.
|
|
667
|
+
For mask files with `filevals` defined, the data is converted to a binary
|
|
668
|
+
mask based on matching values in `filevals`. Default is False.
|
|
669
|
+
|
|
670
|
+
Returns
|
|
671
|
+
-------
|
|
672
|
+
None
|
|
673
|
+
This function does not return a value but updates the instance attributes
|
|
674
|
+
`nim`, `data`, `header`, `dims`, `sizes`, `xdim`, `ydim`, `zdim`, `tdim`,
|
|
675
|
+
`xsize`, `ysize`, `zsize`, `tr`, and `toffset`.
|
|
676
|
+
|
|
677
|
+
Notes
|
|
678
|
+
-----
|
|
679
|
+
- If `invertonload` is True, the data is multiplied by -1.0.
|
|
680
|
+
- The function prints data range and header information if `verbose > 1`.
|
|
681
|
+
- Dimension and spacing information is parsed using `tide_io.parseniftidims` and
|
|
682
|
+
`tide_io.parseniftisizes`.
|
|
683
|
+
|
|
684
|
+
Examples
|
|
685
|
+
--------
|
|
686
|
+
>>> reader = ImageReader()
|
|
687
|
+
>>> reader.filename = "example.nii"
|
|
688
|
+
>>> reader.invertonload = True
|
|
689
|
+
>>> reader.verbose = 2
|
|
690
|
+
>>> reader.readImageData(isaMask=True)
|
|
691
|
+
Overlay data range: -1.0 1.0
|
|
692
|
+
header {'toffset': 0.0, ...}
|
|
693
|
+
Overlay dims: 64 64 32 1
|
|
694
|
+
Overlay sizes: 3.0 3.0 3.0 2.0
|
|
695
|
+
Overlay toffset: 0.0
|
|
696
|
+
"""
|
|
270
697
|
self.nim, self.data, self.header, self.dims, self.sizes = tide_io.readfromnifti(
|
|
271
698
|
self.filename
|
|
272
699
|
)
|
|
700
|
+
if self.invertonload:
|
|
701
|
+
self.data *= -1.0
|
|
273
702
|
if isaMask:
|
|
274
703
|
if self.filevals is None:
|
|
275
704
|
self.data[np.where(self.data < 0.5)] = 0.0
|
|
@@ -290,16 +719,97 @@ class Overlay:
|
|
|
290
719
|
print("Overlay sizes:", self.xsize, self.ysize, self.zsize, self.tr)
|
|
291
720
|
print("Overlay toffset:", self.toffset)
|
|
292
721
|
|
|
293
|
-
def setLabel(self, label):
|
|
722
|
+
def setLabel(self, label: str) -> None:
|
|
723
|
+
"""
|
|
724
|
+
Set the label for the object.
|
|
725
|
+
|
|
726
|
+
Parameters
|
|
727
|
+
----------
|
|
728
|
+
label : str
|
|
729
|
+
The label to assign to the object.
|
|
730
|
+
|
|
731
|
+
Returns
|
|
732
|
+
-------
|
|
733
|
+
None
|
|
734
|
+
This method does not return any value.
|
|
735
|
+
|
|
736
|
+
Notes
|
|
737
|
+
-----
|
|
738
|
+
This method directly assigns the provided label to the object's label attribute.
|
|
739
|
+
The label is typically used for identification or display purposes.
|
|
740
|
+
|
|
741
|
+
Examples
|
|
742
|
+
--------
|
|
743
|
+
>>> obj = MyClass()
|
|
744
|
+
>>> obj.setLabel("New Label")
|
|
745
|
+
>>> print(obj.label)
|
|
746
|
+
'New Label'
|
|
747
|
+
"""
|
|
294
748
|
self.label = label
|
|
295
749
|
|
|
296
|
-
def real2tr(self, time):
|
|
750
|
+
def real2tr(self, time: float) -> float:
|
|
751
|
+
"""
|
|
752
|
+
Convert real time to trigger time.
|
|
753
|
+
|
|
754
|
+
Convert a real time value to its corresponding trigger time value by applying
|
|
755
|
+
the time offset and trigger period parameters.
|
|
756
|
+
|
|
757
|
+
Parameters
|
|
758
|
+
----------
|
|
759
|
+
time : float
|
|
760
|
+
The real time value to be converted to trigger time.
|
|
761
|
+
|
|
762
|
+
Returns
|
|
763
|
+
-------
|
|
764
|
+
float
|
|
765
|
+
The converted trigger time value, rounded to the nearest integer.
|
|
766
|
+
|
|
767
|
+
Notes
|
|
768
|
+
-----
|
|
769
|
+
The conversion is performed using the formula: ``round((time - toffset) / tr)``
|
|
770
|
+
where ``toffset`` is the time offset and ``tr`` is the trigger period.
|
|
771
|
+
|
|
772
|
+
Examples
|
|
773
|
+
--------
|
|
774
|
+
>>> obj.real2tr(10.5)
|
|
775
|
+
2.0
|
|
776
|
+
>>> obj.real2tr(5.0)
|
|
777
|
+
0.0
|
|
778
|
+
"""
|
|
297
779
|
return np.round((time - self.toffset) / self.tr, 0)
|
|
298
780
|
|
|
299
|
-
def tr2real(self, tpos):
|
|
781
|
+
def tr2real(self, tpos: int) -> float:
|
|
300
782
|
return self.toffset + self.tr * tpos
|
|
301
783
|
|
|
302
|
-
def real2vox(
|
|
784
|
+
def real2vox(
|
|
785
|
+
self, xcoord: float, ycoord: float, zcoord: float, time: float
|
|
786
|
+
) -> tuple[int, int, int, int]:
|
|
787
|
+
"""
|
|
788
|
+
Convert a time position to a real time value.
|
|
789
|
+
|
|
790
|
+
Parameters
|
|
791
|
+
----------
|
|
792
|
+
tpos : int
|
|
793
|
+
Time position index to convert to real time value.
|
|
794
|
+
|
|
795
|
+
Returns
|
|
796
|
+
-------
|
|
797
|
+
float
|
|
798
|
+
The corresponding real time value calculated as `toffset + tr * tpos`.
|
|
799
|
+
|
|
800
|
+
Notes
|
|
801
|
+
-----
|
|
802
|
+
This function performs a linear transformation from discrete time positions
|
|
803
|
+
to continuous time values using the instance's time offset and time rate
|
|
804
|
+
parameters.
|
|
805
|
+
|
|
806
|
+
Examples
|
|
807
|
+
--------
|
|
808
|
+
>>> obj.tr2real(0)
|
|
809
|
+
10.0
|
|
810
|
+
>>> obj.tr2real(5)
|
|
811
|
+
15.0
|
|
812
|
+
"""
|
|
303
813
|
x, y, z = nib.apply_affine(self.invaffine, [xcoord, ycoord, zcoord])
|
|
304
814
|
t = self.real2tr(time)
|
|
305
815
|
return (
|
|
@@ -309,30 +819,183 @@ class Overlay:
|
|
|
309
819
|
int(np.round(t, 0)),
|
|
310
820
|
)
|
|
311
821
|
|
|
312
|
-
def vox2real(self, xpos, ypos, zpos, tpos):
|
|
822
|
+
def vox2real(self, xpos: int, ypos: int, zpos: int, tpos: int) -> NDArray:
|
|
823
|
+
"""
|
|
824
|
+
Convert voxel coordinates to real-world coordinates.
|
|
825
|
+
|
|
826
|
+
This function transforms voxel coordinates (x, y, z, t) to real-world coordinates
|
|
827
|
+
using the affine transformation matrix and temporal transformation.
|
|
828
|
+
|
|
829
|
+
Parameters
|
|
830
|
+
----------
|
|
831
|
+
xpos : int
|
|
832
|
+
X coordinate in voxel space
|
|
833
|
+
ypos : int
|
|
834
|
+
Y coordinate in voxel space
|
|
835
|
+
zpos : int
|
|
836
|
+
Z coordinate in voxel space
|
|
837
|
+
tpos : int
|
|
838
|
+
T coordinate in voxel space (temporal dimension)
|
|
839
|
+
|
|
840
|
+
Returns
|
|
841
|
+
-------
|
|
842
|
+
NDArray
|
|
843
|
+
Array containing real-world coordinates [x_real, y_real, z_real, t_real]
|
|
844
|
+
|
|
845
|
+
Notes
|
|
846
|
+
-----
|
|
847
|
+
The conversion uses nibabel's apply_affine function for spatial transformation
|
|
848
|
+
and self.tr2real for temporal transformation. The result includes both
|
|
849
|
+
spatial and temporal coordinates in real-world units.
|
|
850
|
+
|
|
851
|
+
Examples
|
|
852
|
+
--------
|
|
853
|
+
>>> vox2real(10, 20, 30, 5)
|
|
854
|
+
array([12.5, 25.0, 37.5, 2.5])
|
|
855
|
+
"""
|
|
313
856
|
return np.concatenate(
|
|
314
857
|
(nib.apply_affine(self.affine, [xpos, ypos, zpos]), [self.tr2real(tpos)]),
|
|
315
858
|
axis=0,
|
|
316
859
|
)
|
|
317
860
|
|
|
318
|
-
def setXYZpos(self, xpos, ypos, zpos):
|
|
861
|
+
def setXYZpos(self, xpos: int, ypos: int, zpos: int) -> None:
|
|
862
|
+
"""
|
|
863
|
+
Set the 3D position coordinates of the object.
|
|
864
|
+
|
|
865
|
+
Parameters
|
|
866
|
+
----------
|
|
867
|
+
xpos : int
|
|
868
|
+
The x-coordinate position value.
|
|
869
|
+
ypos : int
|
|
870
|
+
The y-coordinate position value.
|
|
871
|
+
zpos : int
|
|
872
|
+
The z-coordinate position value.
|
|
873
|
+
|
|
874
|
+
Returns
|
|
875
|
+
-------
|
|
876
|
+
None
|
|
877
|
+
This method does not return any value.
|
|
878
|
+
|
|
879
|
+
Notes
|
|
880
|
+
-----
|
|
881
|
+
All position values are converted to integers before assignment.
|
|
882
|
+
|
|
883
|
+
Examples
|
|
884
|
+
--------
|
|
885
|
+
>>> obj = MyClass()
|
|
886
|
+
>>> obj.setXYZpos(10, 20, 30)
|
|
887
|
+
>>> print(obj.xpos, obj.ypos, obj.zpos)
|
|
888
|
+
10 20 30
|
|
889
|
+
"""
|
|
319
890
|
self.xpos = int(xpos)
|
|
320
891
|
self.ypos = int(ypos)
|
|
321
892
|
self.zpos = int(zpos)
|
|
322
893
|
|
|
323
|
-
def setTpos(self, tpos):
|
|
894
|
+
def setTpos(self, tpos: int) -> None:
|
|
895
|
+
"""
|
|
896
|
+
Set the temporal position attribute with bounds checking.
|
|
897
|
+
|
|
898
|
+
Parameters
|
|
899
|
+
----------
|
|
900
|
+
tpos : int
|
|
901
|
+
The temporal position to set. If greater than self.tdim - 1,
|
|
902
|
+
it will be clamped to self.tdim - 1.
|
|
903
|
+
|
|
904
|
+
Returns
|
|
905
|
+
-------
|
|
906
|
+
None
|
|
907
|
+
This method modifies the instance in-place and does not return a value.
|
|
908
|
+
|
|
909
|
+
Notes
|
|
910
|
+
-----
|
|
911
|
+
The temporal position is bounded by the dimensionality of the temporal
|
|
912
|
+
space (self.tdim). If the input tpos exceeds this limit, it will be
|
|
913
|
+
automatically adjusted to the maximum valid position (self.tdim - 1).
|
|
914
|
+
|
|
915
|
+
Examples
|
|
916
|
+
--------
|
|
917
|
+
>>> obj = MyClass()
|
|
918
|
+
>>> obj.tdim = 5
|
|
919
|
+
>>> obj.setTpos(3)
|
|
920
|
+
>>> obj.tpos
|
|
921
|
+
3
|
|
922
|
+
>>> obj.setTpos(10)
|
|
923
|
+
>>> obj.tpos
|
|
924
|
+
4
|
|
925
|
+
"""
|
|
324
926
|
if tpos > self.tdim - 1:
|
|
325
927
|
self.tpos = int(self.tdim - 1)
|
|
326
928
|
else:
|
|
327
929
|
self.tpos = int(tpos)
|
|
328
930
|
|
|
329
|
-
def getFocusVal(self):
|
|
931
|
+
def getFocusVal(self) -> float:
|
|
932
|
+
"""
|
|
933
|
+
Get the focus value at the current position.
|
|
934
|
+
|
|
935
|
+
This method retrieves the data value from the masked data array at the
|
|
936
|
+
current position coordinates. The method handles both 3D and 4D data arrays
|
|
937
|
+
by checking the time dimension.
|
|
938
|
+
|
|
939
|
+
Parameters
|
|
940
|
+
----------
|
|
941
|
+
self : object
|
|
942
|
+
The instance of the class containing the masked data and position
|
|
943
|
+
coordinates.
|
|
944
|
+
|
|
945
|
+
Returns
|
|
946
|
+
-------
|
|
947
|
+
float
|
|
948
|
+
The data value at the current position. For 4D data (tdim > 1), returns
|
|
949
|
+
the value at [xpos, ypos, zpos, tpos]. For 3D data (tdim <= 1), returns
|
|
950
|
+
the value at [xpos, ypos, zpos].
|
|
951
|
+
|
|
952
|
+
Notes
|
|
953
|
+
-----
|
|
954
|
+
The method assumes that the instance has the following attributes:
|
|
955
|
+
- maskeddata: numpy array containing the data
|
|
956
|
+
- xpos, ypos, zpos, tpos: integer coordinates
|
|
957
|
+
- tdim: integer representing the time dimension
|
|
958
|
+
|
|
959
|
+
Examples
|
|
960
|
+
--------
|
|
961
|
+
>>> value = obj.getFocusVal()
|
|
962
|
+
>>> print(value)
|
|
963
|
+
0.5
|
|
964
|
+
"""
|
|
330
965
|
if self.tdim > 1:
|
|
331
966
|
return self.maskeddata[self.xpos, self.ypos, self.zpos, self.tpos]
|
|
332
967
|
else:
|
|
333
968
|
return self.maskeddata[self.xpos, self.ypos, self.zpos]
|
|
334
969
|
|
|
335
|
-
def setFuncMask(self, funcmask, maskdata=True):
|
|
970
|
+
def setFuncMask(self, funcmask: NDArray | None, maskdata: bool = True) -> None:
|
|
971
|
+
"""
|
|
972
|
+
Set the functional mask for the object.
|
|
973
|
+
|
|
974
|
+
Parameters
|
|
975
|
+
----------
|
|
976
|
+
funcmask : array-like, optional
|
|
977
|
+
The functional mask to be set. If None, a default mask is created based on
|
|
978
|
+
the dimensionality of the data. If provided, a copy of the mask is stored.
|
|
979
|
+
maskdata : bool, default=True
|
|
980
|
+
If True, calls maskData() method after setting the functional mask.
|
|
981
|
+
|
|
982
|
+
Returns
|
|
983
|
+
-------
|
|
984
|
+
None
|
|
985
|
+
This method modifies the object in-place and does not return any value.
|
|
986
|
+
|
|
987
|
+
Notes
|
|
988
|
+
-----
|
|
989
|
+
When funcmask is None, the method creates a default mask:
|
|
990
|
+
- For 1D data (tdim == 1): creates a mask with the same shape as self.data
|
|
991
|
+
- For higher dimensional data: creates a mask with shape (self.data.shape[0], self.data.shape[1], self.data.shape[2], 1)
|
|
992
|
+
|
|
993
|
+
Examples
|
|
994
|
+
--------
|
|
995
|
+
>>> obj.setFuncMask(None)
|
|
996
|
+
>>> obj.setFuncMask(np.ones((10, 10)))
|
|
997
|
+
>>> obj.setFuncMask(None, maskdata=False)
|
|
998
|
+
"""
|
|
336
999
|
self.funcmask = funcmask
|
|
337
1000
|
if self.funcmask is None:
|
|
338
1001
|
if self.tdim == 1:
|
|
@@ -344,7 +1007,35 @@ class Overlay:
|
|
|
344
1007
|
if maskdata:
|
|
345
1008
|
self.maskData()
|
|
346
1009
|
|
|
347
|
-
def setGeomMask(self, geommask, maskdata=True):
|
|
1010
|
+
def setGeomMask(self, geommask: NDArray | None, maskdata: bool = True) -> None:
|
|
1011
|
+
"""
|
|
1012
|
+
Set the geometric mask for the object and optionally mask the data.
|
|
1013
|
+
|
|
1014
|
+
Parameters
|
|
1015
|
+
----------
|
|
1016
|
+
geommask : ndarray or None
|
|
1017
|
+
Geometric mask array. If None, a default mask is created based on the
|
|
1018
|
+
object's dimensions. If not None, the provided mask is copied and used.
|
|
1019
|
+
maskdata : bool, default=True
|
|
1020
|
+
If True, applies the mask to the data by calling maskData() method.
|
|
1021
|
+
If False, only sets the geometric mask without masking the data.
|
|
1022
|
+
|
|
1023
|
+
Returns
|
|
1024
|
+
-------
|
|
1025
|
+
None
|
|
1026
|
+
This method modifies the object in-place and does not return any value.
|
|
1027
|
+
|
|
1028
|
+
Notes
|
|
1029
|
+
-----
|
|
1030
|
+
When geommask is None and tdim == 1, a mask of ones with the same shape as
|
|
1031
|
+
self.data is created. Otherwise, a mask of ones with the shape of
|
|
1032
|
+
self.data[:, :, :, 0] is created.
|
|
1033
|
+
|
|
1034
|
+
Examples
|
|
1035
|
+
--------
|
|
1036
|
+
>>> obj.setGeomMask(None)
|
|
1037
|
+
>>> obj.setGeomMask(mask_array, maskdata=False)
|
|
1038
|
+
"""
|
|
348
1039
|
self.geommask = geommask
|
|
349
1040
|
if self.geommask is None:
|
|
350
1041
|
if self.tdim == 1:
|
|
@@ -356,22 +1047,180 @@ class Overlay:
|
|
|
356
1047
|
if maskdata:
|
|
357
1048
|
self.maskData()
|
|
358
1049
|
|
|
359
|
-
def maskData(self):
|
|
1050
|
+
def maskData(self) -> None:
|
|
1051
|
+
"""
|
|
1052
|
+
Apply mask to data and update statistics if mask has changed.
|
|
1053
|
+
|
|
1054
|
+
This method combines geometric and functional masks to create a final mask,
|
|
1055
|
+
then checks if the mask has changed since the last update. If the mask has
|
|
1056
|
+
changed, it applies the mask to the data, sets masked values to zero, and
|
|
1057
|
+
updates the statistics.
|
|
1058
|
+
|
|
1059
|
+
Parameters
|
|
1060
|
+
----------
|
|
1061
|
+
None
|
|
1062
|
+
|
|
1063
|
+
Returns
|
|
1064
|
+
-------
|
|
1065
|
+
None
|
|
1066
|
+
This method modifies the instance in-place and does not return any value.
|
|
1067
|
+
|
|
1068
|
+
Notes
|
|
1069
|
+
-----
|
|
1070
|
+
The method uses a hash-based approach to efficiently detect when the mask
|
|
1071
|
+
has changed, avoiding expensive operations when the mask remains the same.
|
|
1072
|
+
The mask is applied by setting values to zero where the combined mask is
|
|
1073
|
+
less than 0.5.
|
|
1074
|
+
|
|
1075
|
+
Examples
|
|
1076
|
+
--------
|
|
1077
|
+
>>> obj.maskData()
|
|
1078
|
+
# Applies mask and updates statistics if mask has changed
|
|
1079
|
+
"""
|
|
360
1080
|
self.mask = self.geommask * self.funcmask
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
self.
|
|
364
|
-
|
|
365
|
-
|
|
1081
|
+
maskhash = hash(self.mask.tobytes())
|
|
1082
|
+
# these operations are expensive, so only do them if the mask is changed
|
|
1083
|
+
if (maskhash == self.maskhash) and (self.verbose > 1):
|
|
1084
|
+
print("mask has not changed")
|
|
1085
|
+
else:
|
|
1086
|
+
if self.verbose > 1:
|
|
1087
|
+
print("mask changed - recalculating")
|
|
1088
|
+
self.maskeddata = self.data.copy()
|
|
1089
|
+
self.maskeddata[np.where(self.mask < 0.5)] = 0.0
|
|
1090
|
+
self.updateStats()
|
|
1091
|
+
self.maskhash = maskhash
|
|
1092
|
+
|
|
1093
|
+
def setReport(self, report: bool) -> None:
|
|
1094
|
+
"""
|
|
1095
|
+
Set the report flag for the object.
|
|
1096
|
+
|
|
1097
|
+
Parameters
|
|
1098
|
+
----------
|
|
1099
|
+
report : bool
|
|
1100
|
+
Flag indicating whether reporting is enabled or disabled.
|
|
1101
|
+
|
|
1102
|
+
Returns
|
|
1103
|
+
-------
|
|
1104
|
+
None
|
|
1105
|
+
This method does not return any value.
|
|
1106
|
+
|
|
1107
|
+
Notes
|
|
1108
|
+
-----
|
|
1109
|
+
This method assigns the provided boolean value to the internal `report` attribute
|
|
1110
|
+
of the object. The attribute can be accessed later to check the current reporting state.
|
|
1111
|
+
|
|
1112
|
+
Examples
|
|
1113
|
+
--------
|
|
1114
|
+
>>> obj = MyClass()
|
|
1115
|
+
>>> obj.setReport(True)
|
|
1116
|
+
>>> obj.report
|
|
1117
|
+
True
|
|
1118
|
+
>>> obj.setReport(False)
|
|
1119
|
+
>>> obj.report
|
|
1120
|
+
False
|
|
1121
|
+
"""
|
|
366
1122
|
self.report = report
|
|
367
1123
|
|
|
368
|
-
def setTR(self, trval):
|
|
1124
|
+
def setTR(self, trval: float) -> None:
|
|
1125
|
+
"""
|
|
1126
|
+
Set the TR (repetition time) value for the object.
|
|
1127
|
+
|
|
1128
|
+
Parameters
|
|
1129
|
+
----------
|
|
1130
|
+
trval : float
|
|
1131
|
+
The repetition time value to be set. This parameter represents the
|
|
1132
|
+
time interval between successive MRI pulse sequences in seconds.
|
|
1133
|
+
|
|
1134
|
+
Returns
|
|
1135
|
+
-------
|
|
1136
|
+
None
|
|
1137
|
+
This method does not return any value.
|
|
1138
|
+
|
|
1139
|
+
Notes
|
|
1140
|
+
-----
|
|
1141
|
+
This method directly assigns the provided value to the internal `tr` attribute
|
|
1142
|
+
of the object. The TR value is commonly used in MRI data processing and
|
|
1143
|
+
represents the time between the start of one pulse sequence and the start
|
|
1144
|
+
of the next.
|
|
1145
|
+
|
|
1146
|
+
Examples
|
|
1147
|
+
--------
|
|
1148
|
+
>>> obj = MyClass()
|
|
1149
|
+
>>> obj.setTR(2.0)
|
|
1150
|
+
>>> print(obj.tr)
|
|
1151
|
+
2.0
|
|
1152
|
+
"""
|
|
369
1153
|
self.tr = trval
|
|
370
1154
|
|
|
371
|
-
def settoffset(self, toffset):
|
|
1155
|
+
def settoffset(self, toffset: float) -> None:
|
|
1156
|
+
"""
|
|
1157
|
+
Set the time offset value.
|
|
1158
|
+
|
|
1159
|
+
Parameters
|
|
1160
|
+
----------
|
|
1161
|
+
toffset : float
|
|
1162
|
+
The time offset value to set.
|
|
1163
|
+
|
|
1164
|
+
Returns
|
|
1165
|
+
-------
|
|
1166
|
+
None
|
|
1167
|
+
This method does not return any value.
|
|
1168
|
+
|
|
1169
|
+
Notes
|
|
1170
|
+
-----
|
|
1171
|
+
This method assigns the provided time offset value to the instance variable
|
|
1172
|
+
`self.toffset`. The time offset is typically used to adjust timing references
|
|
1173
|
+
in time-series data processing or temporal calculations.
|
|
1174
|
+
|
|
1175
|
+
Examples
|
|
1176
|
+
--------
|
|
1177
|
+
>>> obj = MyClass()
|
|
1178
|
+
>>> obj.settoffset(5.0)
|
|
1179
|
+
>>> print(obj.toffset)
|
|
1180
|
+
5.0
|
|
1181
|
+
"""
|
|
372
1182
|
self.toffset = toffset
|
|
373
1183
|
|
|
374
|
-
def setLUT(self, lut_state, alpha=255, endalpha=128):
|
|
1184
|
+
def setLUT(self, lut_state: dict, alpha: int = 255, endalpha: int = 128) -> None:
|
|
1185
|
+
"""
|
|
1186
|
+
Set the lookup table (LUT) state with optional alpha blending adjustments.
|
|
1187
|
+
|
|
1188
|
+
This function configures the lookup table state for gradient visualization,
|
|
1189
|
+
applying alpha transparency adjustments to the color ticks and restoring
|
|
1190
|
+
the gradient state with the updated LUT.
|
|
1191
|
+
|
|
1192
|
+
Parameters
|
|
1193
|
+
----------
|
|
1194
|
+
lut_state : dict
|
|
1195
|
+
Dictionary containing the lookup table state with keys:
|
|
1196
|
+
- "ticks": list of tuples representing color stops
|
|
1197
|
+
- "mode": color mapping mode
|
|
1198
|
+
- "name": name of the LUT
|
|
1199
|
+
alpha : int, optional
|
|
1200
|
+
Alpha value (0-255) to apply to intermediate color ticks, by default 255
|
|
1201
|
+
endalpha : int, optional
|
|
1202
|
+
Alpha value (0-255) to apply to the end color ticks, by default 128
|
|
1203
|
+
|
|
1204
|
+
Returns
|
|
1205
|
+
-------
|
|
1206
|
+
None
|
|
1207
|
+
This function modifies the instance state in-place and does not return anything.
|
|
1208
|
+
|
|
1209
|
+
Notes
|
|
1210
|
+
-----
|
|
1211
|
+
The function applies alpha blending to intermediate color ticks while preserving
|
|
1212
|
+
the original alpha values of the first and last ticks. When verbose mode is enabled
|
|
1213
|
+
(verbose > 1), the modified tick values are printed to the console.
|
|
1214
|
+
|
|
1215
|
+
Examples
|
|
1216
|
+
--------
|
|
1217
|
+
>>> lut_state = {
|
|
1218
|
+
... "ticks": [(0, (0, 0, 0, 255)), (128, (128, 128, 128, 255)), (255, (255, 255, 255, 255))],
|
|
1219
|
+
... "mode": "RGB",
|
|
1220
|
+
... "name": "grayscale"
|
|
1221
|
+
... }
|
|
1222
|
+
>>> setLUT(lut_state, alpha=128, endalpha=64)
|
|
1223
|
+
"""
|
|
375
1224
|
if alpha is not None:
|
|
376
1225
|
theticks = [lut_state["ticks"][0]]
|
|
377
1226
|
for theelement in lut_state["ticks"][1:-1]:
|
|
@@ -389,11 +1238,82 @@ class Overlay:
|
|
|
389
1238
|
self.lut_state = setendalpha(lut_state, endalpha)
|
|
390
1239
|
self.gradient.restoreState(self.lut_state)
|
|
391
1240
|
self.theLUT = self.gradient.getLookupTable(512, alpha=True)
|
|
392
|
-
|
|
393
|
-
|
|
1241
|
+
self.LUTname = lut_state["name"]
|
|
1242
|
+
|
|
1243
|
+
def setisdisplayed(self, display_state: bool) -> None:
|
|
1244
|
+
"""
|
|
1245
|
+
Set the display state of the object.
|
|
1246
|
+
|
|
1247
|
+
Parameters
|
|
1248
|
+
----------
|
|
1249
|
+
display_state : bool
|
|
1250
|
+
The display state to set. True indicates the object should be displayed,
|
|
1251
|
+
False indicates it should be hidden.
|
|
1252
|
+
|
|
1253
|
+
Returns
|
|
1254
|
+
-------
|
|
1255
|
+
None
|
|
1256
|
+
This method does not return any value.
|
|
1257
|
+
|
|
1258
|
+
Notes
|
|
1259
|
+
-----
|
|
1260
|
+
This method directly assigns the provided display state to the internal
|
|
1261
|
+
`display_state` attribute of the object. The display state controls whether
|
|
1262
|
+
the object is visible in the user interface or not.
|
|
1263
|
+
|
|
1264
|
+
Examples
|
|
1265
|
+
--------
|
|
1266
|
+
>>> obj = MyClass()
|
|
1267
|
+
>>> obj.setisdisplayed(True)
|
|
1268
|
+
>>> print(obj.display_state)
|
|
1269
|
+
True
|
|
1270
|
+
>>> obj.setisdisplayed(False)
|
|
1271
|
+
>>> print(obj.display_state)
|
|
1272
|
+
False
|
|
1273
|
+
"""
|
|
394
1274
|
self.display_state = display_state
|
|
395
1275
|
|
|
396
|
-
def summarize(self):
|
|
1276
|
+
def summarize(self) -> None:
|
|
1277
|
+
"""
|
|
1278
|
+
Print a summary of the overlay's properties and metadata.
|
|
1279
|
+
|
|
1280
|
+
This method outputs a formatted summary of the overlay's key attributes,
|
|
1281
|
+
including name, label, file information, dimensions, orientation, and
|
|
1282
|
+
data statistics. It also indicates whether geometric and functional masks
|
|
1283
|
+
are set.
|
|
1284
|
+
|
|
1285
|
+
Notes
|
|
1286
|
+
-----
|
|
1287
|
+
The output is printed directly to the console and does not return any value.
|
|
1288
|
+
This method is intended for debugging or inspection purposes.
|
|
1289
|
+
|
|
1290
|
+
Examples
|
|
1291
|
+
--------
|
|
1292
|
+
>>> overlay = Overlay(...)
|
|
1293
|
+
>>> overlay.summarize()
|
|
1294
|
+
Overlay name: my_overlay
|
|
1295
|
+
label: My Overlay
|
|
1296
|
+
filename: /path/to/my_overlay.nii
|
|
1297
|
+
namebase: my_overlay
|
|
1298
|
+
xdim: 64
|
|
1299
|
+
ydim: 64
|
|
1300
|
+
zdim: 32
|
|
1301
|
+
tdim: 100
|
|
1302
|
+
space: MNI
|
|
1303
|
+
orientation: radiological
|
|
1304
|
+
toffset: 0.0
|
|
1305
|
+
tr: 2.0
|
|
1306
|
+
min: -1.5
|
|
1307
|
+
max: 2.0
|
|
1308
|
+
robustmin: -1.0
|
|
1309
|
+
robustmax: 1.5
|
|
1310
|
+
dispmin: -1.5
|
|
1311
|
+
dispmax: 2.0
|
|
1312
|
+
data shape: (64, 64, 32, 100)
|
|
1313
|
+
masked data shape: (64, 64, 32, 100)
|
|
1314
|
+
geometric mask is set
|
|
1315
|
+
functional mask not set
|
|
1316
|
+
"""
|
|
397
1317
|
print()
|
|
398
1318
|
print("Overlay name: ", self.name)
|
|
399
1319
|
print(" label: ", self.label)
|
|
@@ -432,6 +1352,8 @@ class Overlay:
|
|
|
432
1352
|
|
|
433
1353
|
class RapidtideDataset:
|
|
434
1354
|
"Store all the data associated with a rapidtide dataset"
|
|
1355
|
+
|
|
1356
|
+
fileroot = None
|
|
435
1357
|
focusregressor = None
|
|
436
1358
|
regressorfilterlimits = None
|
|
437
1359
|
regressorsimcalclimits = None
|
|
@@ -451,31 +1373,100 @@ class RapidtideDataset:
|
|
|
451
1373
|
ysize = 0.0
|
|
452
1374
|
zsize = 0.0
|
|
453
1375
|
tr = 0.0
|
|
1376
|
+
space = None
|
|
1377
|
+
affine = None
|
|
454
1378
|
|
|
455
1379
|
def __init__(
|
|
456
1380
|
self,
|
|
457
|
-
name,
|
|
458
|
-
fileroot,
|
|
459
|
-
anatname=None,
|
|
460
|
-
geommaskname=None,
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
1381
|
+
name: str,
|
|
1382
|
+
fileroot: str,
|
|
1383
|
+
anatname: str | None = None,
|
|
1384
|
+
geommaskname: str | None = None,
|
|
1385
|
+
funcmaskname: str | None = None,
|
|
1386
|
+
graymaskspec: str | None = None,
|
|
1387
|
+
whitemaskspec: str | None = None,
|
|
1388
|
+
userise: bool = False,
|
|
1389
|
+
usecorrout: bool = False,
|
|
1390
|
+
useatlas: bool = False,
|
|
1391
|
+
minimal: bool = False,
|
|
1392
|
+
forcetr: bool = False,
|
|
1393
|
+
forceoffset: bool = False,
|
|
1394
|
+
coordinatespace: str = "unspecified",
|
|
1395
|
+
offsettime: float = 0.0,
|
|
1396
|
+
init_LUT: bool = True,
|
|
1397
|
+
verbose: int = 0,
|
|
1398
|
+
) -> None:
|
|
1399
|
+
"""
|
|
1400
|
+
Initialize a RapidtideDataset object for processing neuroimaging data.
|
|
1401
|
+
|
|
1402
|
+
This constructor sets up the dataset configuration based on provided parameters,
|
|
1403
|
+
determines the naming convention used by the dataset (BIDS or legacy), and
|
|
1404
|
+
initializes internal structures for regressor and overlay handling.
|
|
1405
|
+
|
|
1406
|
+
Parameters
|
|
1407
|
+
----------
|
|
1408
|
+
name : str
|
|
1409
|
+
Name of the dataset.
|
|
1410
|
+
fileroot : str
|
|
1411
|
+
Root path to the dataset files.
|
|
1412
|
+
anatname : str, optional
|
|
1413
|
+
Path to the anatomical image file. Default is None.
|
|
1414
|
+
geommaskname : str, optional
|
|
1415
|
+
Path to the geometric mask file. Default is None.
|
|
1416
|
+
funcmaskname : str, optional
|
|
1417
|
+
Path to the functional mask file. Default is None.
|
|
1418
|
+
graymaskspec : str, optional
|
|
1419
|
+
Specification for gray matter mask. Default is None.
|
|
1420
|
+
whitemaskspec : str, optional
|
|
1421
|
+
Specification for white matter mask. Default is None.
|
|
1422
|
+
userise : bool, optional
|
|
1423
|
+
Whether to use RISE (reconstruction of instantaneous signal estimates). Default is False.
|
|
1424
|
+
usecorrout : bool, optional
|
|
1425
|
+
Whether to use corrected output. Default is False.
|
|
1426
|
+
useatlas : bool, optional
|
|
1427
|
+
Whether to use atlas-based processing. Default is False.
|
|
1428
|
+
minimal : bool, optional
|
|
1429
|
+
Whether to run in minimal mode. Default is False.
|
|
1430
|
+
forcetr : bool, optional
|
|
1431
|
+
Whether to force TR (repetition time) correction. Default is False.
|
|
1432
|
+
forceoffset : bool, optional
|
|
1433
|
+
Whether to force offset correction. Default is False.
|
|
1434
|
+
coordinatespace : str, optional
|
|
1435
|
+
Coordinate space of the data. Default is "unspecified".
|
|
1436
|
+
offsettime : float, optional
|
|
1437
|
+
Time offset to apply. Default is 0.0.
|
|
1438
|
+
init_LUT : bool, optional
|
|
1439
|
+
Whether to initialize lookup tables. Default is True.
|
|
1440
|
+
verbose : int, optional
|
|
1441
|
+
Verbosity level. Default is 0.
|
|
1442
|
+
|
|
1443
|
+
Returns
|
|
1444
|
+
-------
|
|
1445
|
+
None
|
|
1446
|
+
This method initializes the object and does not return any value.
|
|
1447
|
+
|
|
1448
|
+
Notes
|
|
1449
|
+
-----
|
|
1450
|
+
The function automatically detects whether the dataset uses BIDS-style naming
|
|
1451
|
+
conventions by checking for the presence of specific files like
|
|
1452
|
+
``<fileroot>desc-maxtime_map.nii.gz``. If not found, it checks for legacy naming
|
|
1453
|
+
patterns such as ``<fileroot>fitmask.nii.gz``.
|
|
1454
|
+
|
|
1455
|
+
Examples
|
|
1456
|
+
--------
|
|
1457
|
+
>>> dataset = RapidtideDataset(
|
|
1458
|
+
... name="test_dataset",
|
|
1459
|
+
... fileroot="/path/to/data",
|
|
1460
|
+
... anatname="/path/to/anat.nii.gz",
|
|
1461
|
+
... verbose=1
|
|
1462
|
+
... )
|
|
1463
|
+
"""
|
|
474
1464
|
self.verbose = verbose
|
|
475
1465
|
self.name = name
|
|
476
1466
|
self.fileroot = fileroot
|
|
477
1467
|
self.anatname = anatname
|
|
478
1468
|
self.geommaskname = geommaskname
|
|
1469
|
+
self.funcmaskname = funcmaskname
|
|
479
1470
|
self.graymaskspec = graymaskspec
|
|
480
1471
|
self.whitemaskspec = whitemaskspec
|
|
481
1472
|
self.userise = userise
|
|
@@ -509,7 +1500,47 @@ class RapidtideDataset:
|
|
|
509
1500
|
self.setupregressors()
|
|
510
1501
|
self.setupoverlays()
|
|
511
1502
|
|
|
512
|
-
def _loadregressors(self):
|
|
1503
|
+
def _loadregressors(self) -> None:
|
|
1504
|
+
"""
|
|
1505
|
+
Load regressor timecourses from specified files.
|
|
1506
|
+
|
|
1507
|
+
This method iterates through the list of regressor specifications (`self.regressorspecs`)
|
|
1508
|
+
and attempts to load each regressor from the corresponding file. If a file exists, it is
|
|
1509
|
+
read into a `Timecourse` object and stored in `self.regressors`. If no regressor is
|
|
1510
|
+
successfully loaded, the first one in the list is set as the focus regressor.
|
|
1511
|
+
|
|
1512
|
+
Parameters
|
|
1513
|
+
----------
|
|
1514
|
+
self : object
|
|
1515
|
+
The instance of the class containing the method. Expected to have the following
|
|
1516
|
+
attributes:
|
|
1517
|
+
- `regressorspecs`: list of tuples specifying regressor files and parameters.
|
|
1518
|
+
- `fileroot`: string, base path for regressor files.
|
|
1519
|
+
- `regressors`: dict, to store loaded regressors.
|
|
1520
|
+
- `focusregressor`: str, name of the currently focused regressor.
|
|
1521
|
+
- `verbose`: int, level of verbosity for logging.
|
|
1522
|
+
- `bidsformat`: bool, flag indicating BIDS format usage.
|
|
1523
|
+
- `regressorsimcalclimits`: tuple, limits for regressor calculation.
|
|
1524
|
+
- `isbids`: bool, flag indicating BIDS format usage (likely a typo for `bidsformat`).
|
|
1525
|
+
|
|
1526
|
+
Returns
|
|
1527
|
+
-------
|
|
1528
|
+
None
|
|
1529
|
+
This method modifies the instance's attributes in place and does not return any value.
|
|
1530
|
+
|
|
1531
|
+
Notes
|
|
1532
|
+
-----
|
|
1533
|
+
- If a regressor file does not exist and the corresponding flag in `regressorspecs` is True,
|
|
1534
|
+
a `FileNotFoundError` is raised.
|
|
1535
|
+
- If a regressor file does not exist and the flag is False, the file is skipped with a message.
|
|
1536
|
+
- The first successfully loaded regressor is set as the `focusregressor` if none is already set.
|
|
1537
|
+
|
|
1538
|
+
Examples
|
|
1539
|
+
--------
|
|
1540
|
+
>>> loader = MyLoader()
|
|
1541
|
+
>>> loader._loadregressors()
|
|
1542
|
+
# Loads regressors specified in `loader.regressorspecs` into `loader.regressors`.
|
|
1543
|
+
"""
|
|
513
1544
|
self.focusregressor = None
|
|
514
1545
|
for thisregressor in self.regressorspecs:
|
|
515
1546
|
if os.path.isfile(self.fileroot + thisregressor[2]):
|
|
@@ -525,6 +1556,7 @@ class RapidtideDataset:
|
|
|
525
1556
|
label=thisregressor[1],
|
|
526
1557
|
starttime=thisregressor[5],
|
|
527
1558
|
isbids=self.bidsformat,
|
|
1559
|
+
limits=self.regressorsimcalclimits,
|
|
528
1560
|
verbose=self.verbose,
|
|
529
1561
|
)
|
|
530
1562
|
if theregressor.timedata is not None:
|
|
@@ -534,14 +1566,59 @@ class RapidtideDataset:
|
|
|
534
1566
|
if self.focusregressor is None:
|
|
535
1567
|
self.focusregressor = thisregressor[0]
|
|
536
1568
|
else:
|
|
537
|
-
if
|
|
538
|
-
|
|
539
|
-
"file
|
|
540
|
-
self.fileroot + thisregressor[2],
|
|
541
|
-
" does not exist - skipping...",
|
|
1569
|
+
if thisregressor[6]:
|
|
1570
|
+
raise FileNotFoundError(
|
|
1571
|
+
f"regressor file {self.fileroot + thisregressor[2]} does not exist"
|
|
542
1572
|
)
|
|
543
|
-
|
|
544
|
-
|
|
1573
|
+
else:
|
|
1574
|
+
if self.verbose > 1:
|
|
1575
|
+
print(
|
|
1576
|
+
"file: ",
|
|
1577
|
+
self.fileroot + thisregressor[2],
|
|
1578
|
+
" does not exist - skipping...",
|
|
1579
|
+
)
|
|
1580
|
+
|
|
1581
|
+
def _loadfuncmaps(self) -> None:
|
|
1582
|
+
"""
|
|
1583
|
+
Load functional maps from NIfTI files and initialize overlays.
|
|
1584
|
+
|
|
1585
|
+
This function iterates through the list of functional maps specified in
|
|
1586
|
+
`self.funcmaps`, loads each map from a NIfTI file (if it exists), and
|
|
1587
|
+
initializes an `Overlay` object for each. It ensures that all loaded
|
|
1588
|
+
maps have consistent dimensions and voxel sizes. If a map is listed in
|
|
1589
|
+
`mapstoinvert`, it will be inverted upon loading.
|
|
1590
|
+
|
|
1591
|
+
Parameters
|
|
1592
|
+
----------
|
|
1593
|
+
None
|
|
1594
|
+
|
|
1595
|
+
Returns
|
|
1596
|
+
-------
|
|
1597
|
+
None
|
|
1598
|
+
This function does not return a value but updates the following
|
|
1599
|
+
instance attributes:
|
|
1600
|
+
- `self.overlays`: Dictionary mapping map names to `Overlay` objects.
|
|
1601
|
+
- `self.loadedfuncmaps`: List of successfully loaded map names.
|
|
1602
|
+
|
|
1603
|
+
Notes
|
|
1604
|
+
-----
|
|
1605
|
+
- The function checks for the existence of `.nii.gz` files before attempting
|
|
1606
|
+
to load them.
|
|
1607
|
+
- If dimensions or voxel sizes of the loaded maps do not match, the program
|
|
1608
|
+
will exit with an error message.
|
|
1609
|
+
- Map names in `mapstoinvert` (currently only "varChange") will be inverted
|
|
1610
|
+
during loading.
|
|
1611
|
+
|
|
1612
|
+
Examples
|
|
1613
|
+
--------
|
|
1614
|
+
Assuming `self.funcmaps` contains entries like:
|
|
1615
|
+
[("varChange", "varchange_map"), ("tstat", "tstat_map")]
|
|
1616
|
+
|
|
1617
|
+
And the corresponding files exist, this function will load these maps and
|
|
1618
|
+
store them in `self.overlays` with appropriate inversion applied where
|
|
1619
|
+
needed.
|
|
1620
|
+
"""
|
|
1621
|
+
mapstoinvert = ["varChange"]
|
|
545
1622
|
self.loadedfuncmaps = []
|
|
546
1623
|
xdim = 0
|
|
547
1624
|
ydim = 0
|
|
@@ -557,12 +1634,17 @@ class RapidtideDataset:
|
|
|
557
1634
|
" exists - reading...",
|
|
558
1635
|
)
|
|
559
1636
|
thepath, thebase = os.path.split(self.fileroot)
|
|
1637
|
+
if mapname in mapstoinvert:
|
|
1638
|
+
invertthismap = True
|
|
1639
|
+
else:
|
|
1640
|
+
invertthismap = False
|
|
560
1641
|
self.overlays[mapname] = Overlay(
|
|
561
1642
|
mapname,
|
|
562
1643
|
self.fileroot + mapfilename + ".nii.gz",
|
|
563
1644
|
thebase,
|
|
564
1645
|
init_LUT=self.init_LUT,
|
|
565
1646
|
report=True,
|
|
1647
|
+
invertonload=invertthismap,
|
|
566
1648
|
verbose=self.verbose,
|
|
567
1649
|
)
|
|
568
1650
|
if xdim == 0:
|
|
@@ -596,7 +1678,53 @@ class RapidtideDataset:
|
|
|
596
1678
|
if self.verbose > 1:
|
|
597
1679
|
print("functional maps loaded:", self.loadedfuncmaps)
|
|
598
1680
|
|
|
599
|
-
def _loadfuncmasks(self):
|
|
1681
|
+
def _loadfuncmasks(self) -> None:
|
|
1682
|
+
"""
|
|
1683
|
+
Load functional masks from specified files and create overlay objects.
|
|
1684
|
+
|
|
1685
|
+
This method iterates through the functional masks defined in `self.funcmasks`
|
|
1686
|
+
and attempts to load each mask file. If a mask file exists, it creates an
|
|
1687
|
+
Overlay object and stores it in `self.overlays` with the mask name as key.
|
|
1688
|
+
|
|
1689
|
+
Parameters
|
|
1690
|
+
----------
|
|
1691
|
+
self : object
|
|
1692
|
+
The instance containing the following attributes:
|
|
1693
|
+
- funcmasks : list of tuples
|
|
1694
|
+
List of (maskname, maskfilename) pairs to load
|
|
1695
|
+
- fileroot : str
|
|
1696
|
+
Root directory path for mask files
|
|
1697
|
+
- overlays : dict
|
|
1698
|
+
Dictionary to store loaded overlay objects
|
|
1699
|
+
- verbose : int
|
|
1700
|
+
Verbosity level for printing status messages
|
|
1701
|
+
- init_LUT : bool, optional
|
|
1702
|
+
Flag to initialize lookup table for overlays
|
|
1703
|
+
- loadedfuncmasks : list
|
|
1704
|
+
List to store names of successfully loaded masks
|
|
1705
|
+
|
|
1706
|
+
Returns
|
|
1707
|
+
-------
|
|
1708
|
+
None
|
|
1709
|
+
This method modifies instance attributes in-place and does not return a value.
|
|
1710
|
+
|
|
1711
|
+
Notes
|
|
1712
|
+
-----
|
|
1713
|
+
- Mask files are expected to have .nii.gz extension
|
|
1714
|
+
- Only masks that exist at the constructed file path are loaded
|
|
1715
|
+
- Progress information is printed based on verbosity level
|
|
1716
|
+
- Successfully loaded mask names are stored in `self.loadedfuncmasks`
|
|
1717
|
+
|
|
1718
|
+
Examples
|
|
1719
|
+
--------
|
|
1720
|
+
>>> # Assuming self.funcmasks = [('mask1', 'mask1_file'), ('mask2', 'mask2_file')]
|
|
1721
|
+
>>> # and mask files exist at self.fileroot + maskfilename + ".nii.gz"
|
|
1722
|
+
>>> _loadfuncmasks()
|
|
1723
|
+
>>> print(self.loadedfuncmasks)
|
|
1724
|
+
['mask1', 'mask2']
|
|
1725
|
+
>>> print(self.overlays['mask1'])
|
|
1726
|
+
<Overlay object at 0x...>
|
|
1727
|
+
"""
|
|
600
1728
|
self.loadedfuncmasks = []
|
|
601
1729
|
for maskname, maskfilename in self.funcmasks:
|
|
602
1730
|
if self.verbose > 1:
|
|
@@ -622,7 +1750,91 @@ class RapidtideDataset:
|
|
|
622
1750
|
if self.verbose > 1:
|
|
623
1751
|
print(self.loadedfuncmasks)
|
|
624
1752
|
|
|
625
|
-
def
|
|
1753
|
+
def _genpmasks(self, pvals: list[float] = [0.05, 0.01, 0.005, 0.001]) -> None:
|
|
1754
|
+
"""
|
|
1755
|
+
Generate binary masks for specified p-value thresholds from negative log10 p-values.
|
|
1756
|
+
|
|
1757
|
+
This function creates binary masks based on negative log10 p-values stored in
|
|
1758
|
+
self.overlays["neglog10p"]. Each mask represents regions where the negative
|
|
1759
|
+
log10 p-values exceed the specified threshold.
|
|
1760
|
+
|
|
1761
|
+
Parameters
|
|
1762
|
+
----------
|
|
1763
|
+
pvals : list of float, optional
|
|
1764
|
+
List of p-value thresholds for mask generation. Default is [0.05, 0.01, 0.005, 0.001].
|
|
1765
|
+
Each threshold is converted to a mask name format "p_lt_{threshold}_mask".
|
|
1766
|
+
|
|
1767
|
+
Returns
|
|
1768
|
+
-------
|
|
1769
|
+
None
|
|
1770
|
+
This function modifies the instance's overlays and loadedfuncmasks attributes
|
|
1771
|
+
in-place and does not return any value.
|
|
1772
|
+
|
|
1773
|
+
Notes
|
|
1774
|
+
-----
|
|
1775
|
+
- Mask names are formatted to replace "0.0" with "0p0" (e.g., "0.05" becomes "0p05")
|
|
1776
|
+
- The function uses the last loaded functional mask as the base for duplication
|
|
1777
|
+
- Generated masks are stored in self.overlays dictionary with corresponding names
|
|
1778
|
+
- The function updates self.loadedfuncmasks with the names of newly created masks
|
|
1779
|
+
|
|
1780
|
+
Examples
|
|
1781
|
+
--------
|
|
1782
|
+
>>> _genpmasks([0.05, 0.01])
|
|
1783
|
+
# Generates masks for p-values 0.05 and 0.01 based on neglog10p data
|
|
1784
|
+
|
|
1785
|
+
>>> _genpmasks()
|
|
1786
|
+
# Generates masks for default p-values [0.05, 0.01, 0.005, 0.001]
|
|
1787
|
+
"""
|
|
1788
|
+
for thepval in pvals:
|
|
1789
|
+
maskname = f"p_lt_{thepval:.3f}_mask".replace("0.0", "0p0")
|
|
1790
|
+
nlpthresh = -np.log10(thepval)
|
|
1791
|
+
if self.verbose > 1:
|
|
1792
|
+
print(f"generating {maskname} from neglog10p")
|
|
1793
|
+
self.overlays[maskname] = self.overlays[self.loadedfuncmasks[-1]].duplicate(
|
|
1794
|
+
maskname, None, self.init_LUT
|
|
1795
|
+
)
|
|
1796
|
+
self.overlays[maskname].setData(
|
|
1797
|
+
np.where(self.overlays["neglog10p"].data > nlpthresh, 1.0, 0.0), isaMask=True
|
|
1798
|
+
)
|
|
1799
|
+
self.loadedfuncmasks.append(maskname)
|
|
1800
|
+
if self.verbose > 1:
|
|
1801
|
+
print(self.loadedfuncmasks)
|
|
1802
|
+
|
|
1803
|
+
def _loadgeommask(self) -> bool:
|
|
1804
|
+
"""
|
|
1805
|
+
Load a geometric mask based on configuration settings and available files.
|
|
1806
|
+
|
|
1807
|
+
This function attempts to load a geometric mask either from a user-specified
|
|
1808
|
+
file or from a default location based on the coordinate space and voxel size.
|
|
1809
|
+
The mask is stored in `self.overlays["geommask"]` if successfully loaded.
|
|
1810
|
+
|
|
1811
|
+
Returns
|
|
1812
|
+
-------
|
|
1813
|
+
bool
|
|
1814
|
+
True if a geometric mask was successfully loaded, False otherwise.
|
|
1815
|
+
|
|
1816
|
+
Notes
|
|
1817
|
+
-----
|
|
1818
|
+
- If `self.geommaskname` is set, the function attempts to load the mask from that file.
|
|
1819
|
+
- If `self.coordinatespace` is "MNI152", the function searches for a default mask
|
|
1820
|
+
based on the voxel size (`xsize`, `ysize`, `zsize`).
|
|
1821
|
+
- The function uses the FSL directory to locate default masks when available.
|
|
1822
|
+
- Verbose output is printed if `self.verbose` is greater than 1.
|
|
1823
|
+
|
|
1824
|
+
Examples
|
|
1825
|
+
--------
|
|
1826
|
+
>>> loader = SomeClass()
|
|
1827
|
+
>>> loader.geommaskname = "/path/to/custom_mask.nii.gz"
|
|
1828
|
+
>>> loader._loadgeommask()
|
|
1829
|
+
True
|
|
1830
|
+
|
|
1831
|
+
>>> loader.coordinatespace = "MNI152"
|
|
1832
|
+
>>> loader.xsize = 2.0
|
|
1833
|
+
>>> loader.ysize = 2.0
|
|
1834
|
+
>>> loader.zsize = 2.0
|
|
1835
|
+
>>> loader._loadgeommask()
|
|
1836
|
+
True # if default mask is found
|
|
1837
|
+
"""
|
|
626
1838
|
if self.geommaskname is not None:
|
|
627
1839
|
if os.path.isfile(self.geommaskname):
|
|
628
1840
|
thepath, thebase = os.path.split(self.geommaskname)
|
|
@@ -677,7 +1889,46 @@ class RapidtideDataset:
|
|
|
677
1889
|
print("no geometric mask loaded")
|
|
678
1890
|
return False
|
|
679
1891
|
|
|
680
|
-
def _loadanatomics(self):
|
|
1892
|
+
def _loadanatomics(self) -> bool:
|
|
1893
|
+
"""
|
|
1894
|
+
Load anatomic image data based on available files and coordinate space settings.
|
|
1895
|
+
|
|
1896
|
+
This method attempts to load anatomic images from various possible sources,
|
|
1897
|
+
prioritizing user-specified files, high-resolution templates, MNI templates,
|
|
1898
|
+
and mean-based images. The loaded image is stored in `self.overlays["anatomic"]`.
|
|
1899
|
+
|
|
1900
|
+
Returns
|
|
1901
|
+
-------
|
|
1902
|
+
bool
|
|
1903
|
+
True if anatomic image was successfully loaded, False otherwise.
|
|
1904
|
+
|
|
1905
|
+
Notes
|
|
1906
|
+
-----
|
|
1907
|
+
The method checks for the following files in order:
|
|
1908
|
+
1. User-specified anatomic file (`self.anatname`)
|
|
1909
|
+
2. High-resolution head image: `highres_head.nii.gz`
|
|
1910
|
+
3. High-resolution image: `highres.nii.gz`
|
|
1911
|
+
4. MNI152 template based on resolution (`xsize`, `ysize`, `zsize`)
|
|
1912
|
+
5. MNI152NLin2009cAsym template based on resolution
|
|
1913
|
+
6. Mean image: `mean.nii.gz`
|
|
1914
|
+
7. Mean value image: `meanvalue.nii.gz`
|
|
1915
|
+
8. Described mean image: `desc-unfiltmean_map.nii.gz`
|
|
1916
|
+
9. Described mean image: `desc-mean_map.nii.gz`
|
|
1917
|
+
|
|
1918
|
+
If `FSLDIR` environment variable is set, it is used to locate MNI152 templates
|
|
1919
|
+
with 2mm resolution.
|
|
1920
|
+
|
|
1921
|
+
Examples
|
|
1922
|
+
--------
|
|
1923
|
+
>>> loader = MyLoader()
|
|
1924
|
+
>>> loader.fileroot = "/path/to/data/"
|
|
1925
|
+
>>> loader.coordinatespace = "MNI152"
|
|
1926
|
+
>>> loader.xsize = 2.0
|
|
1927
|
+
>>> loader.ysize = 2.0
|
|
1928
|
+
>>> loader.zsize = 2.0
|
|
1929
|
+
>>> loader._loadanatomics()
|
|
1930
|
+
True
|
|
1931
|
+
"""
|
|
681
1932
|
try:
|
|
682
1933
|
fsldir = os.environ["FSLDIR"]
|
|
683
1934
|
except KeyError:
|
|
@@ -815,6 +2066,23 @@ class RapidtideDataset:
|
|
|
815
2066
|
print("using ", self.fileroot + "meanvalue.nii.gz", " as background")
|
|
816
2067
|
# allloadedmaps.append('anatomic')
|
|
817
2068
|
return True
|
|
2069
|
+
elif os.path.isfile(self.fileroot + "desc-unfiltmean_map.nii.gz"):
|
|
2070
|
+
thepath, thebase = os.path.split(self.fileroot)
|
|
2071
|
+
self.overlays["anatomic"] = Overlay(
|
|
2072
|
+
"anatomic",
|
|
2073
|
+
self.fileroot + "desc-unfiltmean_map.nii.gz",
|
|
2074
|
+
thebase,
|
|
2075
|
+
init_LUT=self.init_LUT,
|
|
2076
|
+
verbose=self.verbose,
|
|
2077
|
+
)
|
|
2078
|
+
if self.verbose > 1:
|
|
2079
|
+
print(
|
|
2080
|
+
"using ",
|
|
2081
|
+
self.fileroot + "desc-unfiltmean_map.nii.gz",
|
|
2082
|
+
" as background",
|
|
2083
|
+
)
|
|
2084
|
+
# allloadedmaps.append('anatomic')
|
|
2085
|
+
return True
|
|
818
2086
|
elif os.path.isfile(self.fileroot + "desc-mean_map.nii.gz"):
|
|
819
2087
|
thepath, thebase = os.path.split(self.fileroot)
|
|
820
2088
|
self.overlays["anatomic"] = Overlay(
|
|
@@ -837,7 +2105,33 @@ class RapidtideDataset:
|
|
|
837
2105
|
print("no anatomic image loaded")
|
|
838
2106
|
return False
|
|
839
2107
|
|
|
840
|
-
def _loadgraymask(self):
|
|
2108
|
+
def _loadgraymask(self) -> bool:
|
|
2109
|
+
"""
|
|
2110
|
+
Load gray matter mask from specification.
|
|
2111
|
+
|
|
2112
|
+
Load a gray matter mask from the file specification stored in `self.graymaskspec`.
|
|
2113
|
+
If successful, the mask is stored in `self.overlays["graymask"]` and the function
|
|
2114
|
+
returns True. If no mask specification is provided or the file doesn't exist,
|
|
2115
|
+
the function returns False.
|
|
2116
|
+
|
|
2117
|
+
Returns
|
|
2118
|
+
-------
|
|
2119
|
+
bool
|
|
2120
|
+
True if gray matter mask was successfully loaded, False otherwise.
|
|
2121
|
+
|
|
2122
|
+
Notes
|
|
2123
|
+
-----
|
|
2124
|
+
This function checks if `self.graymaskspec` is not None and if the specified
|
|
2125
|
+
file exists. If both conditions are met, it creates an Overlay object for the
|
|
2126
|
+
gray mask and stores it in `self.overlays["graymask"]`. The function also
|
|
2127
|
+
prints verbose messages when loading or skipping the mask.
|
|
2128
|
+
|
|
2129
|
+
Examples
|
|
2130
|
+
--------
|
|
2131
|
+
>>> loaded = self._loadgraymask()
|
|
2132
|
+
>>> print(loaded)
|
|
2133
|
+
True
|
|
2134
|
+
"""
|
|
841
2135
|
if self.graymaskspec is not None:
|
|
842
2136
|
filename, dummy = tide_io.parsefilespec(self.graymaskspec)
|
|
843
2137
|
if os.path.isfile(filename):
|
|
@@ -859,7 +2153,39 @@ class RapidtideDataset:
|
|
|
859
2153
|
print("no gray mask loaded")
|
|
860
2154
|
return False
|
|
861
2155
|
|
|
862
|
-
def _loadwhitemask(self):
|
|
2156
|
+
def _loadwhitemask(self) -> bool:
|
|
2157
|
+
"""
|
|
2158
|
+
Load white matter mask from specification if available.
|
|
2159
|
+
|
|
2160
|
+
This method attempts to load a white matter mask from the specification
|
|
2161
|
+
stored in `self.whitemaskspec`. If the specification is valid and the
|
|
2162
|
+
corresponding file exists, it creates an Overlay object for the white
|
|
2163
|
+
matter mask and stores it in `self.overlays["whitemask"]`.
|
|
2164
|
+
|
|
2165
|
+
Parameters
|
|
2166
|
+
----------
|
|
2167
|
+
self : object
|
|
2168
|
+
The instance containing the white matter mask specification and
|
|
2169
|
+
overlay storage.
|
|
2170
|
+
|
|
2171
|
+
Returns
|
|
2172
|
+
-------
|
|
2173
|
+
bool
|
|
2174
|
+
True if white matter mask was successfully loaded, False otherwise.
|
|
2175
|
+
|
|
2176
|
+
Notes
|
|
2177
|
+
-----
|
|
2178
|
+
The method checks if `self.whitemaskspec` is not None and if the
|
|
2179
|
+
specified file exists before attempting to load it. If successful,
|
|
2180
|
+
the mask is stored in `self.overlays["whitemask"]` and a verbose
|
|
2181
|
+
message is printed if `self.verbose` is greater than 1.
|
|
2182
|
+
|
|
2183
|
+
Examples
|
|
2184
|
+
--------
|
|
2185
|
+
>>> loaded = self._loadwhitemask()
|
|
2186
|
+
>>> print(loaded)
|
|
2187
|
+
True
|
|
2188
|
+
"""
|
|
863
2189
|
if self.whitemaskspec is not None:
|
|
864
2190
|
filename, dummy = tide_io.parsefilespec(self.whitemaskspec)
|
|
865
2191
|
if os.path.isfile(filename):
|
|
@@ -881,7 +2207,42 @@ class RapidtideDataset:
|
|
|
881
2207
|
print("no white mask loaded")
|
|
882
2208
|
return False
|
|
883
2209
|
|
|
884
|
-
def setupregressors(self):
|
|
2210
|
+
def setupregressors(self) -> None:
|
|
2211
|
+
"""
|
|
2212
|
+
Set up regressor specifications and load regressor data.
|
|
2213
|
+
|
|
2214
|
+
This method initializes the regressor specifications based on the BIDS format
|
|
2215
|
+
and the run options, and loads the corresponding regressor data. It handles
|
|
2216
|
+
various configuration parameters such as filter limits, sampling frequencies,
|
|
2217
|
+
and similarity metrics, and prepares a list of regressor specifications for
|
|
2218
|
+
use in subsequent processing steps.
|
|
2219
|
+
|
|
2220
|
+
Parameters
|
|
2221
|
+
----------
|
|
2222
|
+
None
|
|
2223
|
+
|
|
2224
|
+
Returns
|
|
2225
|
+
-------
|
|
2226
|
+
None
|
|
2227
|
+
This method does not return any value but updates the instance attributes
|
|
2228
|
+
`regressors`, `regressorfilterlimits`, `fmrifreq`, `inputfreq`,
|
|
2229
|
+
`inputstarttime`, `oversampfactor`, `similaritymetric`, `regressorsimcalclimits`,
|
|
2230
|
+
`numberofpasses`, and `regressorspecs`.
|
|
2231
|
+
|
|
2232
|
+
Notes
|
|
2233
|
+
-----
|
|
2234
|
+
- The method reads run options from a file specified by `self.fileroot + "desc-runoptions_info"`.
|
|
2235
|
+
- If `self.bidsformat` is True, the regressor files are named according to BIDS conventions.
|
|
2236
|
+
- The method determines the number of passes and sets up the regressor specifications accordingly.
|
|
2237
|
+
- The `regressorspecs` list contains information for loading regressors at different stages:
|
|
2238
|
+
pre-filtered, post-filtered, and multiple passes, with associated file names, frequencies,
|
|
2239
|
+
and time offsets.
|
|
2240
|
+
|
|
2241
|
+
Examples
|
|
2242
|
+
--------
|
|
2243
|
+
>>> setupregressors()
|
|
2244
|
+
# Updates instance attributes with regressor configurations and loads data.
|
|
2245
|
+
"""
|
|
885
2246
|
# load the regressors
|
|
886
2247
|
self.regressors = {}
|
|
887
2248
|
self.therunoptions = tide_io.readoptionsfile(self.fileroot + "desc-runoptions_info")
|
|
@@ -942,6 +2303,7 @@ class RapidtideDataset:
|
|
|
942
2303
|
self.inputfreq,
|
|
943
2304
|
self.inputfreq,
|
|
944
2305
|
self.inputstarttime,
|
|
2306
|
+
True,
|
|
945
2307
|
],
|
|
946
2308
|
[
|
|
947
2309
|
"postfilt",
|
|
@@ -950,6 +2312,7 @@ class RapidtideDataset:
|
|
|
950
2312
|
self.inputfreq,
|
|
951
2313
|
self.inputfreq,
|
|
952
2314
|
self.inputstarttime,
|
|
2315
|
+
True,
|
|
953
2316
|
],
|
|
954
2317
|
[
|
|
955
2318
|
"pass1",
|
|
@@ -958,6 +2321,7 @@ class RapidtideDataset:
|
|
|
958
2321
|
self.fmrifreq * self.oversampfactor,
|
|
959
2322
|
self.fmrifreq,
|
|
960
2323
|
0.0,
|
|
2324
|
+
True,
|
|
961
2325
|
],
|
|
962
2326
|
[
|
|
963
2327
|
"pass2",
|
|
@@ -966,6 +2330,7 @@ class RapidtideDataset:
|
|
|
966
2330
|
self.fmrifreq * self.oversampfactor,
|
|
967
2331
|
self.fmrifreq,
|
|
968
2332
|
0.0,
|
|
2333
|
+
False,
|
|
969
2334
|
],
|
|
970
2335
|
[
|
|
971
2336
|
"pass3",
|
|
@@ -974,6 +2339,7 @@ class RapidtideDataset:
|
|
|
974
2339
|
self.fmrifreq * self.oversampfactor,
|
|
975
2340
|
self.fmrifreq,
|
|
976
2341
|
0.0,
|
|
2342
|
+
False,
|
|
977
2343
|
],
|
|
978
2344
|
[
|
|
979
2345
|
"pass4",
|
|
@@ -982,6 +2348,7 @@ class RapidtideDataset:
|
|
|
982
2348
|
self.fmrifreq * self.oversampfactor,
|
|
983
2349
|
self.fmrifreq,
|
|
984
2350
|
0.0,
|
|
2351
|
+
False,
|
|
985
2352
|
],
|
|
986
2353
|
]
|
|
987
2354
|
else:
|
|
@@ -993,6 +2360,7 @@ class RapidtideDataset:
|
|
|
993
2360
|
self.inputfreq,
|
|
994
2361
|
self.inputfreq,
|
|
995
2362
|
self.inputstarttime,
|
|
2363
|
+
True,
|
|
996
2364
|
],
|
|
997
2365
|
[
|
|
998
2366
|
"postfilt",
|
|
@@ -1001,6 +2369,7 @@ class RapidtideDataset:
|
|
|
1001
2369
|
self.inputfreq,
|
|
1002
2370
|
self.inputfreq,
|
|
1003
2371
|
self.inputstarttime,
|
|
2372
|
+
True,
|
|
1004
2373
|
],
|
|
1005
2374
|
[
|
|
1006
2375
|
"pass1",
|
|
@@ -1009,6 +2378,7 @@ class RapidtideDataset:
|
|
|
1009
2378
|
self.fmrifreq * self.oversampfactor,
|
|
1010
2379
|
self.fmrifreq,
|
|
1011
2380
|
0.0,
|
|
2381
|
+
True,
|
|
1012
2382
|
],
|
|
1013
2383
|
[
|
|
1014
2384
|
"pass2",
|
|
@@ -1017,6 +2387,7 @@ class RapidtideDataset:
|
|
|
1017
2387
|
self.fmrifreq * self.oversampfactor,
|
|
1018
2388
|
self.fmrifreq,
|
|
1019
2389
|
0.0,
|
|
2390
|
+
False,
|
|
1020
2391
|
],
|
|
1021
2392
|
[
|
|
1022
2393
|
"pass3",
|
|
@@ -1025,6 +2396,7 @@ class RapidtideDataset:
|
|
|
1025
2396
|
self.fmrifreq * self.oversampfactor,
|
|
1026
2397
|
self.fmrifreq,
|
|
1027
2398
|
0.0,
|
|
2399
|
+
False,
|
|
1028
2400
|
],
|
|
1029
2401
|
[
|
|
1030
2402
|
"pass4",
|
|
@@ -1033,17 +2405,139 @@ class RapidtideDataset:
|
|
|
1033
2405
|
self.fmrifreq * self.oversampfactor,
|
|
1034
2406
|
self.fmrifreq,
|
|
1035
2407
|
0.0,
|
|
2408
|
+
False,
|
|
1036
2409
|
],
|
|
1037
2410
|
]
|
|
1038
2411
|
self._loadregressors()
|
|
1039
2412
|
|
|
1040
|
-
def getregressors(self):
|
|
2413
|
+
def getregressors(self) -> dict:
|
|
2414
|
+
"""
|
|
2415
|
+
Return the regressors stored in the object.
|
|
2416
|
+
|
|
2417
|
+
Returns
|
|
2418
|
+
-------
|
|
2419
|
+
dict
|
|
2420
|
+
A dictionary containing the regressors. The keys are typically
|
|
2421
|
+
regressor names and the values are the corresponding regressor objects.
|
|
2422
|
+
|
|
2423
|
+
Notes
|
|
2424
|
+
-----
|
|
2425
|
+
This method provides access to the internal regressors dictionary
|
|
2426
|
+
that stores all regression models used by the object.
|
|
2427
|
+
|
|
2428
|
+
Examples
|
|
2429
|
+
--------
|
|
2430
|
+
>>> model = MyRegressionModel()
|
|
2431
|
+
>>> regressors = model.getregressors()
|
|
2432
|
+
>>> print(regressors)
|
|
2433
|
+
{'linear_reg': LinearRegression(), 'ridge_reg': Ridge()}
|
|
2434
|
+
"""
|
|
1041
2435
|
return self.regressors
|
|
1042
2436
|
|
|
1043
|
-
def setfocusregressor(self, whichregressor):
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
2437
|
+
def setfocusregressor(self, whichregressor: str) -> None:
|
|
2438
|
+
"""
|
|
2439
|
+
Set the focus regressor for the current instance.
|
|
2440
|
+
|
|
2441
|
+
This method sets the focus regressor to the specified regressor name if it exists
|
|
2442
|
+
in the regressors dictionary. If the specified regressor does not exist, it defaults
|
|
2443
|
+
to "prefilt".
|
|
2444
|
+
|
|
2445
|
+
Parameters
|
|
2446
|
+
----------
|
|
2447
|
+
whichregressor : str
|
|
2448
|
+
The name of the regressor to set as the focus regressor. This should be a key
|
|
2449
|
+
present in the instance's regressors dictionary.
|
|
2450
|
+
|
|
2451
|
+
Returns
|
|
2452
|
+
-------
|
|
2453
|
+
None
|
|
2454
|
+
This method does not return any value.
|
|
2455
|
+
|
|
2456
|
+
Notes
|
|
2457
|
+
-----
|
|
2458
|
+
If the specified regressor name is not found in self.regressors, the method will
|
|
2459
|
+
automatically fall back to setting the focus regressor to "prefilt".
|
|
2460
|
+
|
|
2461
|
+
Examples
|
|
2462
|
+
--------
|
|
2463
|
+
>>> instance.setfocusregressor("regressor1")
|
|
2464
|
+
>>> print(instance.focusregressor)
|
|
2465
|
+
'regressor1'
|
|
2466
|
+
|
|
2467
|
+
>>> instance.setfocusregressor("nonexistent")
|
|
2468
|
+
>>> print(instance.focusregressor)
|
|
2469
|
+
'prefilt'
|
|
2470
|
+
"""
|
|
2471
|
+
try:
|
|
2472
|
+
testregressor = self.regressors[whichregressor]
|
|
2473
|
+
self.focusregressor = whichregressor
|
|
2474
|
+
except KeyError:
|
|
2475
|
+
self.focusregressor = "prefilt"
|
|
2476
|
+
|
|
2477
|
+
def setupoverlays(self) -> None:
|
|
2478
|
+
"""
|
|
2479
|
+
Set up and load all overlays for functional and anatomical data.
|
|
2480
|
+
|
|
2481
|
+
This function initializes the overlays dictionary and loads various functional
|
|
2482
|
+
maps, masks, and anatomical data based on the configuration parameters such as
|
|
2483
|
+
BIDS format, use of correlation outputs, and coordinate space. It also handles
|
|
2484
|
+
setting TR and time offset values for the loaded maps, and loads additional
|
|
2485
|
+
data such as atlases and tissue masks if applicable.
|
|
2486
|
+
|
|
2487
|
+
Parameters
|
|
2488
|
+
----------
|
|
2489
|
+
self : object
|
|
2490
|
+
The instance of the class containing this method. Expected to have the
|
|
2491
|
+
following attributes:
|
|
2492
|
+
|
|
2493
|
+
- bidsformat : bool
|
|
2494
|
+
Indicates whether the data is in BIDS format.
|
|
2495
|
+
- usecorrout : bool
|
|
2496
|
+
Whether to include correlation output maps.
|
|
2497
|
+
- newstylenames : bool
|
|
2498
|
+
Whether to use new-style naming conventions for maps.
|
|
2499
|
+
- userise : bool
|
|
2500
|
+
Whether to include rise time-related maps.
|
|
2501
|
+
- forcetr : bool
|
|
2502
|
+
Whether to force TR value for loaded maps.
|
|
2503
|
+
- forceoffset : bool
|
|
2504
|
+
Whether to force time offset for loaded maps.
|
|
2505
|
+
- trval : float
|
|
2506
|
+
The TR value to be set if `forcetr` is True.
|
|
2507
|
+
- offsettime : float
|
|
2508
|
+
The time offset to be set if `forceoffset` is True.
|
|
2509
|
+
- verbose : int
|
|
2510
|
+
Verbosity level for output messages.
|
|
2511
|
+
- referencedir : str
|
|
2512
|
+
Directory containing reference data such as atlases.
|
|
2513
|
+
- init_LUT : bool
|
|
2514
|
+
Whether to initialize lookup tables for overlays.
|
|
2515
|
+
- useatlas : bool
|
|
2516
|
+
Whether to load atlas data.
|
|
2517
|
+
- coordinatespace : str
|
|
2518
|
+
The coordinate space of the data (e.g., "MNI152", "MNI152NLin2009cAsym").
|
|
2519
|
+
|
|
2520
|
+
Returns
|
|
2521
|
+
-------
|
|
2522
|
+
None
|
|
2523
|
+
This function does not return any value. It modifies the instance's
|
|
2524
|
+
attributes in place.
|
|
2525
|
+
|
|
2526
|
+
Notes
|
|
2527
|
+
-----
|
|
2528
|
+
- Functional maps are loaded based on the BIDS format and naming conventions.
|
|
2529
|
+
- The function dynamically builds lists of functional maps and masks depending
|
|
2530
|
+
on the configuration.
|
|
2531
|
+
- If an atlas is to be used and the coordinate space is compatible, it will be
|
|
2532
|
+
loaded and added to the overlays.
|
|
2533
|
+
- The function sets up several instance variables such as `xdim`, `ydim`, `zdim`,
|
|
2534
|
+
`tdim`, `xsize`, `ysize`, `zsize`, and `tr` from the focus map.
|
|
2535
|
+
|
|
2536
|
+
Examples
|
|
2537
|
+
--------
|
|
2538
|
+
>>> setupoverlays()
|
|
2539
|
+
# Loads all overlays and sets up the instance for further processing.
|
|
2540
|
+
"""
|
|
1047
2541
|
# load the overlays
|
|
1048
2542
|
self.overlays = {}
|
|
1049
2543
|
|
|
@@ -1051,13 +2545,22 @@ class RapidtideDataset:
|
|
|
1051
2545
|
if self.bidsformat:
|
|
1052
2546
|
self.funcmaps = [
|
|
1053
2547
|
["lagtimes", "desc-maxtime_map"],
|
|
2548
|
+
["lagtimesrefined", "desc-maxtimerefined_map"],
|
|
1054
2549
|
["timepercentile", "desc-timepercentile_map"],
|
|
1055
2550
|
["lagstrengths", "desc-maxcorr_map"],
|
|
2551
|
+
["lagstrengthsrefined", "desc-maxcorrrefined_map"],
|
|
1056
2552
|
["lagsigma", "desc-maxwidth_map"],
|
|
1057
2553
|
["MTT", "desc-MTT_map"],
|
|
1058
2554
|
["R2", "desc-lfofilterR2_map"],
|
|
2555
|
+
["CoV", "desc-CoV_map"],
|
|
2556
|
+
["confoundR2", "desc-confoundfilterR2_map"],
|
|
2557
|
+
["varBefore", "desc-lfofilterInbandVarianceBefore_map"],
|
|
2558
|
+
["varAfter", "desc-lfofilterInbandVarianceAfter_map"],
|
|
2559
|
+
["varChange", "desc-lfofilterInbandVarianceChange_map"],
|
|
1059
2560
|
["fitNorm", "desc-lfofilterNorm_map"],
|
|
1060
2561
|
["fitcoff", "desc-lfofilterCoeff_map"],
|
|
2562
|
+
["neglog10p", "desc-neglog10p_map"],
|
|
2563
|
+
["delayoffset", "desc-delayoffset_map"],
|
|
1061
2564
|
]
|
|
1062
2565
|
if self.usecorrout:
|
|
1063
2566
|
self.funcmaps += [["corrout", "desc-corrout_info"]]
|
|
@@ -1146,12 +2649,17 @@ class RapidtideDataset:
|
|
|
1146
2649
|
["lagmask", "desc-corrfit_mask"],
|
|
1147
2650
|
["refinemask", "desc-refine_mask"],
|
|
1148
2651
|
["meanmask", "desc-globalmean_mask"],
|
|
2652
|
+
["brainmask", "desc-brainmask_mask"],
|
|
1149
2653
|
["preselectmask", "desc-globalmeanpreselect_mask"],
|
|
1150
|
-
["p_lt_0p050_mask", "desc-plt0p050_mask"],
|
|
1151
|
-
["p_lt_0p010_mask", "desc-plt0p010_mask"],
|
|
1152
|
-
["p_lt_0p005_mask", "desc-plt0p005_mask"],
|
|
1153
|
-
["p_lt_0p001_mask", "desc-plt0p001_mask"],
|
|
1154
2654
|
]
|
|
2655
|
+
if not ("neglog10p" in self.loadedfuncmaps):
|
|
2656
|
+
# load p maps manually
|
|
2657
|
+
self.funcmasks += [
|
|
2658
|
+
["p_lt_0p050_mask", "desc-plt0p050_mask"],
|
|
2659
|
+
["p_lt_0p010_mask", "desc-plt0p010_mask"],
|
|
2660
|
+
["p_lt_0p005_mask", "desc-plt0p005_mask"],
|
|
2661
|
+
["p_lt_0p001_mask", "desc-plt0p001_mask"],
|
|
2662
|
+
]
|
|
1155
2663
|
else:
|
|
1156
2664
|
if self.newstylenames:
|
|
1157
2665
|
self.funcmasks = [
|
|
@@ -1174,6 +2682,9 @@ class RapidtideDataset:
|
|
|
1174
2682
|
["p_lt_0p001_mask", "p_lt_0p001_mask"],
|
|
1175
2683
|
]
|
|
1176
2684
|
self._loadfuncmasks()
|
|
2685
|
+
if "neglog10p" in self.loadedfuncmaps:
|
|
2686
|
+
# generate p maps on the fly
|
|
2687
|
+
self._genpmasks()
|
|
1177
2688
|
|
|
1178
2689
|
# then the geometric masks
|
|
1179
2690
|
if self._loadgeommask():
|
|
@@ -1190,8 +2701,7 @@ class RapidtideDataset:
|
|
|
1190
2701
|
or (self.coordinatespace == "MNI152NLin6")
|
|
1191
2702
|
or (self.coordinatespace == "MNI152NLin2009cAsym")
|
|
1192
2703
|
):
|
|
1193
|
-
|
|
1194
|
-
self.atlasshortname = "ATT"
|
|
2704
|
+
self.atlasshortname = "JHU1"
|
|
1195
2705
|
self.atlasname = atlases[self.atlasshortname]["atlasname"]
|
|
1196
2706
|
self.atlaslabels = tide_io.readlabels(
|
|
1197
2707
|
os.path.join(self.referencedir, self.atlasname + "_regions.txt")
|
|
@@ -1200,19 +2710,20 @@ class RapidtideDataset:
|
|
|
1200
2710
|
print(self.atlaslabels)
|
|
1201
2711
|
self.atlasniftiname = None
|
|
1202
2712
|
if self.coordinatespace == "MNI152":
|
|
2713
|
+
spacename = "_space-MNI152NLin6Asym"
|
|
1203
2714
|
if self.xsize == 2.0 and self.ysize == 2.0 and self.zsize == 2.0:
|
|
1204
2715
|
self.atlasniftiname = os.path.join(
|
|
1205
|
-
self.referencedir, self.atlasname + "_2mm.nii.gz"
|
|
2716
|
+
self.referencedir, self.atlasname + spacename + "_2mm.nii.gz"
|
|
1206
2717
|
)
|
|
1207
2718
|
self.atlasmaskniftiname = os.path.join(
|
|
1208
|
-
self.referencedir, self.atlasname + "_2mm_mask.nii.gz"
|
|
2719
|
+
self.referencedir, self.atlasname + spacename + "_2mm_mask.nii.gz"
|
|
1209
2720
|
)
|
|
1210
2721
|
if self.xsize == 3.0 and self.ysize == 3.0 and self.zsize == 3.0:
|
|
1211
2722
|
self.atlasniftiname = os.path.join(
|
|
1212
|
-
self.referencedir, self.atlasname + "_3mm.nii.gz"
|
|
2723
|
+
self.referencedir, self.atlasname + spacename + "_3mm.nii.gz"
|
|
1213
2724
|
)
|
|
1214
2725
|
self.atlasmaskniftiname = os.path.join(
|
|
1215
|
-
self.referencedir, self.atlasname + "_3mm_mask.nii.gz"
|
|
2726
|
+
self.referencedir, self.atlasname + spacename + "_3mm_mask.nii.gz"
|
|
1216
2727
|
)
|
|
1217
2728
|
else:
|
|
1218
2729
|
pass
|
|
@@ -1256,8 +2767,92 @@ class RapidtideDataset:
|
|
|
1256
2767
|
if self.verbose > 1:
|
|
1257
2768
|
print("done")
|
|
1258
2769
|
|
|
1259
|
-
def getoverlays(self):
|
|
2770
|
+
def getoverlays(self) -> dict:
|
|
2771
|
+
"""
|
|
2772
|
+
Return the overlays dictionary.
|
|
2773
|
+
|
|
2774
|
+
Returns
|
|
2775
|
+
-------
|
|
2776
|
+
dict
|
|
2777
|
+
A dictionary containing the overlays data.
|
|
2778
|
+
|
|
2779
|
+
Notes
|
|
2780
|
+
-----
|
|
2781
|
+
This method provides access to the internal overlays attribute.
|
|
2782
|
+
The returned dictionary contains all overlay data managed by this instance.
|
|
2783
|
+
|
|
2784
|
+
Examples
|
|
2785
|
+
--------
|
|
2786
|
+
>>> overlays = obj.getoverlays()
|
|
2787
|
+
>>> print(overlays)
|
|
2788
|
+
{'overlay1': <OverlayObject>, 'overlay2': <OverlayObject>}
|
|
2789
|
+
"""
|
|
1260
2790
|
return self.overlays
|
|
1261
2791
|
|
|
1262
|
-
def setfocusmap(self, whichmap):
|
|
1263
|
-
|
|
2792
|
+
def setfocusmap(self, whichmap: str) -> None:
|
|
2793
|
+
"""
|
|
2794
|
+
Set the focus map to the specified map name.
|
|
2795
|
+
|
|
2796
|
+
This method sets the current focus map to the specified map name if it exists
|
|
2797
|
+
in the overlays dictionary. If the specified map does not exist, it defaults
|
|
2798
|
+
to setting the focus map to "lagtimes".
|
|
2799
|
+
|
|
2800
|
+
Parameters
|
|
2801
|
+
----------
|
|
2802
|
+
whichmap : str
|
|
2803
|
+
The name of the map to set as the focus map. This should correspond to
|
|
2804
|
+
a key in the self.overlays dictionary.
|
|
2805
|
+
|
|
2806
|
+
Returns
|
|
2807
|
+
-------
|
|
2808
|
+
None
|
|
2809
|
+
This method does not return any value.
|
|
2810
|
+
|
|
2811
|
+
Notes
|
|
2812
|
+
-----
|
|
2813
|
+
If the specified `whichmap` is not found in `self.overlays`, the method
|
|
2814
|
+
will automatically fall back to setting the focus map to "lagtimes".
|
|
2815
|
+
|
|
2816
|
+
Examples
|
|
2817
|
+
--------
|
|
2818
|
+
>>> obj.setfocusmap("temperature")
|
|
2819
|
+
>>> obj.focusmap
|
|
2820
|
+
'temperature'
|
|
2821
|
+
|
|
2822
|
+
>>> obj.setfocusmap("nonexistent")
|
|
2823
|
+
>>> obj.focusmap
|
|
2824
|
+
'lagtimes'
|
|
2825
|
+
"""
|
|
2826
|
+
try:
|
|
2827
|
+
testmap = self.overlays[whichmap]
|
|
2828
|
+
self.focusmap = whichmap
|
|
2829
|
+
except KeyError:
|
|
2830
|
+
self.focusmap = "lagtimes"
|
|
2831
|
+
|
|
2832
|
+
def setFuncMaskName(self, maskname: str) -> None:
|
|
2833
|
+
"""
|
|
2834
|
+
Set the function mask name attribute.
|
|
2835
|
+
|
|
2836
|
+
Parameters
|
|
2837
|
+
----------
|
|
2838
|
+
maskname : str
|
|
2839
|
+
The name to assign to the function mask attribute.
|
|
2840
|
+
|
|
2841
|
+
Returns
|
|
2842
|
+
-------
|
|
2843
|
+
None
|
|
2844
|
+
This method does not return any value.
|
|
2845
|
+
|
|
2846
|
+
Notes
|
|
2847
|
+
-----
|
|
2848
|
+
This method assigns the provided mask name to the internal `funcmaskname` attribute
|
|
2849
|
+
of the object instance.
|
|
2850
|
+
|
|
2851
|
+
Examples
|
|
2852
|
+
--------
|
|
2853
|
+
>>> obj = MyClass()
|
|
2854
|
+
>>> obj.setFuncMaskName("my_mask")
|
|
2855
|
+
>>> print(obj.funcmaskname)
|
|
2856
|
+
'my_mask'
|
|
2857
|
+
"""
|
|
2858
|
+
self.funcmaskname = maskname
|