rapidtide 2.9.5__py3-none-any.whl → 3.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cloud/gmscalc-HCPYA +1 -1
- cloud/mount-and-run +2 -0
- cloud/rapidtide-HCPYA +3 -3
- rapidtide/Colortables.py +538 -38
- rapidtide/OrthoImageItem.py +1094 -51
- rapidtide/RapidtideDataset.py +1709 -114
- rapidtide/__init__.py +0 -8
- rapidtide/_version.py +4 -4
- rapidtide/calccoherence.py +242 -97
- rapidtide/calcnullsimfunc.py +240 -140
- rapidtide/calcsimfunc.py +314 -129
- rapidtide/correlate.py +1211 -389
- rapidtide/data/examples/src/testLD +56 -0
- rapidtide/data/examples/src/test_findmaxlag.py +2 -2
- rapidtide/data/examples/src/test_mlregressallt.py +32 -17
- rapidtide/data/examples/src/testalign +1 -1
- rapidtide/data/examples/src/testatlasaverage +35 -7
- rapidtide/data/examples/src/testboth +21 -0
- rapidtide/data/examples/src/testcifti +11 -0
- rapidtide/data/examples/src/testdelayvar +13 -0
- rapidtide/data/examples/src/testdlfilt +25 -0
- rapidtide/data/examples/src/testfft +35 -0
- rapidtide/data/examples/src/testfileorfloat +37 -0
- rapidtide/data/examples/src/testfmri +94 -27
- rapidtide/data/examples/src/testfuncs +3 -3
- rapidtide/data/examples/src/testglmfilt +8 -6
- rapidtide/data/examples/src/testhappy +84 -51
- rapidtide/data/examples/src/testinitdelay +19 -0
- rapidtide/data/examples/src/testmodels +33 -0
- rapidtide/data/examples/src/testnewrefine +26 -0
- rapidtide/data/examples/src/testnoiseamp +21 -0
- rapidtide/data/examples/src/testppgproc +17 -0
- rapidtide/data/examples/src/testrefineonly +22 -0
- rapidtide/data/examples/src/testretro +26 -13
- rapidtide/data/examples/src/testretrolagtcs +16 -0
- rapidtide/data/examples/src/testrolloff +11 -0
- rapidtide/data/examples/src/testsimdata +45 -28
- rapidtide/data/models/model_cnn_pytorch/loss.png +0 -0
- rapidtide/data/models/model_cnn_pytorch/loss.txt +1 -0
- rapidtide/data/models/model_cnn_pytorch/model.pth +0 -0
- rapidtide/data/models/model_cnn_pytorch/model_meta.json +68 -0
- rapidtide/data/models/model_cnn_pytorch_fulldata/loss.png +0 -0
- rapidtide/data/models/model_cnn_pytorch_fulldata/loss.txt +1 -0
- rapidtide/data/models/model_cnn_pytorch_fulldata/model.pth +0 -0
- rapidtide/data/models/model_cnn_pytorch_fulldata/model_meta.json +80 -0
- rapidtide/data/models/model_cnnbp_pytorch_fullldata/loss.png +0 -0
- rapidtide/data/models/model_cnnbp_pytorch_fullldata/loss.txt +1 -0
- rapidtide/data/models/model_cnnbp_pytorch_fullldata/model.pth +0 -0
- rapidtide/data/models/model_cnnbp_pytorch_fullldata/model_meta.json +138 -0
- rapidtide/data/models/model_cnnfft_pytorch_fulldata/loss.png +0 -0
- rapidtide/data/models/model_cnnfft_pytorch_fulldata/loss.txt +1 -0
- rapidtide/data/models/model_cnnfft_pytorch_fulldata/model.pth +0 -0
- rapidtide/data/models/model_cnnfft_pytorch_fulldata/model_meta.json +128 -0
- rapidtide/data/models/model_ppgattention_pytorch_w128_fulldata/loss.png +0 -0
- rapidtide/data/models/model_ppgattention_pytorch_w128_fulldata/loss.txt +1 -0
- rapidtide/data/models/model_ppgattention_pytorch_w128_fulldata/model.pth +0 -0
- rapidtide/data/models/model_ppgattention_pytorch_w128_fulldata/model_meta.json +49 -0
- rapidtide/data/models/model_revised_tf2/model.keras +0 -0
- rapidtide/data/models/{model_serdar → model_revised_tf2}/model_meta.json +1 -1
- rapidtide/data/models/model_serdar2_tf2/model.keras +0 -0
- rapidtide/data/models/{model_serdar2 → model_serdar2_tf2}/model_meta.json +1 -1
- rapidtide/data/models/model_serdar_tf2/model.keras +0 -0
- rapidtide/data/models/{model_revised → model_serdar_tf2}/model_meta.json +1 -1
- rapidtide/data/reference/HCP1200v2_MTT_2mm.nii.gz +0 -0
- rapidtide/data/reference/HCP1200v2_binmask_2mm.nii.gz +0 -0
- rapidtide/data/reference/HCP1200v2_csf_2mm.nii.gz +0 -0
- rapidtide/data/reference/HCP1200v2_gray_2mm.nii.gz +0 -0
- rapidtide/data/reference/HCP1200v2_graylaghist.json +7 -0
- rapidtide/data/reference/HCP1200v2_graylaghist.tsv.gz +0 -0
- rapidtide/data/reference/HCP1200v2_laghist.json +7 -0
- rapidtide/data/reference/HCP1200v2_laghist.tsv.gz +0 -0
- rapidtide/data/reference/HCP1200v2_mask_2mm.nii.gz +0 -0
- rapidtide/data/reference/HCP1200v2_maxcorr_2mm.nii.gz +0 -0
- rapidtide/data/reference/HCP1200v2_maxtime_2mm.nii.gz +0 -0
- rapidtide/data/reference/HCP1200v2_maxwidth_2mm.nii.gz +0 -0
- rapidtide/data/reference/HCP1200v2_negmask_2mm.nii.gz +0 -0
- rapidtide/data/reference/HCP1200v2_timepercentile_2mm.nii.gz +0 -0
- rapidtide/data/reference/HCP1200v2_white_2mm.nii.gz +0 -0
- rapidtide/data/reference/HCP1200v2_whitelaghist.json +7 -0
- rapidtide/data/reference/HCP1200v2_whitelaghist.tsv.gz +0 -0
- rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1-seg2.xml +131 -0
- rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1-seg2_regions.txt +60 -0
- rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1-seg2_space-MNI152NLin6Asym_2mm.nii.gz +0 -0
- rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm.nii.gz +0 -0
- rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm_mask.nii.gz +0 -0
- rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin6Asym_2mm_mask.nii.gz +0 -0
- rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL2_space-MNI152NLin6Asym_2mm_mask.nii.gz +0 -0
- rapidtide/data/reference/MNI152_T1_1mm_Brain_FAST_seg.nii.gz +0 -0
- rapidtide/data/reference/MNI152_T1_1mm_Brain_Mask.nii.gz +0 -0
- rapidtide/data/reference/MNI152_T1_2mm_Brain_FAST_seg.nii.gz +0 -0
- rapidtide/data/reference/MNI152_T1_2mm_Brain_Mask.nii.gz +0 -0
- rapidtide/decorators.py +91 -0
- rapidtide/dlfilter.py +2553 -414
- rapidtide/dlfiltertorch.py +5201 -0
- rapidtide/externaltools.py +328 -13
- rapidtide/fMRIData_class.py +178 -0
- rapidtide/ffttools.py +168 -0
- rapidtide/filter.py +2704 -1462
- rapidtide/fit.py +2361 -579
- rapidtide/genericmultiproc.py +197 -0
- rapidtide/happy_supportfuncs.py +3255 -548
- rapidtide/helper_classes.py +590 -1181
- rapidtide/io.py +2569 -468
- rapidtide/linfitfiltpass.py +784 -0
- rapidtide/makelaggedtcs.py +267 -97
- rapidtide/maskutil.py +555 -25
- rapidtide/miscmath.py +867 -137
- rapidtide/multiproc.py +217 -44
- rapidtide/patchmatch.py +752 -0
- rapidtide/peakeval.py +32 -32
- rapidtide/ppgproc.py +2205 -0
- rapidtide/qualitycheck.py +353 -40
- rapidtide/refinedelay.py +854 -0
- rapidtide/refineregressor.py +939 -0
- rapidtide/resample.py +725 -204
- rapidtide/scripts/__init__.py +1 -0
- rapidtide/scripts/{adjustoffset → adjustoffset.py} +7 -2
- rapidtide/scripts/{aligntcs → aligntcs.py} +7 -2
- rapidtide/scripts/{applydlfilter → applydlfilter.py} +7 -2
- rapidtide/scripts/applyppgproc.py +28 -0
- rapidtide/scripts/{atlasaverage → atlasaverage.py} +7 -2
- rapidtide/scripts/{atlastool → atlastool.py} +7 -2
- rapidtide/scripts/{calcicc → calcicc.py} +7 -2
- rapidtide/scripts/{calctexticc → calctexticc.py} +7 -2
- rapidtide/scripts/{calcttest → calcttest.py} +7 -2
- rapidtide/scripts/{ccorrica → ccorrica.py} +7 -2
- rapidtide/scripts/delayvar.py +28 -0
- rapidtide/scripts/{diffrois → diffrois.py} +7 -2
- rapidtide/scripts/{endtidalproc → endtidalproc.py} +7 -2
- rapidtide/scripts/{fdica → fdica.py} +7 -2
- rapidtide/scripts/{filtnifti → filtnifti.py} +7 -2
- rapidtide/scripts/{filttc → filttc.py} +7 -2
- rapidtide/scripts/{fingerprint → fingerprint.py} +20 -16
- rapidtide/scripts/{fixtr → fixtr.py} +7 -2
- rapidtide/scripts/{gmscalc → gmscalc.py} +7 -2
- rapidtide/scripts/{happy → happy.py} +7 -2
- rapidtide/scripts/{happy2std → happy2std.py} +7 -2
- rapidtide/scripts/{happywarp → happywarp.py} +8 -4
- rapidtide/scripts/{histnifti → histnifti.py} +7 -2
- rapidtide/scripts/{histtc → histtc.py} +7 -2
- rapidtide/scripts/{glmfilt → linfitfilt.py} +7 -4
- rapidtide/scripts/{localflow → localflow.py} +7 -2
- rapidtide/scripts/{mergequality → mergequality.py} +7 -2
- rapidtide/scripts/{pairproc → pairproc.py} +7 -2
- rapidtide/scripts/{pairwisemergenifti → pairwisemergenifti.py} +7 -2
- rapidtide/scripts/{physiofreq → physiofreq.py} +7 -2
- rapidtide/scripts/{pixelcomp → pixelcomp.py} +7 -2
- rapidtide/scripts/{plethquality → plethquality.py} +7 -2
- rapidtide/scripts/{polyfitim → polyfitim.py} +7 -2
- rapidtide/scripts/{proj2flow → proj2flow.py} +7 -2
- rapidtide/scripts/{rankimage → rankimage.py} +7 -2
- rapidtide/scripts/{rapidtide → rapidtide.py} +7 -2
- rapidtide/scripts/{rapidtide2std → rapidtide2std.py} +7 -2
- rapidtide/scripts/{resamplenifti → resamplenifti.py} +7 -2
- rapidtide/scripts/{resampletc → resampletc.py} +7 -2
- rapidtide/scripts/retrolagtcs.py +28 -0
- rapidtide/scripts/retroregress.py +28 -0
- rapidtide/scripts/{roisummarize → roisummarize.py} +7 -2
- rapidtide/scripts/{runqualitycheck → runqualitycheck.py} +7 -2
- rapidtide/scripts/{showarbcorr → showarbcorr.py} +7 -2
- rapidtide/scripts/{showhist → showhist.py} +7 -2
- rapidtide/scripts/{showstxcorr → showstxcorr.py} +7 -2
- rapidtide/scripts/{showtc → showtc.py} +7 -2
- rapidtide/scripts/{showxcorr_legacy → showxcorr_legacy.py} +8 -8
- rapidtide/scripts/{showxcorrx → showxcorrx.py} +7 -2
- rapidtide/scripts/{showxy → showxy.py} +7 -2
- rapidtide/scripts/{simdata → simdata.py} +7 -2
- rapidtide/scripts/{spatialdecomp → spatialdecomp.py} +7 -2
- rapidtide/scripts/{spatialfit → spatialfit.py} +7 -2
- rapidtide/scripts/{spatialmi → spatialmi.py} +7 -2
- rapidtide/scripts/{spectrogram → spectrogram.py} +7 -2
- rapidtide/scripts/stupidramtricks.py +238 -0
- rapidtide/scripts/{synthASL → synthASL.py} +7 -2
- rapidtide/scripts/{tcfrom2col → tcfrom2col.py} +7 -2
- rapidtide/scripts/{tcfrom3col → tcfrom3col.py} +7 -2
- rapidtide/scripts/{temporaldecomp → temporaldecomp.py} +7 -2
- rapidtide/scripts/{testhrv → testhrv.py} +1 -1
- rapidtide/scripts/{threeD → threeD.py} +7 -2
- rapidtide/scripts/{tidepool → tidepool.py} +7 -2
- rapidtide/scripts/{variabilityizer → variabilityizer.py} +7 -2
- rapidtide/simFuncClasses.py +2113 -0
- rapidtide/simfuncfit.py +312 -108
- rapidtide/stats.py +579 -247
- rapidtide/tests/.coveragerc +27 -6
- rapidtide-2.9.5.data/scripts/fdica → rapidtide/tests/cleanposttest +4 -6
- rapidtide/tests/happycomp +9 -0
- rapidtide/tests/resethappytargets +1 -1
- rapidtide/tests/resetrapidtidetargets +1 -1
- rapidtide/tests/resettargets +1 -1
- rapidtide/tests/runlocaltest +3 -3
- rapidtide/tests/showkernels +1 -1
- rapidtide/tests/test_aliasedcorrelate.py +4 -4
- rapidtide/tests/test_aligntcs.py +1 -1
- rapidtide/tests/test_calcicc.py +1 -1
- rapidtide/tests/test_cleanregressor.py +184 -0
- rapidtide/tests/test_congrid.py +70 -81
- rapidtide/tests/test_correlate.py +1 -1
- rapidtide/tests/test_corrpass.py +4 -4
- rapidtide/tests/test_delayestimation.py +54 -59
- rapidtide/tests/test_dlfiltertorch.py +437 -0
- rapidtide/tests/test_doresample.py +2 -2
- rapidtide/tests/test_externaltools.py +69 -0
- rapidtide/tests/test_fastresampler.py +9 -5
- rapidtide/tests/test_filter.py +96 -57
- rapidtide/tests/test_findmaxlag.py +50 -19
- rapidtide/tests/test_fullrunhappy_v1.py +15 -10
- rapidtide/tests/test_fullrunhappy_v2.py +19 -13
- rapidtide/tests/test_fullrunhappy_v3.py +28 -13
- rapidtide/tests/test_fullrunhappy_v4.py +30 -11
- rapidtide/tests/test_fullrunhappy_v5.py +62 -0
- rapidtide/tests/test_fullrunrapidtide_v1.py +61 -7
- rapidtide/tests/test_fullrunrapidtide_v2.py +27 -15
- rapidtide/tests/test_fullrunrapidtide_v3.py +28 -8
- rapidtide/tests/test_fullrunrapidtide_v4.py +16 -8
- rapidtide/tests/test_fullrunrapidtide_v5.py +15 -6
- rapidtide/tests/test_fullrunrapidtide_v6.py +142 -0
- rapidtide/tests/test_fullrunrapidtide_v7.py +114 -0
- rapidtide/tests/test_fullrunrapidtide_v8.py +66 -0
- rapidtide/tests/test_getparsers.py +158 -0
- rapidtide/tests/test_io.py +59 -18
- rapidtide/tests/{test_glmpass.py → test_linfitfiltpass.py} +10 -10
- rapidtide/tests/test_mi.py +1 -1
- rapidtide/tests/test_miscmath.py +1 -1
- rapidtide/tests/test_motionregress.py +5 -5
- rapidtide/tests/test_nullcorr.py +6 -9
- rapidtide/tests/test_padvec.py +216 -0
- rapidtide/tests/test_parserfuncs.py +101 -0
- rapidtide/tests/test_phaseanalysis.py +1 -1
- rapidtide/tests/test_rapidtideparser.py +59 -53
- rapidtide/tests/test_refinedelay.py +296 -0
- rapidtide/tests/test_runmisc.py +5 -5
- rapidtide/tests/test_sharedmem.py +60 -0
- rapidtide/tests/test_simroundtrip.py +132 -0
- rapidtide/tests/test_simulate.py +1 -1
- rapidtide/tests/test_stcorrelate.py +4 -2
- rapidtide/tests/test_timeshift.py +2 -2
- rapidtide/tests/test_valtoindex.py +1 -1
- rapidtide/tests/test_zRapidtideDataset.py +5 -3
- rapidtide/tests/utils.py +10 -9
- rapidtide/tidepoolTemplate.py +88 -70
- rapidtide/tidepoolTemplate.ui +60 -46
- rapidtide/tidepoolTemplate_alt.py +88 -53
- rapidtide/tidepoolTemplate_alt.ui +62 -52
- rapidtide/tidepoolTemplate_alt_qt6.py +921 -0
- rapidtide/tidepoolTemplate_big.py +1125 -0
- rapidtide/tidepoolTemplate_big.ui +2386 -0
- rapidtide/tidepoolTemplate_big_qt6.py +1129 -0
- rapidtide/tidepoolTemplate_qt6.py +793 -0
- rapidtide/util.py +1389 -148
- rapidtide/voxelData.py +1048 -0
- rapidtide/wiener.py +138 -25
- rapidtide/wiener2.py +114 -8
- rapidtide/workflows/adjustoffset.py +107 -5
- rapidtide/workflows/aligntcs.py +86 -3
- rapidtide/workflows/applydlfilter.py +231 -89
- rapidtide/workflows/applyppgproc.py +540 -0
- rapidtide/workflows/atlasaverage.py +309 -48
- rapidtide/workflows/atlastool.py +130 -9
- rapidtide/workflows/calcSimFuncMap.py +490 -0
- rapidtide/workflows/calctexticc.py +202 -10
- rapidtide/workflows/ccorrica.py +123 -15
- rapidtide/workflows/cleanregressor.py +415 -0
- rapidtide/workflows/delayvar.py +1268 -0
- rapidtide/workflows/diffrois.py +84 -6
- rapidtide/workflows/endtidalproc.py +149 -9
- rapidtide/workflows/fdica.py +197 -17
- rapidtide/workflows/filtnifti.py +71 -4
- rapidtide/workflows/filttc.py +76 -5
- rapidtide/workflows/fitSimFuncMap.py +578 -0
- rapidtide/workflows/fixtr.py +74 -4
- rapidtide/workflows/gmscalc.py +116 -6
- rapidtide/workflows/happy.py +1242 -480
- rapidtide/workflows/happy2std.py +145 -13
- rapidtide/workflows/happy_parser.py +277 -59
- rapidtide/workflows/histnifti.py +120 -4
- rapidtide/workflows/histtc.py +85 -4
- rapidtide/workflows/{glmfilt.py → linfitfilt.py} +128 -14
- rapidtide/workflows/localflow.py +329 -29
- rapidtide/workflows/mergequality.py +80 -4
- rapidtide/workflows/niftidecomp.py +323 -19
- rapidtide/workflows/niftistats.py +178 -8
- rapidtide/workflows/pairproc.py +99 -5
- rapidtide/workflows/pairwisemergenifti.py +86 -3
- rapidtide/workflows/parser_funcs.py +1488 -56
- rapidtide/workflows/physiofreq.py +139 -12
- rapidtide/workflows/pixelcomp.py +211 -9
- rapidtide/workflows/plethquality.py +105 -23
- rapidtide/workflows/polyfitim.py +159 -19
- rapidtide/workflows/proj2flow.py +76 -3
- rapidtide/workflows/rankimage.py +115 -8
- rapidtide/workflows/rapidtide.py +1833 -1919
- rapidtide/workflows/rapidtide2std.py +101 -3
- rapidtide/workflows/rapidtide_parser.py +607 -372
- rapidtide/workflows/refineDelayMap.py +249 -0
- rapidtide/workflows/refineRegressor.py +1215 -0
- rapidtide/workflows/regressfrommaps.py +308 -0
- rapidtide/workflows/resamplenifti.py +86 -4
- rapidtide/workflows/resampletc.py +92 -4
- rapidtide/workflows/retrolagtcs.py +442 -0
- rapidtide/workflows/retroregress.py +1501 -0
- rapidtide/workflows/roisummarize.py +176 -7
- rapidtide/workflows/runqualitycheck.py +72 -7
- rapidtide/workflows/showarbcorr.py +172 -16
- rapidtide/workflows/showhist.py +87 -3
- rapidtide/workflows/showstxcorr.py +161 -4
- rapidtide/workflows/showtc.py +172 -10
- rapidtide/workflows/showxcorrx.py +250 -62
- rapidtide/workflows/showxy.py +186 -16
- rapidtide/workflows/simdata.py +418 -112
- rapidtide/workflows/spatialfit.py +83 -8
- rapidtide/workflows/spatialmi.py +252 -29
- rapidtide/workflows/spectrogram.py +306 -33
- rapidtide/workflows/synthASL.py +157 -6
- rapidtide/workflows/tcfrom2col.py +77 -3
- rapidtide/workflows/tcfrom3col.py +75 -3
- rapidtide/workflows/tidepool.py +3829 -666
- rapidtide/workflows/utils.py +45 -19
- rapidtide/workflows/utils_doc.py +293 -0
- rapidtide/workflows/variabilityizer.py +118 -5
- {rapidtide-2.9.5.dist-info → rapidtide-3.1.3.dist-info}/METADATA +30 -223
- rapidtide-3.1.3.dist-info/RECORD +393 -0
- {rapidtide-2.9.5.dist-info → rapidtide-3.1.3.dist-info}/WHEEL +1 -1
- rapidtide-3.1.3.dist-info/entry_points.txt +65 -0
- rapidtide-3.1.3.dist-info/top_level.txt +2 -0
- rapidtide/calcandfitcorrpairs.py +0 -262
- rapidtide/data/examples/src/testoutputsize +0 -45
- rapidtide/data/models/model_revised/model.h5 +0 -0
- rapidtide/data/models/model_serdar/model.h5 +0 -0
- rapidtide/data/models/model_serdar2/model.h5 +0 -0
- rapidtide/data/reference/ASPECTS_nlin_asym_09c_2mm.nii.gz +0 -0
- rapidtide/data/reference/ASPECTS_nlin_asym_09c_2mm_mask.nii.gz +0 -0
- rapidtide/data/reference/ATTbasedFlowTerritories_split_nlin_asym_09c_2mm.nii.gz +0 -0
- rapidtide/data/reference/ATTbasedFlowTerritories_split_nlin_asym_09c_2mm_mask.nii.gz +0 -0
- rapidtide/data/reference/HCP1200_binmask_2mm_2009c_asym.nii.gz +0 -0
- rapidtide/data/reference/HCP1200_lag_2mm_2009c_asym.nii.gz +0 -0
- rapidtide/data/reference/HCP1200_mask_2mm_2009c_asym.nii.gz +0 -0
- rapidtide/data/reference/HCP1200_negmask_2mm_2009c_asym.nii.gz +0 -0
- rapidtide/data/reference/HCP1200_sigma_2mm_2009c_asym.nii.gz +0 -0
- rapidtide/data/reference/HCP1200_strength_2mm_2009c_asym.nii.gz +0 -0
- rapidtide/glmpass.py +0 -434
- rapidtide/refine_factored.py +0 -641
- rapidtide/scripts/retroglm +0 -23
- rapidtide/workflows/glmfrommaps.py +0 -202
- rapidtide/workflows/retroglm.py +0 -643
- rapidtide-2.9.5.data/scripts/adjustoffset +0 -23
- rapidtide-2.9.5.data/scripts/aligntcs +0 -23
- rapidtide-2.9.5.data/scripts/applydlfilter +0 -23
- rapidtide-2.9.5.data/scripts/atlasaverage +0 -23
- rapidtide-2.9.5.data/scripts/atlastool +0 -23
- rapidtide-2.9.5.data/scripts/calcicc +0 -22
- rapidtide-2.9.5.data/scripts/calctexticc +0 -23
- rapidtide-2.9.5.data/scripts/calcttest +0 -22
- rapidtide-2.9.5.data/scripts/ccorrica +0 -23
- rapidtide-2.9.5.data/scripts/diffrois +0 -23
- rapidtide-2.9.5.data/scripts/endtidalproc +0 -23
- rapidtide-2.9.5.data/scripts/filtnifti +0 -23
- rapidtide-2.9.5.data/scripts/filttc +0 -23
- rapidtide-2.9.5.data/scripts/fingerprint +0 -593
- rapidtide-2.9.5.data/scripts/fixtr +0 -23
- rapidtide-2.9.5.data/scripts/glmfilt +0 -24
- rapidtide-2.9.5.data/scripts/gmscalc +0 -22
- rapidtide-2.9.5.data/scripts/happy +0 -25
- rapidtide-2.9.5.data/scripts/happy2std +0 -23
- rapidtide-2.9.5.data/scripts/happywarp +0 -350
- rapidtide-2.9.5.data/scripts/histnifti +0 -23
- rapidtide-2.9.5.data/scripts/histtc +0 -23
- rapidtide-2.9.5.data/scripts/localflow +0 -23
- rapidtide-2.9.5.data/scripts/mergequality +0 -23
- rapidtide-2.9.5.data/scripts/pairproc +0 -23
- rapidtide-2.9.5.data/scripts/pairwisemergenifti +0 -23
- rapidtide-2.9.5.data/scripts/physiofreq +0 -23
- rapidtide-2.9.5.data/scripts/pixelcomp +0 -23
- rapidtide-2.9.5.data/scripts/plethquality +0 -23
- rapidtide-2.9.5.data/scripts/polyfitim +0 -23
- rapidtide-2.9.5.data/scripts/proj2flow +0 -23
- rapidtide-2.9.5.data/scripts/rankimage +0 -23
- rapidtide-2.9.5.data/scripts/rapidtide +0 -23
- rapidtide-2.9.5.data/scripts/rapidtide2std +0 -23
- rapidtide-2.9.5.data/scripts/resamplenifti +0 -23
- rapidtide-2.9.5.data/scripts/resampletc +0 -23
- rapidtide-2.9.5.data/scripts/retroglm +0 -23
- rapidtide-2.9.5.data/scripts/roisummarize +0 -23
- rapidtide-2.9.5.data/scripts/runqualitycheck +0 -23
- rapidtide-2.9.5.data/scripts/showarbcorr +0 -23
- rapidtide-2.9.5.data/scripts/showhist +0 -23
- rapidtide-2.9.5.data/scripts/showstxcorr +0 -23
- rapidtide-2.9.5.data/scripts/showtc +0 -23
- rapidtide-2.9.5.data/scripts/showxcorr_legacy +0 -536
- rapidtide-2.9.5.data/scripts/showxcorrx +0 -23
- rapidtide-2.9.5.data/scripts/showxy +0 -23
- rapidtide-2.9.5.data/scripts/simdata +0 -23
- rapidtide-2.9.5.data/scripts/spatialdecomp +0 -23
- rapidtide-2.9.5.data/scripts/spatialfit +0 -23
- rapidtide-2.9.5.data/scripts/spatialmi +0 -23
- rapidtide-2.9.5.data/scripts/spectrogram +0 -23
- rapidtide-2.9.5.data/scripts/synthASL +0 -23
- rapidtide-2.9.5.data/scripts/tcfrom2col +0 -23
- rapidtide-2.9.5.data/scripts/tcfrom3col +0 -23
- rapidtide-2.9.5.data/scripts/temporaldecomp +0 -23
- rapidtide-2.9.5.data/scripts/threeD +0 -236
- rapidtide-2.9.5.data/scripts/tidepool +0 -23
- rapidtide-2.9.5.data/scripts/variabilityizer +0 -23
- rapidtide-2.9.5.dist-info/RECORD +0 -357
- rapidtide-2.9.5.dist-info/top_level.txt +0 -86
- {rapidtide-2.9.5.dist-info → rapidtide-3.1.3.dist-info/licenses}/LICENSE +0 -0
rapidtide/OrthoImageItem.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,12 +19,12 @@
|
|
|
19
19
|
"""
|
|
20
20
|
A widget for orthographically displaying 3 and 4 dimensional data
|
|
21
21
|
"""
|
|
22
|
-
|
|
23
|
-
import copy
|
|
24
22
|
import os
|
|
23
|
+
from typing import Any
|
|
25
24
|
|
|
26
25
|
import numpy as np
|
|
27
26
|
import pyqtgraph as pg
|
|
27
|
+
from numpy.typing import NDArray
|
|
28
28
|
from pyqtgraph.Qt import QtCore, QtGui, QtWidgets
|
|
29
29
|
|
|
30
30
|
try:
|
|
@@ -34,8 +34,69 @@ try:
|
|
|
34
34
|
except ImportError:
|
|
35
35
|
PILexists = False
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
try:
|
|
38
|
+
from PySide6.QtCore import __version__
|
|
39
|
+
except ImportError:
|
|
40
|
+
try:
|
|
41
|
+
from PyQt6.QtCore import QT_VERSION_STR
|
|
42
|
+
except ImportError:
|
|
43
|
+
pyqtbinding = "pyqt5"
|
|
44
|
+
else:
|
|
45
|
+
pyqtbinding = "pyqt6"
|
|
46
|
+
else:
|
|
47
|
+
pyqtbinding = "pyside6"
|
|
48
|
+
print(f"using {pyqtbinding=}")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def newColorbar(
|
|
52
|
+
left: float, top: float, impixpervoxx: float, impixpervoxy: float, imgsize: int
|
|
53
|
+
) -> tuple[Any, Any, Any, NDArray[np.float64]]:
|
|
54
|
+
"""
|
|
55
|
+
Create a colorbar widget with foreground and background image items for plotting.
|
|
56
|
+
|
|
57
|
+
This function generates a colorbar using PyGraphQt (pg) components, including
|
|
58
|
+
a foreground and background `ImageItem`, a `ViewBox` for layout control, and
|
|
59
|
+
a 2D array of color values. The colorbar is scaled and positioned according
|
|
60
|
+
to the provided parameters.
|
|
61
|
+
|
|
62
|
+
Parameters
|
|
63
|
+
----------
|
|
64
|
+
left : float
|
|
65
|
+
The x-coordinate of the top-left corner of the colorbar in the scene.
|
|
66
|
+
top : float
|
|
67
|
+
The y-coordinate of the top-left corner of the colorbar in the scene.
|
|
68
|
+
impixpervoxx : float
|
|
69
|
+
Scaling factor for the horizontal axis (pixel per unit in x-direction).
|
|
70
|
+
impixpervoxy : float
|
|
71
|
+
Scaling factor for the vertical axis (pixel per unit in y-direction).
|
|
72
|
+
imgsize : int
|
|
73
|
+
The size of the colorbar image in pixels, used to determine dimensions.
|
|
74
|
+
|
|
75
|
+
Returns
|
|
76
|
+
-------
|
|
77
|
+
tuple[Any, Any, Any, NDArray[np.float64]]
|
|
78
|
+
A tuple containing:
|
|
79
|
+
- `thecolorbarfgwin`: The foreground `ImageItem` for the colorbar.
|
|
80
|
+
- `thecolorbarbgwin`: The background `ImageItem` for the colorbar.
|
|
81
|
+
- `theviewbox`: The `ViewBox` that contains the colorbar items.
|
|
82
|
+
- `colorbarvals`: A 2D NumPy array of shape `(cb_xdim, cb_ydim)` with
|
|
83
|
+
color values ranging from 0.0 to 1.0, used for rendering the colorbar.
|
|
84
|
+
|
|
85
|
+
Notes
|
|
86
|
+
-----
|
|
87
|
+
The colorbar uses a linear gradient from black (0.0) to white (1.0) along the
|
|
88
|
+
vertical axis. The horizontal dimension is set to 1/10th of `imgsize`, and
|
|
89
|
+
the vertical dimension equals `imgsize`. The `ViewBox` is configured to disable
|
|
90
|
+
auto-ranging and mouse interaction.
|
|
91
|
+
|
|
92
|
+
Examples
|
|
93
|
+
--------
|
|
94
|
+
>>> fg_item, bg_item, view_box, color_vals = newColorbar(
|
|
95
|
+
... left=100, top=50, impixpervoxx=1.0, impixpervoxy=1.0, imgsize=256
|
|
96
|
+
... )
|
|
97
|
+
>>> view_box.addItem(fg_item)
|
|
98
|
+
>>> view_box.addItem(bg_item)
|
|
99
|
+
"""
|
|
39
100
|
cb_xdim = imgsize // 10
|
|
40
101
|
cb_ydim = imgsize
|
|
41
102
|
theviewbox = pg.ViewBox(enableMouse=False)
|
|
@@ -68,7 +129,65 @@ def newColorbar(left, top, impixpervoxx, impixpervoxy, imgsize):
|
|
|
68
129
|
return thecolorbarfgwin, thecolorbarbgwin, theviewbox, colorbarvals
|
|
69
130
|
|
|
70
131
|
|
|
71
|
-
def
|
|
132
|
+
def setupViewWindow(
|
|
133
|
+
view: Any,
|
|
134
|
+
left: float,
|
|
135
|
+
top: float,
|
|
136
|
+
impixpervoxx: float,
|
|
137
|
+
impixpervoxy: float,
|
|
138
|
+
imgsize: int,
|
|
139
|
+
enableMouse: bool = False,
|
|
140
|
+
) -> tuple[Any, Any, Any, Any, Any]:
|
|
141
|
+
"""
|
|
142
|
+
Set up a view window with background and foreground image items, and crosshair lines.
|
|
143
|
+
|
|
144
|
+
This function configures a PyGraphQt view box with specified image transformation
|
|
145
|
+
parameters and adds background and foreground image items along with vertical and
|
|
146
|
+
horizontal crosshair lines for visualization purposes.
|
|
147
|
+
|
|
148
|
+
Parameters
|
|
149
|
+
----------
|
|
150
|
+
view : Any
|
|
151
|
+
The parent view object to which the view box will be added.
|
|
152
|
+
left : float
|
|
153
|
+
The x-coordinate offset for the image transformation.
|
|
154
|
+
top : float
|
|
155
|
+
The y-coordinate offset for the image transformation.
|
|
156
|
+
impixpervoxx : float
|
|
157
|
+
The scaling factor for the horizontal axis of the image.
|
|
158
|
+
impixpervoxy : float
|
|
159
|
+
The scaling factor for the vertical axis of the image.
|
|
160
|
+
imgsize : int
|
|
161
|
+
The size of the image in pixels, used to set the view range.
|
|
162
|
+
enableMouse : bool, optional
|
|
163
|
+
Whether to enable mouse interaction with the view box. Default is False.
|
|
164
|
+
|
|
165
|
+
Returns
|
|
166
|
+
-------
|
|
167
|
+
tuple[Any, Any, Any, Any, Any]
|
|
168
|
+
A tuple containing:
|
|
169
|
+
- theviewfgwin: The foreground image item.
|
|
170
|
+
- theviewbgwin: The background image item.
|
|
171
|
+
- theviewvLine: The vertical crosshair line.
|
|
172
|
+
- theviewhLine: The horizontal crosshair line.
|
|
173
|
+
- theviewbox: The configured view box object.
|
|
174
|
+
|
|
175
|
+
Notes
|
|
176
|
+
-----
|
|
177
|
+
The view box is locked to a 1:1 aspect ratio and initialized with a gray background.
|
|
178
|
+
The transformation applied to both image items includes translation and scaling
|
|
179
|
+
to align the image properly within the view.
|
|
180
|
+
|
|
181
|
+
Examples
|
|
182
|
+
--------
|
|
183
|
+
>>> import pyqtgraph as pg
|
|
184
|
+
>>> from PyQt5 import QtCore, QtGui
|
|
185
|
+
>>> view = pg.GraphicsLayoutWidget()
|
|
186
|
+
>>> fgwin, bgwin, vline, hline, vbox = setupViewWindow(
|
|
187
|
+
... view, 0, 0, 1.0, 1.0, 256, enableMouse=True
|
|
188
|
+
... )
|
|
189
|
+
"""
|
|
190
|
+
|
|
72
191
|
theviewbox = view.addViewBox(enableMouse=enableMouse, enableMenu=False, lockAspect=1.0)
|
|
73
192
|
theviewbox.setAspectLocked()
|
|
74
193
|
theviewbox.setRange(QtCore.QRectF(0, 0, imgsize, imgsize), padding=0.0, disableAutoRange=True)
|
|
@@ -104,19 +223,72 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
104
223
|
|
|
105
224
|
def __init__(
|
|
106
225
|
self,
|
|
107
|
-
map,
|
|
108
|
-
axview,
|
|
109
|
-
corview,
|
|
110
|
-
sagview,
|
|
111
|
-
enableMouse=False,
|
|
112
|
-
button=None,
|
|
113
|
-
imgsize=64,
|
|
114
|
-
arrangement=0,
|
|
115
|
-
bgmap=None,
|
|
116
|
-
verbose=0,
|
|
117
|
-
):
|
|
226
|
+
map: Any,
|
|
227
|
+
axview: Any,
|
|
228
|
+
corview: Any,
|
|
229
|
+
sagview: Any,
|
|
230
|
+
enableMouse: bool = False,
|
|
231
|
+
button: Any | None = None,
|
|
232
|
+
imgsize: int = 64,
|
|
233
|
+
arrangement: int = 0,
|
|
234
|
+
bgmap: Any | None = None,
|
|
235
|
+
verbose: int = 0,
|
|
236
|
+
) -> None:
|
|
237
|
+
"""
|
|
238
|
+
Initialize the OrthoImageItem widget for displaying 3D medical images in orthogonal views.
|
|
239
|
+
|
|
240
|
+
This constructor sets up the necessary attributes and configurations for rendering
|
|
241
|
+
a 3D image volume in three orthogonal views (axial, coronal, and sagittal) using
|
|
242
|
+
PyQt and PySide. It handles coordinate transformations, view setup, and mouse interaction
|
|
243
|
+
if enabled.
|
|
244
|
+
|
|
245
|
+
Parameters
|
|
246
|
+
----------
|
|
247
|
+
map : Any
|
|
248
|
+
The 3D image data map object containing image dimensions and voxel information.
|
|
249
|
+
axview : Any
|
|
250
|
+
The axial view widget (e.g., a PySide QGraphicsView).
|
|
251
|
+
corview : Any
|
|
252
|
+
The coronal view widget (e.g., a PySide QGraphicsView).
|
|
253
|
+
sagview : Any
|
|
254
|
+
The sagittal view widget (e.g., a PySide QGraphicsView).
|
|
255
|
+
enableMouse : bool, optional
|
|
256
|
+
Whether to enable mouse interaction for navigating the views, by default False.
|
|
257
|
+
button : Any | None, optional
|
|
258
|
+
Mouse button used for interaction, by default None.
|
|
259
|
+
imgsize : int, optional
|
|
260
|
+
Size of the image display in pixels, by default 64.
|
|
261
|
+
arrangement : int, optional
|
|
262
|
+
Layout arrangement for the views, by default 0.
|
|
263
|
+
bgmap : Any | None, optional
|
|
264
|
+
Background image map for overlay, by default None.
|
|
265
|
+
verbose : int, optional
|
|
266
|
+
Verbosity level for printing debug information, by default 0.
|
|
267
|
+
|
|
268
|
+
Returns
|
|
269
|
+
-------
|
|
270
|
+
None
|
|
271
|
+
This method initializes the object and does not return any value.
|
|
272
|
+
|
|
273
|
+
Notes
|
|
274
|
+
-----
|
|
275
|
+
The method performs coordinate transformations to map voxel indices to physical space
|
|
276
|
+
and sets up the view ranges and layouts for each of the three orthogonal views.
|
|
277
|
+
If `enableMouse` is True, mouse event handlers are attached to allow navigation.
|
|
278
|
+
|
|
279
|
+
Examples
|
|
280
|
+
--------
|
|
281
|
+
>>> ortho_item = OrthoImageItem(
|
|
282
|
+
... map=volume_map,
|
|
283
|
+
... axview=axial_view,
|
|
284
|
+
... corview=coronal_view,
|
|
285
|
+
... sagview=sagittal_view,
|
|
286
|
+
... enableMouse=True
|
|
287
|
+
... )
|
|
288
|
+
"""
|
|
118
289
|
QtWidgets.QWidget.__init__(self)
|
|
119
290
|
self.map = map
|
|
291
|
+
self.mapname = self.map.label
|
|
120
292
|
self.bgmap = bgmap
|
|
121
293
|
self.axview = axview
|
|
122
294
|
self.corview = corview
|
|
@@ -146,9 +318,21 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
146
318
|
self.offsetx = self.imgsize * (0.5 - self.xfov / (2.0 * self.maxfov))
|
|
147
319
|
self.offsety = self.imgsize * (0.5 - self.yfov / (2.0 * self.maxfov))
|
|
148
320
|
self.offsetz = self.imgsize * (0.5 - self.zfov / (2.0 * self.maxfov))
|
|
321
|
+
self.axviewbox = None
|
|
322
|
+
self.corviewbox = None
|
|
323
|
+
self.sagviewbox = None
|
|
324
|
+
self.axviewwin = None
|
|
325
|
+
self.corviewwin = None
|
|
326
|
+
self.sagviewwin = None
|
|
327
|
+
self.axviewbgwin = None
|
|
328
|
+
self.corviewbgwin = None
|
|
329
|
+
self.sagviewbgwin = None
|
|
330
|
+
self.debug = True
|
|
331
|
+
self.arrangement = arrangement
|
|
149
332
|
|
|
150
333
|
if self.verbose > 1:
|
|
151
|
-
print("OrthoImageItem
|
|
334
|
+
print("OrthoImageItem initialization:")
|
|
335
|
+
print(" Map name:", self.mapname)
|
|
152
336
|
print(" Dimensions:", self.xdim, self.ydim, self.zdim)
|
|
153
337
|
print(" Voxel sizes:", self.xsize, self.ysize, self.zsize)
|
|
154
338
|
print(" FOVs:", self.xfov, self.yfov, self.zfov)
|
|
@@ -162,7 +346,6 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
162
346
|
print(" Offsets:", self.offsetx, self.offsety, self.offsetz)
|
|
163
347
|
self.buttonisdown = False
|
|
164
348
|
|
|
165
|
-
self.arrangement = arrangement
|
|
166
349
|
self.axview.setBackground(None)
|
|
167
350
|
self.axview.setRange(padding=0.0)
|
|
168
351
|
self.axview.ci.layout.setContentsMargins(0, 0, 0, 0)
|
|
@@ -182,7 +365,7 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
182
365
|
self.axviewvLine,
|
|
183
366
|
self.axviewhLine,
|
|
184
367
|
self.axviewbox,
|
|
185
|
-
) =
|
|
368
|
+
) = setupViewWindow(
|
|
186
369
|
self.axview,
|
|
187
370
|
self.offsetx,
|
|
188
371
|
self.offsety,
|
|
@@ -197,7 +380,7 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
197
380
|
self.corviewvLine,
|
|
198
381
|
self.corviewhLine,
|
|
199
382
|
self.corviewbox,
|
|
200
|
-
) =
|
|
383
|
+
) = setupViewWindow(
|
|
201
384
|
self.corview,
|
|
202
385
|
self.offsetx,
|
|
203
386
|
self.offsetz,
|
|
@@ -212,7 +395,7 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
212
395
|
self.sagviewvLine,
|
|
213
396
|
self.sagviewhLine,
|
|
214
397
|
self.sagviewbox,
|
|
215
|
-
) =
|
|
398
|
+
) = setupViewWindow(
|
|
216
399
|
self.sagview,
|
|
217
400
|
self.offsety,
|
|
218
401
|
self.offsetz,
|
|
@@ -236,16 +419,128 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
236
419
|
self.enableView()
|
|
237
420
|
self.updateAllViews()
|
|
238
421
|
|
|
239
|
-
def xvox2pix(self, xpos):
|
|
422
|
+
def xvox2pix(self, xpos: int) -> int:
|
|
423
|
+
"""
|
|
424
|
+
Convert voxel position to pixel position along x-axis.
|
|
425
|
+
|
|
426
|
+
Parameters
|
|
427
|
+
----------
|
|
428
|
+
xpos : int
|
|
429
|
+
Voxel position along x-axis to be converted to pixel coordinates.
|
|
430
|
+
|
|
431
|
+
Returns
|
|
432
|
+
-------
|
|
433
|
+
int
|
|
434
|
+
Corresponding pixel position along x-axis.
|
|
435
|
+
|
|
436
|
+
Notes
|
|
437
|
+
-----
|
|
438
|
+
This function performs a linear transformation from voxel coordinates to pixel coordinates
|
|
439
|
+
using the formula: pixel = offsetx + impixpervoxx * voxel_position
|
|
440
|
+
|
|
441
|
+
Examples
|
|
442
|
+
--------
|
|
443
|
+
>>> obj.xvox2pix(10)
|
|
444
|
+
15
|
|
445
|
+
>>> obj.xvox2pix(0)
|
|
446
|
+
5
|
|
447
|
+
"""
|
|
240
448
|
return int(np.round(self.offsetx + self.impixpervoxx * xpos))
|
|
241
449
|
|
|
242
|
-
def yvox2pix(self, ypos):
|
|
450
|
+
def yvox2pix(self, ypos: int) -> int:
|
|
451
|
+
"""
|
|
452
|
+
Convert voxel y-coordinate to pixel y-coordinate.
|
|
453
|
+
|
|
454
|
+
This function transforms a y-coordinate from voxel space to pixel space using
|
|
455
|
+
the transformation parameters stored in the object.
|
|
456
|
+
|
|
457
|
+
Parameters
|
|
458
|
+
----------
|
|
459
|
+
ypos : int
|
|
460
|
+
Y-coordinate in voxel space to be converted to pixel space.
|
|
461
|
+
|
|
462
|
+
Returns
|
|
463
|
+
-------
|
|
464
|
+
int
|
|
465
|
+
Y-coordinate in pixel space corresponding to the input voxel y-coordinate.
|
|
466
|
+
|
|
467
|
+
Notes
|
|
468
|
+
-----
|
|
469
|
+
The conversion follows the formula: pixel_y = offsety + impixpervoxy * voxel_y
|
|
470
|
+
where offsety and impixpervoxy are attributes of the object.
|
|
471
|
+
|
|
472
|
+
Examples
|
|
473
|
+
--------
|
|
474
|
+
>>> obj = MyClass()
|
|
475
|
+
>>> obj.offsety = 10
|
|
476
|
+
>>> obj.impixpervoxy = 2.5
|
|
477
|
+
>>> obj.yvox2pix(4)
|
|
478
|
+
20
|
|
479
|
+
"""
|
|
243
480
|
return int(np.round(self.offsety + self.impixpervoxy * ypos))
|
|
244
481
|
|
|
245
|
-
def zvox2pix(self, zpos):
|
|
482
|
+
def zvox2pix(self, zpos: int) -> int:
|
|
483
|
+
"""
|
|
484
|
+
Convert z-voxel position to pixel position.
|
|
485
|
+
|
|
486
|
+
This function transforms a z-coordinate in voxel space to its corresponding
|
|
487
|
+
position in pixel space using the camera's offset and pixel-per-voxel ratio.
|
|
488
|
+
|
|
489
|
+
Parameters
|
|
490
|
+
----------
|
|
491
|
+
zpos : int
|
|
492
|
+
Z-coordinate in voxel space to be converted to pixel space.
|
|
493
|
+
|
|
494
|
+
Returns
|
|
495
|
+
-------
|
|
496
|
+
int
|
|
497
|
+
Corresponding z-position in pixel space.
|
|
498
|
+
|
|
499
|
+
Notes
|
|
500
|
+
-----
|
|
501
|
+
The conversion follows the formula: pixel_position = offsetz + impixpervoxz * zpos
|
|
502
|
+
where:
|
|
503
|
+
- offsetz: base offset in pixel space
|
|
504
|
+
- impixpervoxz: pixels per voxel in z-direction
|
|
505
|
+
|
|
506
|
+
Examples
|
|
507
|
+
--------
|
|
508
|
+
>>> zvox2pix(10)
|
|
509
|
+
150
|
|
510
|
+
"""
|
|
246
511
|
return int(np.round(self.offsetz + self.impixpervoxz * zpos))
|
|
247
512
|
|
|
248
|
-
def xpix2vox(self, xpix):
|
|
513
|
+
def xpix2vox(self, xpix: float) -> int:
|
|
514
|
+
"""
|
|
515
|
+
Convert pixel coordinate to voxel coordinate in x-direction.
|
|
516
|
+
|
|
517
|
+
This function transforms a pixel coordinate in the x-direction to its
|
|
518
|
+
corresponding voxel coordinate, taking into account the image offset and
|
|
519
|
+
pixel-to-voxel conversion factors.
|
|
520
|
+
|
|
521
|
+
Parameters
|
|
522
|
+
----------
|
|
523
|
+
xpix : float
|
|
524
|
+
The pixel coordinate in x-direction to be converted to voxel coordinate.
|
|
525
|
+
|
|
526
|
+
Returns
|
|
527
|
+
-------
|
|
528
|
+
int
|
|
529
|
+
The corresponding voxel coordinate in x-direction, clamped to the
|
|
530
|
+
valid range [0, self.xdim-1].
|
|
531
|
+
|
|
532
|
+
Notes
|
|
533
|
+
-----
|
|
534
|
+
The conversion is performed using the formula: voxel = (pixel - offset) / pixels_per_voxel.
|
|
535
|
+
Edge cases are handled by clamping values to the valid voxel range.
|
|
536
|
+
|
|
537
|
+
Examples
|
|
538
|
+
--------
|
|
539
|
+
>>> # Assuming self.offsetx = 10, self.impixpervoxx = 2.0, self.xdim = 100
|
|
540
|
+
>>> result = self.xpix2vox(20.0)
|
|
541
|
+
>>> print(result)
|
|
542
|
+
5
|
|
543
|
+
"""
|
|
249
544
|
thepos = (xpix - self.offsetx) / self.impixpervoxx
|
|
250
545
|
if thepos > self.xdim - 1:
|
|
251
546
|
thepos = self.xdim - 1
|
|
@@ -253,7 +548,36 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
253
548
|
thepos = 0
|
|
254
549
|
return int(np.round(thepos))
|
|
255
550
|
|
|
256
|
-
def ypix2vox(self, ypix):
|
|
551
|
+
def ypix2vox(self, ypix: float) -> int:
|
|
552
|
+
"""
|
|
553
|
+
Convert y pixel coordinate to voxel coordinate.
|
|
554
|
+
|
|
555
|
+
This function transforms a y pixel coordinate in the image space to
|
|
556
|
+
the corresponding voxel coordinate in the volume space, taking into
|
|
557
|
+
account the image offset and pixel spacing.
|
|
558
|
+
|
|
559
|
+
Parameters
|
|
560
|
+
----------
|
|
561
|
+
ypix : float
|
|
562
|
+
Y pixel coordinate in image space
|
|
563
|
+
|
|
564
|
+
Returns
|
|
565
|
+
-------
|
|
566
|
+
int
|
|
567
|
+
Corresponding y voxel coordinate in volume space
|
|
568
|
+
|
|
569
|
+
Notes
|
|
570
|
+
-----
|
|
571
|
+
The conversion uses the formula: voxel = (pixel - offset) / pixels_per_voxel
|
|
572
|
+
Boundary conditions are enforced to ensure the result stays within valid
|
|
573
|
+
voxel range [0, ydim-1].
|
|
574
|
+
|
|
575
|
+
Examples
|
|
576
|
+
--------
|
|
577
|
+
>>> # Assuming self.offsety = 10, self.impixpervoxy = 2.0, self.ydim = 100
|
|
578
|
+
>>> ypix2vox(12) # Returns 1
|
|
579
|
+
>>> ypix2vox(200) # Returns 99 (clamped to maximum valid voxel)
|
|
580
|
+
"""
|
|
257
581
|
thepos = (ypix - self.offsety) / self.impixpervoxy
|
|
258
582
|
if thepos > self.ydim - 1:
|
|
259
583
|
thepos = self.ydim - 1
|
|
@@ -261,7 +585,40 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
261
585
|
thepos = 0
|
|
262
586
|
return int(np.round(thepos))
|
|
263
587
|
|
|
264
|
-
def zpix2vox(self, zpix):
|
|
588
|
+
def zpix2vox(self, zpix: float) -> int:
|
|
589
|
+
"""
|
|
590
|
+
Convert z-pixel coordinate to z-voxel coordinate.
|
|
591
|
+
|
|
592
|
+
This function transforms a z-pixel coordinate to the corresponding z-voxel
|
|
593
|
+
coordinate by applying the inverse transformation using the offset and
|
|
594
|
+
pixel-per-voxel parameters.
|
|
595
|
+
|
|
596
|
+
Parameters
|
|
597
|
+
----------
|
|
598
|
+
zpix : float
|
|
599
|
+
Z-pixel coordinate to be converted to voxel coordinate.
|
|
600
|
+
|
|
601
|
+
Returns
|
|
602
|
+
-------
|
|
603
|
+
int
|
|
604
|
+
Corresponding z-voxel coordinate. The result is clamped to the
|
|
605
|
+
valid range [0, self.zdim-1].
|
|
606
|
+
|
|
607
|
+
Notes
|
|
608
|
+
-----
|
|
609
|
+
The conversion is performed using the formula:
|
|
610
|
+
voxel = (zpix - offsetz) / impixpervoxz
|
|
611
|
+
|
|
612
|
+
If the resulting voxel coordinate exceeds the valid range [0, self.zdim-1],
|
|
613
|
+
it is clamped to the nearest boundary value.
|
|
614
|
+
|
|
615
|
+
Examples
|
|
616
|
+
--------
|
|
617
|
+
>>> # Assuming self.offsetz = 10, self.impixpervoxz = 2, self.zdim = 100
|
|
618
|
+
>>> zpix2vox(12) # Returns 1
|
|
619
|
+
>>> zpix2vox(10) # Returns 0
|
|
620
|
+
>>> zpix2vox(200) # Returns 99 (clamped to max)
|
|
621
|
+
"""
|
|
265
622
|
thepos = (zpix - self.offsetz) / self.impixpervoxz
|
|
266
623
|
if thepos > self.zdim - 1:
|
|
267
624
|
thepos = self.zdim - 1
|
|
@@ -269,7 +626,35 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
269
626
|
thepos = 0
|
|
270
627
|
return int(np.round(thepos))
|
|
271
628
|
|
|
272
|
-
def updateAllViews(self):
|
|
629
|
+
def updateAllViews(self) -> None:
|
|
630
|
+
"""
|
|
631
|
+
Update all three views (axial, coronal, and sagittal) of the visualization.
|
|
632
|
+
|
|
633
|
+
This function updates the axial, coronal, and sagittal views based on the current
|
|
634
|
+
position settings (`xpos`, `ypos`, `zpos`) and time index (`tpos`), using the
|
|
635
|
+
underlying data, mask, and background map if available. It also updates the
|
|
636
|
+
position lines in each view to reflect the current voxel coordinates.
|
|
637
|
+
|
|
638
|
+
Notes
|
|
639
|
+
-----
|
|
640
|
+
The function handles both 2D and 3D data depending on the value of `self.tdim`.
|
|
641
|
+
If `self.tdim == 1`, the data is treated as 2D; otherwise, it is treated as 3D
|
|
642
|
+
with a time dimension.
|
|
643
|
+
|
|
644
|
+
Parameters
|
|
645
|
+
----------
|
|
646
|
+
None
|
|
647
|
+
|
|
648
|
+
Returns
|
|
649
|
+
-------
|
|
650
|
+
None
|
|
651
|
+
This function does not return any value.
|
|
652
|
+
|
|
653
|
+
Examples
|
|
654
|
+
--------
|
|
655
|
+
>>> updateAllViews()
|
|
656
|
+
Updates all three views (axial, coronal, sagittal) with current data and position.
|
|
657
|
+
"""
|
|
273
658
|
if self.tdim == 1:
|
|
274
659
|
axdata = self.map.maskeddata[:, :, self.zpos]
|
|
275
660
|
else:
|
|
@@ -322,17 +707,123 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
322
707
|
self.sagviewvLine.setValue(self.yvox2pix(self.ypos))
|
|
323
708
|
self.sagviewhLine.setValue(self.zvox2pix(self.zpos))
|
|
324
709
|
|
|
325
|
-
def updateOneView(
|
|
710
|
+
def updateOneView(
|
|
711
|
+
self,
|
|
712
|
+
data: NDArray,
|
|
713
|
+
mask: NDArray,
|
|
714
|
+
background: NDArray | None,
|
|
715
|
+
theLUT: NDArray,
|
|
716
|
+
thefgwin: Any,
|
|
717
|
+
thebgwin: Any,
|
|
718
|
+
) -> None:
|
|
719
|
+
"""
|
|
720
|
+
Update the visualization view with processed data and optional background.
|
|
721
|
+
|
|
722
|
+
This function applies a lookup table to the input data, displays it in the
|
|
723
|
+
foreground window, and optionally displays a background image in the background window.
|
|
724
|
+
|
|
725
|
+
Parameters
|
|
726
|
+
----------
|
|
727
|
+
data : NDArray
|
|
728
|
+
The main data array to be processed and displayed.
|
|
729
|
+
mask : NDArray
|
|
730
|
+
The mask array used for data processing.
|
|
731
|
+
background : NDArray | None
|
|
732
|
+
The background data array to be displayed, or None if no background.
|
|
733
|
+
theLUT : NDArray
|
|
734
|
+
The lookup table array used for color mapping.
|
|
735
|
+
thefgwin : Any
|
|
736
|
+
The foreground window object where the processed data will be displayed.
|
|
737
|
+
thebgwin : Any
|
|
738
|
+
The background window object where the background data will be displayed.
|
|
739
|
+
|
|
740
|
+
Returns
|
|
741
|
+
-------
|
|
742
|
+
None
|
|
743
|
+
This function does not return any value.
|
|
744
|
+
|
|
745
|
+
Notes
|
|
746
|
+
-----
|
|
747
|
+
The function applies the lookup table using `self.applyLUT` method and sets
|
|
748
|
+
the image in the foreground window with float data type. If background is
|
|
749
|
+
provided, it is displayed in the background window with automatic level
|
|
750
|
+
adjustment enabled.
|
|
751
|
+
|
|
752
|
+
Examples
|
|
753
|
+
--------
|
|
754
|
+
>>> updateOneView(data, mask, background, theLUT, fg_window, bg_window)
|
|
755
|
+
"""
|
|
326
756
|
im = self.applyLUT(data, mask, theLUT, self.map.dispmin, self.map.dispmax)
|
|
327
757
|
thefgwin.setImage(im.astype("float"))
|
|
328
758
|
if background is not None:
|
|
329
759
|
thebgwin.setImage(background.astype("float"), autoLevels=True)
|
|
330
760
|
|
|
331
|
-
def setMap(self, themap):
|
|
761
|
+
def setMap(self, themap: Any) -> None:
|
|
762
|
+
"""
|
|
763
|
+
Set the map attribute and update related properties.
|
|
764
|
+
|
|
765
|
+
This method assigns the provided map to the instance and updates
|
|
766
|
+
the dimensionality and label properties based on the map's attributes.
|
|
767
|
+
|
|
768
|
+
Parameters
|
|
769
|
+
----------
|
|
770
|
+
themap : Any
|
|
771
|
+
The map object to be assigned to the instance. Expected to have
|
|
772
|
+
attributes 'tdim' (dimensionality) and 'label' (name/label).
|
|
773
|
+
|
|
774
|
+
Returns
|
|
775
|
+
-------
|
|
776
|
+
None
|
|
777
|
+
This method does not return any value.
|
|
778
|
+
|
|
779
|
+
Notes
|
|
780
|
+
-----
|
|
781
|
+
The method assumes that the input map object has 'tdim' and 'label'
|
|
782
|
+
attributes. If these attributes are not present, an AttributeError
|
|
783
|
+
will be raised.
|
|
784
|
+
|
|
785
|
+
Examples
|
|
786
|
+
--------
|
|
787
|
+
>>> instance.setMap(my_map)
|
|
788
|
+
>>> print(instance.tdim)
|
|
789
|
+
2
|
|
790
|
+
>>> print(instance.mapname)
|
|
791
|
+
'my_map_label'
|
|
792
|
+
"""
|
|
332
793
|
self.map = themap
|
|
333
794
|
self.tdim = self.map.tdim
|
|
334
|
-
|
|
335
|
-
|
|
795
|
+
self.mapname = self.map.label
|
|
796
|
+
|
|
797
|
+
def enableView(self) -> None:
|
|
798
|
+
"""
|
|
799
|
+
Enable and display all view components.
|
|
800
|
+
|
|
801
|
+
This method enables the main button and displays all three view components
|
|
802
|
+
(axial, coronal, and sagittal) by setting their visibility to True.
|
|
803
|
+
|
|
804
|
+
Parameters
|
|
805
|
+
----------
|
|
806
|
+
self : object
|
|
807
|
+
The instance of the class containing the view components and button.
|
|
808
|
+
|
|
809
|
+
Returns
|
|
810
|
+
-------
|
|
811
|
+
None
|
|
812
|
+
This method does not return any value.
|
|
813
|
+
|
|
814
|
+
Notes
|
|
815
|
+
-----
|
|
816
|
+
The method first checks if the button exists before attempting to modify it.
|
|
817
|
+
If the button exists, it updates the button text with the map label and enables
|
|
818
|
+
the button. All three view components (axview, corview, and sagview) are then
|
|
819
|
+
made visible.
|
|
820
|
+
|
|
821
|
+
Examples
|
|
822
|
+
--------
|
|
823
|
+
>>> viewer = Viewer()
|
|
824
|
+
>>> viewer.enableView()
|
|
825
|
+
>>> # All view components are now visible and button is enabled
|
|
826
|
+
"""
|
|
336
827
|
if self.button is not None:
|
|
337
828
|
self.button.setText(self.map.label)
|
|
338
829
|
self.button.setDisabled(False)
|
|
@@ -341,7 +832,47 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
341
832
|
self.corview.show()
|
|
342
833
|
self.sagview.show()
|
|
343
834
|
|
|
344
|
-
def applyLUT(
|
|
835
|
+
def applyLUT(
|
|
836
|
+
self, theimage: NDArray, mask: NDArray, theLUT: NDArray, dispmin: float, dispmax: float
|
|
837
|
+
) -> NDArray:
|
|
838
|
+
"""
|
|
839
|
+
Apply a lookup table to an image with optional masking and scaling.
|
|
840
|
+
|
|
841
|
+
This function maps image values to colors using a lookup table, applying
|
|
842
|
+
scaling based on the display range and masking invalid regions.
|
|
843
|
+
|
|
844
|
+
Parameters
|
|
845
|
+
----------
|
|
846
|
+
theimage : NDArray
|
|
847
|
+
Input image array to be mapped using the lookup table
|
|
848
|
+
mask : NDArray
|
|
849
|
+
Mask array where values less than 1 will be set to transparent (alpha = 0)
|
|
850
|
+
theLUT : NDArray
|
|
851
|
+
Lookup table array for color mapping, typically with shape (N, 4) for RGBA values
|
|
852
|
+
dispmin : float
|
|
853
|
+
Minimum display value for scaling the input image
|
|
854
|
+
dispmax : float
|
|
855
|
+
Maximum display value for scaling the input image
|
|
856
|
+
|
|
857
|
+
Returns
|
|
858
|
+
-------
|
|
859
|
+
NDArray
|
|
860
|
+
Mapped image array with the same shape as input image, with colors applied
|
|
861
|
+
from the lookup table and masked regions set to transparent
|
|
862
|
+
|
|
863
|
+
Notes
|
|
864
|
+
-----
|
|
865
|
+
The function performs the following operations:
|
|
866
|
+
1. Scales input image values to index range of the lookup table
|
|
867
|
+
2. Clamps scaled values to valid lookup table indices
|
|
868
|
+
3. Maps image values to colors using the lookup table
|
|
869
|
+
4. Applies mask to set transparent pixels where mask < 1
|
|
870
|
+
|
|
871
|
+
Examples
|
|
872
|
+
--------
|
|
873
|
+
>>> # Apply LUT to image with display range [0, 255]
|
|
874
|
+
>>> result = applyLUT(image, mask, lut, 0.0, 255.0)
|
|
875
|
+
"""
|
|
345
876
|
offset = dispmin
|
|
346
877
|
if dispmax - dispmin > 0:
|
|
347
878
|
scale = len(theLUT) / (dispmax - dispmin)
|
|
@@ -354,7 +885,48 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
354
885
|
mappeddata[:, :, 3][np.where(mask < 1)] = 0
|
|
355
886
|
return mappeddata
|
|
356
887
|
|
|
357
|
-
def updateCursors(self):
|
|
888
|
+
def updateCursors(self) -> None:
|
|
889
|
+
"""
|
|
890
|
+
Update cursor positions in all view axes based on voxel coordinates.
|
|
891
|
+
|
|
892
|
+
This method converts voxel coordinates to pixel coordinates for each view
|
|
893
|
+
and updates the corresponding cursor lines in the axial, coronal, and
|
|
894
|
+
sagittal views.
|
|
895
|
+
|
|
896
|
+
Parameters
|
|
897
|
+
----------
|
|
898
|
+
self : object
|
|
899
|
+
The instance containing the cursor update functionality
|
|
900
|
+
|
|
901
|
+
Returns
|
|
902
|
+
-------
|
|
903
|
+
None
|
|
904
|
+
This method does not return any value
|
|
905
|
+
|
|
906
|
+
Notes
|
|
907
|
+
-----
|
|
908
|
+
The method uses the following coordinate conversion methods:
|
|
909
|
+
- xvox2pix: converts x voxel coordinate to x pixel coordinate
|
|
910
|
+
- yvox2pix: converts y voxel coordinate to y pixel coordinate
|
|
911
|
+
- zvox2pix: converts z voxel coordinate to z pixel coordinate
|
|
912
|
+
|
|
913
|
+
The cursor lines are updated in the following views:
|
|
914
|
+
- axviewvLine: axial view vertical line
|
|
915
|
+
- axviewhLine: axial view horizontal line
|
|
916
|
+
- corviewvLine: coronal view vertical line
|
|
917
|
+
- corviewhLine: coronal view horizontal line
|
|
918
|
+
- sagviewvLine: sagittal view vertical line
|
|
919
|
+
- sagviewhLine: sagittal view horizontal line
|
|
920
|
+
|
|
921
|
+
Examples
|
|
922
|
+
--------
|
|
923
|
+
>>> viewer = Viewer()
|
|
924
|
+
>>> viewer.xpos = 10
|
|
925
|
+
>>> viewer.ypos = 15
|
|
926
|
+
>>> viewer.zpos = 20
|
|
927
|
+
>>> viewer.updateCursors()
|
|
928
|
+
>>> # Cursor positions updated in all three views
|
|
929
|
+
"""
|
|
358
930
|
xpix = self.xvox2pix(self.xpos)
|
|
359
931
|
ypix = self.yvox2pix(self.ypos)
|
|
360
932
|
zpix = self.zvox2pix(self.zpos)
|
|
@@ -365,60 +937,332 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
365
937
|
self.sagviewvLine.setValue(ypix)
|
|
366
938
|
self.sagviewhLine.setValue(zpix)
|
|
367
939
|
|
|
368
|
-
def handlemouseup(self, event):
|
|
940
|
+
def handlemouseup(self, event: Any) -> None:
|
|
941
|
+
"""
|
|
942
|
+
Handle mouse button up event.
|
|
943
|
+
|
|
944
|
+
This method is called when a mouse button is released. It updates the internal
|
|
945
|
+
state to reflect that the button is no longer pressed and refreshes all views
|
|
946
|
+
to ensure proper cursor representation and visual feedback.
|
|
947
|
+
|
|
948
|
+
Parameters
|
|
949
|
+
----------
|
|
950
|
+
event : Any
|
|
951
|
+
The mouse event object containing information about the mouse button release.
|
|
952
|
+
This typically includes coordinates and button information.
|
|
953
|
+
|
|
954
|
+
Returns
|
|
955
|
+
-------
|
|
956
|
+
None
|
|
957
|
+
This method does not return any value.
|
|
958
|
+
|
|
959
|
+
Notes
|
|
960
|
+
-----
|
|
961
|
+
This method updates the cursor state and triggers updates across all connected views
|
|
962
|
+
to ensure consistent visual representation of the mouse state.
|
|
963
|
+
|
|
964
|
+
Examples
|
|
965
|
+
--------
|
|
966
|
+
>>> widget.handlemouseup(event)
|
|
967
|
+
>>> # Mouse button state updated and views refreshed
|
|
968
|
+
"""
|
|
369
969
|
self.buttonisdown = False
|
|
370
970
|
self.updateCursors()
|
|
371
971
|
self.updateAllViews()
|
|
372
972
|
|
|
373
|
-
def handleaxmousemove(self, event):
|
|
973
|
+
def handleaxmousemove(self, event: Any) -> None:
|
|
974
|
+
"""
|
|
975
|
+
Handle mouse move events for axis navigation.
|
|
976
|
+
|
|
977
|
+
This method is called when the mouse is moved while a button is pressed,
|
|
978
|
+
updating the position coordinates and triggering view updates.
|
|
979
|
+
|
|
980
|
+
Parameters
|
|
981
|
+
----------
|
|
982
|
+
event : Any
|
|
983
|
+
Mouse event object containing position information. The event object
|
|
984
|
+
should have a `pos()` method that returns the mouse position.
|
|
985
|
+
|
|
986
|
+
Returns
|
|
987
|
+
-------
|
|
988
|
+
None
|
|
989
|
+
This method does not return any value.
|
|
990
|
+
|
|
991
|
+
Notes
|
|
992
|
+
-----
|
|
993
|
+
The method only processes mouse movement when `self.buttonisdown` is True.
|
|
994
|
+
Position coordinates are converted from pixel to voxel space using
|
|
995
|
+
`xpix2vox` and `ypix2vox` conversion methods. The image size is used to
|
|
996
|
+
properly map y-coordinates from pixel space to voxel space.
|
|
997
|
+
|
|
998
|
+
Examples
|
|
999
|
+
--------
|
|
1000
|
+
>>> # This method is typically called internally by the GUI framework
|
|
1001
|
+
>>> # when mouse events occur
|
|
1002
|
+
>>> self.handleaxmousemove(mouse_event)
|
|
1003
|
+
>>> # Updates self.xpos and self.ypos coordinates
|
|
1004
|
+
>>> # Triggers view updates and emits updated signal
|
|
1005
|
+
"""
|
|
374
1006
|
if self.buttonisdown:
|
|
375
1007
|
self.xpos = self.xpix2vox(event.pos().x() - 1)
|
|
376
1008
|
self.ypos = self.ypix2vox(self.imgsize - event.pos().y() + 1)
|
|
377
1009
|
self.updateAllViews()
|
|
378
1010
|
self.updated.emit()
|
|
379
1011
|
|
|
380
|
-
def handlecormousemove(self, event):
|
|
1012
|
+
def handlecormousemove(self, event: Any) -> None:
|
|
1013
|
+
"""
|
|
1014
|
+
Handle mouse move events for correlation function view navigation.
|
|
1015
|
+
|
|
1016
|
+
This method updates the x and z position coordinates based on mouse movement
|
|
1017
|
+
when a button is pressed. It converts pixel coordinates to voxel coordinates
|
|
1018
|
+
and triggers view updates and signal emission.
|
|
1019
|
+
|
|
1020
|
+
Parameters
|
|
1021
|
+
----------
|
|
1022
|
+
event : Any
|
|
1023
|
+
Mouse event object containing position information. Expected to have
|
|
1024
|
+
a `pos()` method that returns a position object with `x()` and `y()` methods.
|
|
1025
|
+
|
|
1026
|
+
Returns
|
|
1027
|
+
-------
|
|
1028
|
+
None
|
|
1029
|
+
This method does not return any value.
|
|
1030
|
+
|
|
1031
|
+
Notes
|
|
1032
|
+
-----
|
|
1033
|
+
The method only processes mouse movement when `self.buttonisdown` is True.
|
|
1034
|
+
Pixel coordinates are converted to voxel coordinates using:
|
|
1035
|
+
- x position: `xpix2vox(event.pos().x() - 1)`
|
|
1036
|
+
- z position: `zpix2vox(self.imgsize - event.pos().y() + 1)`
|
|
1037
|
+
|
|
1038
|
+
Examples
|
|
1039
|
+
--------
|
|
1040
|
+
>>> # This method is typically called internally by the GUI framework
|
|
1041
|
+
>>> # when mouse events occur in the correlative view
|
|
1042
|
+
>>> handlecormousemove(mouse_event)
|
|
1043
|
+
"""
|
|
381
1044
|
if self.buttonisdown:
|
|
382
1045
|
self.xpos = self.xpix2vox(event.pos().x() - 1)
|
|
383
1046
|
self.zpos = self.zpix2vox(self.imgsize - event.pos().y() + 1)
|
|
384
1047
|
self.updateAllViews()
|
|
385
1048
|
self.updated.emit()
|
|
386
1049
|
|
|
387
|
-
def handlesagmousemove(self, event):
|
|
1050
|
+
def handlesagmousemove(self, event: Any) -> None:
|
|
1051
|
+
"""
|
|
1052
|
+
Handle mouse move events for sagittal view navigation.
|
|
1053
|
+
|
|
1054
|
+
This method updates the y and z position coordinates when the mouse is moved
|
|
1055
|
+
while the button is pressed, and triggers view updates and signals.
|
|
1056
|
+
|
|
1057
|
+
Parameters
|
|
1058
|
+
----------
|
|
1059
|
+
event : Any
|
|
1060
|
+
Mouse event object containing position information. Expected to have
|
|
1061
|
+
a `pos()` method that returns a position object with `x()` and `y()` methods.
|
|
1062
|
+
|
|
1063
|
+
Returns
|
|
1064
|
+
-------
|
|
1065
|
+
None
|
|
1066
|
+
This method does not return any value.
|
|
1067
|
+
|
|
1068
|
+
Notes
|
|
1069
|
+
-----
|
|
1070
|
+
The method only processes mouse movement when `self.buttonisdown` is True.
|
|
1071
|
+
Position coordinates are converted from pixel to voxel space using
|
|
1072
|
+
`self.ypix2vox()` and `self.zpix2vox()` conversion methods.
|
|
1073
|
+
|
|
1074
|
+
Examples
|
|
1075
|
+
--------
|
|
1076
|
+
>>> self.handlesagmousemove(mouse_event)
|
|
1077
|
+
# Updates position coordinates and triggers view updates
|
|
1078
|
+
"""
|
|
388
1079
|
if self.buttonisdown:
|
|
389
1080
|
self.ypos = self.ypix2vox(event.pos().x() - 1)
|
|
390
1081
|
self.zpos = self.zpix2vox(self.imgsize - event.pos().y() + 1)
|
|
391
1082
|
self.updateAllViews()
|
|
392
1083
|
self.updated.emit()
|
|
393
1084
|
|
|
394
|
-
def handleaxkey(self, event):
|
|
1085
|
+
def handleaxkey(self, event: Any) -> None:
|
|
1086
|
+
"""
|
|
1087
|
+
Handle axis key events and update views.
|
|
1088
|
+
|
|
1089
|
+
This method is called when an axis key event occurs. It prints the event
|
|
1090
|
+
if verbose mode is enabled (verbose > 1), updates all views in the
|
|
1091
|
+
application, and emits an updated signal.
|
|
1092
|
+
|
|
1093
|
+
Parameters
|
|
1094
|
+
----------
|
|
1095
|
+
event : Any
|
|
1096
|
+
The axis key event object containing event information and data.
|
|
1097
|
+
|
|
1098
|
+
Returns
|
|
1099
|
+
-------
|
|
1100
|
+
None
|
|
1101
|
+
This method does not return any value.
|
|
1102
|
+
|
|
1103
|
+
Notes
|
|
1104
|
+
-----
|
|
1105
|
+
This method is typically used as an event handler for axis key events.
|
|
1106
|
+
The verbose flag controls whether event information is printed to stdout.
|
|
1107
|
+
|
|
1108
|
+
Examples
|
|
1109
|
+
--------
|
|
1110
|
+
>>> # Typically called internally by event system
|
|
1111
|
+
>>> self.handleaxkey(some_event_object)
|
|
1112
|
+
>>> # Output will be printed if self.verbose > 1
|
|
1113
|
+
"""
|
|
395
1114
|
if self.verbose > 1:
|
|
396
1115
|
print(event)
|
|
397
1116
|
self.updateAllViews()
|
|
398
1117
|
self.updated.emit()
|
|
399
1118
|
|
|
400
|
-
def handleaxclick(self, event):
|
|
1119
|
+
def handleaxclick(self, event: Any) -> None:
|
|
1120
|
+
"""
|
|
1121
|
+
Handle mouse click events on the axis.
|
|
1122
|
+
|
|
1123
|
+
This method processes mouse click events to convert pixel coordinates to voxel coordinates,
|
|
1124
|
+
updates the button state, and triggers view updates.
|
|
1125
|
+
|
|
1126
|
+
Parameters
|
|
1127
|
+
----------
|
|
1128
|
+
event : Any
|
|
1129
|
+
Mouse event object containing position information. Expected to have a `pos()` method
|
|
1130
|
+
that returns a position object with `x()` and `y()` methods.
|
|
1131
|
+
|
|
1132
|
+
Returns
|
|
1133
|
+
-------
|
|
1134
|
+
None
|
|
1135
|
+
This method does not return any value.
|
|
1136
|
+
|
|
1137
|
+
Notes
|
|
1138
|
+
-----
|
|
1139
|
+
The method converts pixel coordinates to voxel coordinates using the following transformations:
|
|
1140
|
+
- x-coordinate: xpix2vox(event.pos().x() - 1)
|
|
1141
|
+
- y-coordinate: ypix2vox(self.imgsize - event.pos().y() + 1)
|
|
1142
|
+
|
|
1143
|
+
The y-coordinate transformation accounts for the difference between pixel coordinate systems
|
|
1144
|
+
where (0,0) is typically at the top-left corner, and voxel coordinate systems where (0,0)
|
|
1145
|
+
is at the bottom-left corner.
|
|
1146
|
+
|
|
1147
|
+
Examples
|
|
1148
|
+
--------
|
|
1149
|
+
>>> handleaxclick(event)
|
|
1150
|
+
# Processes the mouse click event and updates internal state
|
|
1151
|
+
"""
|
|
401
1152
|
self.xpos = self.xpix2vox(event.pos().x() - 1)
|
|
402
1153
|
self.ypos = self.ypix2vox(self.imgsize - event.pos().y() + 1)
|
|
403
1154
|
self.buttonisdown = True
|
|
404
1155
|
self.updateAllViews()
|
|
405
1156
|
self.updated.emit()
|
|
406
1157
|
|
|
407
|
-
def handlecorclick(self, event):
|
|
1158
|
+
def handlecorclick(self, event: Any) -> None:
|
|
1159
|
+
"""
|
|
1160
|
+
Handle mouse click event for coordinate conversion and view update.
|
|
1161
|
+
|
|
1162
|
+
This method processes mouse click events to convert pixel coordinates to voxel coordinates,
|
|
1163
|
+
updates the button state, and triggers view updates and signals.
|
|
1164
|
+
|
|
1165
|
+
Parameters
|
|
1166
|
+
----------
|
|
1167
|
+
event : Any
|
|
1168
|
+
Mouse event object containing position information. Expected to have a `pos()` method
|
|
1169
|
+
that returns a point with `x()` and `y()` coordinate methods.
|
|
1170
|
+
|
|
1171
|
+
Returns
|
|
1172
|
+
-------
|
|
1173
|
+
None
|
|
1174
|
+
This method does not return any value.
|
|
1175
|
+
|
|
1176
|
+
Notes
|
|
1177
|
+
-----
|
|
1178
|
+
The method converts pixel coordinates to voxel coordinates using:
|
|
1179
|
+
- x coordinate: `xpix2vox(event.pos().x() - 1)`
|
|
1180
|
+
- z coordinate: `zpix2vox(self.imgsize - event.pos().y() + 1)`
|
|
1181
|
+
|
|
1182
|
+
The coordinate transformation accounts for pixel indexing differences and image orientation.
|
|
1183
|
+
|
|
1184
|
+
Examples
|
|
1185
|
+
--------
|
|
1186
|
+
>>> # Typical usage in event handling context
|
|
1187
|
+
>>> self.handlecorclick(mouse_event)
|
|
1188
|
+
>>> # Updates self.xpos, self.zpos, self.buttonisdown and triggers updates
|
|
1189
|
+
"""
|
|
408
1190
|
self.xpos = self.xpix2vox(event.pos().x() - 1)
|
|
409
1191
|
self.zpos = self.zpix2vox(self.imgsize - event.pos().y() + 1)
|
|
410
1192
|
self.buttonisdown = True
|
|
411
1193
|
self.updateAllViews()
|
|
412
1194
|
self.updated.emit()
|
|
413
1195
|
|
|
414
|
-
def handlesagclick(self, event):
|
|
1196
|
+
def handlesagclick(self, event: Any) -> None:
|
|
1197
|
+
"""
|
|
1198
|
+
Handle mouse click events for sagittal view navigation.
|
|
1199
|
+
|
|
1200
|
+
This method processes mouse click events in the sagittal view, converting pixel
|
|
1201
|
+
coordinates to voxel coordinates and updating the view accordingly.
|
|
1202
|
+
|
|
1203
|
+
Parameters
|
|
1204
|
+
----------
|
|
1205
|
+
event : Any
|
|
1206
|
+
Mouse event object containing position information. Expected to have a
|
|
1207
|
+
`pos()` method that returns a position object with `x()` and `y()` methods.
|
|
1208
|
+
|
|
1209
|
+
Returns
|
|
1210
|
+
-------
|
|
1211
|
+
None
|
|
1212
|
+
This method does not return any value.
|
|
1213
|
+
|
|
1214
|
+
Notes
|
|
1215
|
+
-----
|
|
1216
|
+
The method updates internal position variables (ypos, zpos) and triggers
|
|
1217
|
+
view updates through the updateAllViews() method and updated.emit() signal.
|
|
1218
|
+
The pixel coordinates are adjusted by subtracting 1 from x and adding 1 to y
|
|
1219
|
+
for proper coordinate system alignment.
|
|
1220
|
+
|
|
1221
|
+
Examples
|
|
1222
|
+
--------
|
|
1223
|
+
>>> viewer = ImageViewer()
|
|
1224
|
+
>>> event = MouseEvent(pos=QPoint(100, 150))
|
|
1225
|
+
>>> viewer.handlesagclick(event)
|
|
1226
|
+
>>> print(viewer.ypos, viewer.zpos)
|
|
1227
|
+
(0.5, 0.75)
|
|
1228
|
+
"""
|
|
415
1229
|
self.ypos = self.ypix2vox(event.pos().x() - 1)
|
|
416
1230
|
self.zpos = self.zpix2vox(self.imgsize - event.pos().y() + 1)
|
|
417
1231
|
self.buttonisdown = True
|
|
418
1232
|
self.updateAllViews()
|
|
419
1233
|
self.updated.emit()
|
|
420
1234
|
|
|
421
|
-
def setXYZpos(self, xpos, ypos, zpos, emitsignal=True):
|
|
1235
|
+
def setXYZpos(self, xpos: int, ypos: int, zpos: int, emitsignal: bool = True) -> None:
|
|
1236
|
+
"""
|
|
1237
|
+
Set the XYZ position coordinates and update views.
|
|
1238
|
+
|
|
1239
|
+
Parameters
|
|
1240
|
+
----------
|
|
1241
|
+
xpos : int
|
|
1242
|
+
The x-coordinate position value.
|
|
1243
|
+
ypos : int
|
|
1244
|
+
The y-coordinate position value.
|
|
1245
|
+
zpos : int
|
|
1246
|
+
The z-coordinate position value.
|
|
1247
|
+
emitsignal : bool, optional
|
|
1248
|
+
If True, emit the updated signal after position change (default is True).
|
|
1249
|
+
|
|
1250
|
+
Returns
|
|
1251
|
+
-------
|
|
1252
|
+
None
|
|
1253
|
+
This method does not return any value.
|
|
1254
|
+
|
|
1255
|
+
Notes
|
|
1256
|
+
-----
|
|
1257
|
+
This method converts all position parameters to integers and updates
|
|
1258
|
+
all views through the updateAllViews() call. The updated signal is
|
|
1259
|
+
only emitted when emitsignal is True.
|
|
1260
|
+
|
|
1261
|
+
Examples
|
|
1262
|
+
--------
|
|
1263
|
+
>>> obj.setXYZpos(10, 20, 30)
|
|
1264
|
+
>>> obj.setXYZpos(5, 15, 25, emitsignal=False)
|
|
1265
|
+
"""
|
|
422
1266
|
self.xpos = int(xpos)
|
|
423
1267
|
self.ypos = int(ypos)
|
|
424
1268
|
self.zpos = int(zpos)
|
|
@@ -426,7 +1270,37 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
426
1270
|
if emitsignal:
|
|
427
1271
|
self.updated.emit()
|
|
428
1272
|
|
|
429
|
-
def setTpos(self, tpos, emitsignal=True):
|
|
1273
|
+
def setTpos(self, tpos: int, emitsignal: bool = True) -> None:
|
|
1274
|
+
"""
|
|
1275
|
+
Set the current time position and update all views.
|
|
1276
|
+
|
|
1277
|
+
This method updates the internal time position counter and triggers
|
|
1278
|
+
view updates. If emitsignal is True, it also emits the updated signal.
|
|
1279
|
+
|
|
1280
|
+
Parameters
|
|
1281
|
+
----------
|
|
1282
|
+
tpos : int
|
|
1283
|
+
The new time position to set. If tpos exceeds the maximum allowed
|
|
1284
|
+
time position (self.tdim - 1), it will be clamped to the maximum value.
|
|
1285
|
+
emitsignal : bool, optional
|
|
1286
|
+
If True, emit the updated signal after updating the time position.
|
|
1287
|
+
Default is True.
|
|
1288
|
+
|
|
1289
|
+
Returns
|
|
1290
|
+
-------
|
|
1291
|
+
None
|
|
1292
|
+
This method does not return any value.
|
|
1293
|
+
|
|
1294
|
+
Notes
|
|
1295
|
+
-----
|
|
1296
|
+
The time position is automatically clamped to the valid range [0, self.tdim - 1].
|
|
1297
|
+
This ensures that the time position never exceeds the dimension limits.
|
|
1298
|
+
|
|
1299
|
+
Examples
|
|
1300
|
+
--------
|
|
1301
|
+
>>> obj.setTpos(5)
|
|
1302
|
+
>>> obj.setTpos(10, emitsignal=False)
|
|
1303
|
+
"""
|
|
430
1304
|
if tpos > self.tdim - 1:
|
|
431
1305
|
self.tpos = int(self.tdim - 1)
|
|
432
1306
|
else:
|
|
@@ -436,13 +1310,103 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
436
1310
|
if emitsignal:
|
|
437
1311
|
self.updated.emit()
|
|
438
1312
|
|
|
439
|
-
def getFocusVal(self):
|
|
1313
|
+
def getFocusVal(self) -> float:
|
|
1314
|
+
"""
|
|
1315
|
+
Get the focus value at the current position.
|
|
1316
|
+
|
|
1317
|
+
This method retrieves the data value from the masked data array at the
|
|
1318
|
+
current position coordinates. The method handles both 3D and 4D data arrays
|
|
1319
|
+
by checking the time dimension.
|
|
1320
|
+
|
|
1321
|
+
Parameters
|
|
1322
|
+
----------
|
|
1323
|
+
self : object
|
|
1324
|
+
The instance containing the data and position attributes.
|
|
1325
|
+
|
|
1326
|
+
Returns
|
|
1327
|
+
-------
|
|
1328
|
+
float
|
|
1329
|
+
The focus value at the current position. Returns a scalar value
|
|
1330
|
+
from the masked data array.
|
|
1331
|
+
|
|
1332
|
+
Notes
|
|
1333
|
+
-----
|
|
1334
|
+
The method uses the following attributes from the instance:
|
|
1335
|
+
- self.tdim: Time dimension flag (1 for 3D, >1 for 4D)
|
|
1336
|
+
- self.map.maskeddata: The data array containing the values
|
|
1337
|
+
- self.xpos, self.ypos, self.zpos, self.tpos: Position coordinates
|
|
1338
|
+
|
|
1339
|
+
Examples
|
|
1340
|
+
--------
|
|
1341
|
+
>>> value = obj.getFocusVal()
|
|
1342
|
+
>>> print(value)
|
|
1343
|
+
0.567
|
|
1344
|
+
"""
|
|
440
1345
|
if self.tdim > 1:
|
|
441
1346
|
return self.map.maskeddata[self.xpos, self.ypos, self.zpos, self.tpos]
|
|
442
1347
|
else:
|
|
443
1348
|
return self.map.maskeddata[self.xpos, self.ypos, self.zpos]
|
|
444
1349
|
|
|
445
|
-
def saveandcomposite(
|
|
1350
|
+
def saveandcomposite(
|
|
1351
|
+
self,
|
|
1352
|
+
square_img: Any,
|
|
1353
|
+
fg_img: Any,
|
|
1354
|
+
bg_img: Any,
|
|
1355
|
+
name: str,
|
|
1356
|
+
savedir: str,
|
|
1357
|
+
scalefach: float,
|
|
1358
|
+
scalefacv: float,
|
|
1359
|
+
) -> None:
|
|
1360
|
+
"""
|
|
1361
|
+
Save and composite image layers into a final output file.
|
|
1362
|
+
|
|
1363
|
+
This function saves individual image layers (square, foreground, and background)
|
|
1364
|
+
and composites them into a final image. If PIL is available, it performs
|
|
1365
|
+
additional operations such as flipping, scaling, and saving the composite
|
|
1366
|
+
as a JPEG file. Temporary files are removed after processing.
|
|
1367
|
+
|
|
1368
|
+
Parameters
|
|
1369
|
+
----------
|
|
1370
|
+
square_img : Any
|
|
1371
|
+
The square image to be saved.
|
|
1372
|
+
fg_img : Any
|
|
1373
|
+
The foreground image to be saved and composited.
|
|
1374
|
+
bg_img : Any
|
|
1375
|
+
The background image to be saved and composited.
|
|
1376
|
+
name : str
|
|
1377
|
+
Base name for the output files.
|
|
1378
|
+
savedir : str
|
|
1379
|
+
Directory where output files will be saved.
|
|
1380
|
+
scalefach : float
|
|
1381
|
+
Horizontal scaling factor for the final image.
|
|
1382
|
+
scalefacv : float
|
|
1383
|
+
Vertical scaling factor for the final image.
|
|
1384
|
+
|
|
1385
|
+
Returns
|
|
1386
|
+
-------
|
|
1387
|
+
None
|
|
1388
|
+
This function does not return any value.
|
|
1389
|
+
|
|
1390
|
+
Notes
|
|
1391
|
+
-----
|
|
1392
|
+
- If PIL is available, the function will save the images in PNG format
|
|
1393
|
+
and composite them into a JPEG file.
|
|
1394
|
+
- Temporary files are deleted after processing.
|
|
1395
|
+
- The function uses `Image.NEAREST` for resizing to preserve pixel integrity.
|
|
1396
|
+
- Verbose logging is enabled based on `self.verbose` level.
|
|
1397
|
+
|
|
1398
|
+
Examples
|
|
1399
|
+
--------
|
|
1400
|
+
>>> saveandcomposite(
|
|
1401
|
+
... square_img=square,
|
|
1402
|
+
... fg_img=foreground,
|
|
1403
|
+
... bg_img=background,
|
|
1404
|
+
... name="test_image",
|
|
1405
|
+
... savedir="/path/to/save",
|
|
1406
|
+
... scalefach=1.0,
|
|
1407
|
+
... scalefacv=1.0
|
|
1408
|
+
... )
|
|
1409
|
+
"""
|
|
446
1410
|
if PILexists:
|
|
447
1411
|
if self.verbose > 1:
|
|
448
1412
|
print("using PIL to save ", name)
|
|
@@ -491,11 +1455,66 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
491
1455
|
fg_img.save(os.path.join(savedir, name + "_fg.png"))
|
|
492
1456
|
bg_img.save(os.path.join(savedir, name + "_bg.png"))
|
|
493
1457
|
|
|
494
|
-
def saveDisp(self):
|
|
1458
|
+
def saveDisp(self) -> None:
|
|
1459
|
+
"""
|
|
1460
|
+
Save display windows for axial, coronal, and sagittal views of the image data.
|
|
1461
|
+
|
|
1462
|
+
This function saves three orthogonal views (axial, coronal, and sagittal) of the
|
|
1463
|
+
image data to the specified directory. It also saves a colorbar and writes
|
|
1464
|
+
display limits to a text file. The saved images are composed using the
|
|
1465
|
+
`saveandcomposite` method, and the colorbar is generated using `newColorbar`.
|
|
1466
|
+
|
|
1467
|
+
Parameters
|
|
1468
|
+
----------
|
|
1469
|
+
self : object
|
|
1470
|
+
The instance of the class containing this method. Expected to have attributes:
|
|
1471
|
+
- `verbose`: int, controls verbosity of output.
|
|
1472
|
+
- `map`: object with attributes:
|
|
1473
|
+
- `namebase`: str, base name for output files.
|
|
1474
|
+
- `name`: str, name of the map.
|
|
1475
|
+
- `theLUT`: lookup table for color mapping.
|
|
1476
|
+
- `dispmin`: float, minimum display value.
|
|
1477
|
+
- `dispmax`: float, maximum display value.
|
|
1478
|
+
- `impixpervoxx`, `impixpervoxy`, `impixpervoxz`: float, voxel sizes in each dimension.
|
|
1479
|
+
- `xdim`, `ydim`, `zdim`: int, dimensions of the image in each axis.
|
|
1480
|
+
- `xsize`, `ysize`, `zsize`: float, physical size per voxel in each axis.
|
|
1481
|
+
- `axviewwin`, `axviewbgwin`, `corviewwin`, `corviewbgwin`, `sagviewwin`, `sagviewbgwin`:
|
|
1482
|
+
ImageItem objects for the respective views.
|
|
1483
|
+
- `applyLUT`: method to apply lookup table to data.
|
|
1484
|
+
- `saveandcomposite`: method to composite and save image views.
|
|
1485
|
+
|
|
1486
|
+
Returns
|
|
1487
|
+
-------
|
|
1488
|
+
None
|
|
1489
|
+
This function does not return any value.
|
|
1490
|
+
|
|
1491
|
+
Notes
|
|
1492
|
+
-----
|
|
1493
|
+
- The function uses Qt bindings (PyQt5, PyQt6, or PySide6) to open a file dialog
|
|
1494
|
+
for selecting the output directory.
|
|
1495
|
+
- The saved images are named with the base name from `self.map.namebase` and
|
|
1496
|
+
appended with `_ax`, `_cor`, and `_sag` for the respective views.
|
|
1497
|
+
- A colorbar is generated but currently commented out in the code.
|
|
1498
|
+
- The display limits are saved to a file named `<namebase><name>_lims.txt`.
|
|
1499
|
+
|
|
1500
|
+
Examples
|
|
1501
|
+
--------
|
|
1502
|
+
Assuming `obj` is an instance of the class containing this method:
|
|
1503
|
+
|
|
1504
|
+
>>> obj.saveDisp()
|
|
1505
|
+
# Saves axial, coronal, and sagittal views to the selected directory.
|
|
1506
|
+
"""
|
|
495
1507
|
if self.verbose > 1:
|
|
496
1508
|
print("saving main window")
|
|
497
1509
|
mydialog = QtWidgets.QFileDialog()
|
|
498
|
-
|
|
1510
|
+
if pyqtbinding == "pyqt5":
|
|
1511
|
+
options = mydialog.Options()
|
|
1512
|
+
elif pyqtbinding == "pyqt6":
|
|
1513
|
+
options = mydialog.options()
|
|
1514
|
+
elif pyqtbinding == "pyside6":
|
|
1515
|
+
options = mydialog.options()
|
|
1516
|
+
else:
|
|
1517
|
+
print("unsupported qt binding")
|
|
499
1518
|
thedir = str(
|
|
500
1519
|
mydialog.getExistingDirectory(options=options, caption="Image output directory")
|
|
501
1520
|
)
|
|
@@ -528,7 +1547,7 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
528
1547
|
) = newColorbar(0, 0, maximpervox, maximpervox, maxdim)
|
|
529
1548
|
cbim = self.applyLUT(
|
|
530
1549
|
colorbarvals,
|
|
531
|
-
(colorbarvals
|
|
1550
|
+
np.ones_like(colorbarvals, "int"),
|
|
532
1551
|
self.map.theLUT,
|
|
533
1552
|
0.0,
|
|
534
1553
|
1.0,
|
|
@@ -577,7 +1596,31 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
577
1596
|
FILE.writelines(str(self.map.dispmin) + "\t" + str(self.map.dispmax))
|
|
578
1597
|
# img_colorbar.save(thedir + self.map.name + '_colorbar.png')
|
|
579
1598
|
|
|
580
|
-
def summarize(self):
|
|
1599
|
+
def summarize(self) -> None:
|
|
1600
|
+
"""
|
|
1601
|
+
Summarize the orthoimage item information.
|
|
1602
|
+
|
|
1603
|
+
This method performs a summary operation on the orthoimage item, typically
|
|
1604
|
+
used to validate or prepare the item for further processing. When a map is
|
|
1605
|
+
associated with the item, it may perform additional operations or validation.
|
|
1606
|
+
|
|
1607
|
+
Notes
|
|
1608
|
+
-----
|
|
1609
|
+
The method currently contains a placeholder implementation that only checks
|
|
1610
|
+
if a map is set. In a complete implementation, this method would likely
|
|
1611
|
+
generate summary statistics, validate data integrity, or prepare the item
|
|
1612
|
+
for display or export operations.
|
|
1613
|
+
|
|
1614
|
+
Examples
|
|
1615
|
+
--------
|
|
1616
|
+
>>> item = OrthoImageItem()
|
|
1617
|
+
>>> item.summarize()
|
|
1618
|
+
# Performs summary operation on the item
|
|
1619
|
+
|
|
1620
|
+
See Also
|
|
1621
|
+
--------
|
|
1622
|
+
OrthoImageItem : Main class for orthoimage items
|
|
1623
|
+
"""
|
|
581
1624
|
if self.map is not None:
|
|
582
1625
|
# print('OrthoImageItem[', self.map.name, ']: map is set')
|
|
583
1626
|
pass
|