rapidtide 3.0.11__py3-none-any.whl → 3.1.1__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.
- rapidtide/Colortables.py +492 -27
- rapidtide/OrthoImageItem.py +1049 -46
- rapidtide/RapidtideDataset.py +1533 -86
- rapidtide/_version.py +3 -3
- rapidtide/calccoherence.py +196 -29
- rapidtide/calcnullsimfunc.py +188 -40
- rapidtide/calcsimfunc.py +242 -42
- rapidtide/correlate.py +1203 -383
- rapidtide/data/examples/src/testLD +56 -0
- rapidtide/data/examples/src/testalign +1 -1
- rapidtide/data/examples/src/testdelayvar +0 -1
- rapidtide/data/examples/src/testfmri +53 -3
- rapidtide/data/examples/src/testglmfilt +5 -5
- rapidtide/data/examples/src/testhappy +29 -7
- rapidtide/data/examples/src/testppgproc +17 -0
- rapidtide/data/examples/src/testrolloff +11 -0
- rapidtide/data/models/model_cnn_pytorch/best_model.pth +0 -0
- 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/decorators.py +91 -0
- rapidtide/dlfilter.py +2226 -110
- rapidtide/dlfiltertorch.py +4842 -0
- rapidtide/externaltools.py +327 -12
- rapidtide/fMRIData_class.py +79 -40
- rapidtide/filter.py +1899 -810
- rapidtide/fit.py +2011 -581
- rapidtide/genericmultiproc.py +93 -18
- rapidtide/happy_supportfuncs.py +2047 -172
- rapidtide/helper_classes.py +584 -43
- rapidtide/io.py +2370 -372
- rapidtide/linfitfiltpass.py +346 -99
- rapidtide/makelaggedtcs.py +210 -24
- rapidtide/maskutil.py +448 -62
- rapidtide/miscmath.py +827 -121
- rapidtide/multiproc.py +210 -22
- rapidtide/patchmatch.py +242 -42
- rapidtide/peakeval.py +31 -31
- rapidtide/ppgproc.py +2203 -0
- rapidtide/qualitycheck.py +352 -39
- rapidtide/refinedelay.py +431 -57
- rapidtide/refineregressor.py +494 -189
- rapidtide/resample.py +671 -185
- rapidtide/scripts/applyppgproc.py +28 -0
- rapidtide/scripts/showxcorr_legacy.py +7 -7
- rapidtide/scripts/stupidramtricks.py +15 -17
- rapidtide/simFuncClasses.py +1052 -77
- rapidtide/simfuncfit.py +269 -69
- rapidtide/stats.py +540 -238
- rapidtide/tests/happycomp +9 -0
- rapidtide/tests/test_cleanregressor.py +1 -2
- rapidtide/tests/test_dlfiltertorch.py +627 -0
- rapidtide/tests/test_findmaxlag.py +24 -8
- rapidtide/tests/test_fullrunhappy_v1.py +0 -2
- rapidtide/tests/test_fullrunhappy_v2.py +0 -2
- rapidtide/tests/test_fullrunhappy_v3.py +11 -4
- rapidtide/tests/test_fullrunhappy_v4.py +10 -2
- rapidtide/tests/test_fullrunrapidtide_v7.py +1 -1
- rapidtide/tests/test_getparsers.py +11 -3
- rapidtide/tests/test_refinedelay.py +0 -1
- rapidtide/tests/test_simroundtrip.py +16 -8
- rapidtide/tests/test_stcorrelate.py +3 -1
- rapidtide/tests/utils.py +9 -8
- rapidtide/tidepoolTemplate.py +142 -38
- rapidtide/tidepoolTemplate_alt.py +165 -44
- rapidtide/tidepoolTemplate_big.py +189 -52
- rapidtide/util.py +1217 -118
- rapidtide/voxelData.py +684 -37
- rapidtide/wiener.py +136 -23
- rapidtide/wiener2.py +113 -7
- rapidtide/workflows/adjustoffset.py +105 -3
- rapidtide/workflows/aligntcs.py +85 -2
- rapidtide/workflows/applydlfilter.py +87 -10
- rapidtide/workflows/applyppgproc.py +540 -0
- rapidtide/workflows/atlasaverage.py +210 -47
- rapidtide/workflows/atlastool.py +100 -3
- rapidtide/workflows/calcSimFuncMap.py +288 -69
- rapidtide/workflows/calctexticc.py +201 -9
- rapidtide/workflows/ccorrica.py +101 -6
- rapidtide/workflows/cleanregressor.py +165 -31
- rapidtide/workflows/delayvar.py +171 -23
- rapidtide/workflows/diffrois.py +81 -3
- rapidtide/workflows/endtidalproc.py +144 -4
- rapidtide/workflows/fdica.py +195 -15
- rapidtide/workflows/filtnifti.py +70 -3
- rapidtide/workflows/filttc.py +74 -3
- rapidtide/workflows/fitSimFuncMap.py +202 -51
- rapidtide/workflows/fixtr.py +73 -3
- rapidtide/workflows/gmscalc.py +113 -3
- rapidtide/workflows/happy.py +801 -199
- rapidtide/workflows/happy2std.py +144 -12
- rapidtide/workflows/happy_parser.py +163 -23
- rapidtide/workflows/histnifti.py +118 -2
- rapidtide/workflows/histtc.py +84 -3
- rapidtide/workflows/linfitfilt.py +117 -4
- rapidtide/workflows/localflow.py +328 -28
- rapidtide/workflows/mergequality.py +79 -3
- rapidtide/workflows/niftidecomp.py +322 -18
- rapidtide/workflows/niftistats.py +174 -4
- rapidtide/workflows/pairproc.py +98 -4
- rapidtide/workflows/pairwisemergenifti.py +85 -2
- rapidtide/workflows/parser_funcs.py +1421 -40
- rapidtide/workflows/physiofreq.py +137 -11
- rapidtide/workflows/pixelcomp.py +207 -5
- rapidtide/workflows/plethquality.py +103 -21
- rapidtide/workflows/polyfitim.py +151 -11
- rapidtide/workflows/proj2flow.py +75 -2
- rapidtide/workflows/rankimage.py +111 -4
- rapidtide/workflows/rapidtide.py +368 -76
- rapidtide/workflows/rapidtide2std.py +98 -2
- rapidtide/workflows/rapidtide_parser.py +109 -9
- rapidtide/workflows/refineDelayMap.py +144 -33
- rapidtide/workflows/refineRegressor.py +675 -96
- rapidtide/workflows/regressfrommaps.py +161 -37
- rapidtide/workflows/resamplenifti.py +85 -3
- rapidtide/workflows/resampletc.py +91 -3
- rapidtide/workflows/retrolagtcs.py +99 -9
- rapidtide/workflows/retroregress.py +176 -26
- rapidtide/workflows/roisummarize.py +174 -5
- rapidtide/workflows/runqualitycheck.py +71 -3
- rapidtide/workflows/showarbcorr.py +149 -6
- rapidtide/workflows/showhist.py +86 -2
- rapidtide/workflows/showstxcorr.py +160 -3
- rapidtide/workflows/showtc.py +159 -3
- rapidtide/workflows/showxcorrx.py +190 -10
- rapidtide/workflows/showxy.py +185 -15
- rapidtide/workflows/simdata.py +264 -38
- rapidtide/workflows/spatialfit.py +77 -2
- rapidtide/workflows/spatialmi.py +250 -27
- rapidtide/workflows/spectrogram.py +305 -32
- rapidtide/workflows/synthASL.py +154 -3
- rapidtide/workflows/tcfrom2col.py +76 -2
- rapidtide/workflows/tcfrom3col.py +74 -2
- rapidtide/workflows/tidepool.py +2971 -130
- rapidtide/workflows/utils.py +19 -14
- rapidtide/workflows/utils_doc.py +293 -0
- rapidtide/workflows/variabilityizer.py +116 -3
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/METADATA +10 -8
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/RECORD +144 -128
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/entry_points.txt +1 -0
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/WHEEL +0 -0
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/licenses/LICENSE +0 -0
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/top_level.txt +0 -0
rapidtide/OrthoImageItem.py
CHANGED
|
@@ -20,9 +20,11 @@
|
|
|
20
20
|
A widget for orthographically displaying 3 and 4 dimensional data
|
|
21
21
|
"""
|
|
22
22
|
import os
|
|
23
|
+
from typing import Any
|
|
23
24
|
|
|
24
25
|
import numpy as np
|
|
25
26
|
import pyqtgraph as pg
|
|
27
|
+
from numpy.typing import NDArray
|
|
26
28
|
from pyqtgraph.Qt import QtCore, QtGui, QtWidgets
|
|
27
29
|
|
|
28
30
|
try:
|
|
@@ -46,7 +48,55 @@ else:
|
|
|
46
48
|
print(f"using {pyqtbinding=}")
|
|
47
49
|
|
|
48
50
|
|
|
49
|
-
def newColorbar(
|
|
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
|
+
"""
|
|
50
100
|
cb_xdim = imgsize // 10
|
|
51
101
|
cb_ydim = imgsize
|
|
52
102
|
theviewbox = pg.ViewBox(enableMouse=False)
|
|
@@ -80,14 +130,63 @@ def newColorbar(left, top, impixpervoxx, impixpervoxy, imgsize):
|
|
|
80
130
|
|
|
81
131
|
|
|
82
132
|
def setupViewWindow(
|
|
83
|
-
view,
|
|
84
|
-
left,
|
|
85
|
-
top,
|
|
86
|
-
impixpervoxx,
|
|
87
|
-
impixpervoxy,
|
|
88
|
-
imgsize,
|
|
89
|
-
enableMouse=False,
|
|
90
|
-
):
|
|
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
|
+
"""
|
|
91
190
|
|
|
92
191
|
theviewbox = view.addViewBox(enableMouse=enableMouse, enableMenu=False, lockAspect=1.0)
|
|
93
192
|
theviewbox.setAspectLocked()
|
|
@@ -124,17 +223,69 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
124
223
|
|
|
125
224
|
def __init__(
|
|
126
225
|
self,
|
|
127
|
-
map,
|
|
128
|
-
axview,
|
|
129
|
-
corview,
|
|
130
|
-
sagview,
|
|
131
|
-
enableMouse=False,
|
|
132
|
-
button=None,
|
|
133
|
-
imgsize=64,
|
|
134
|
-
arrangement=0,
|
|
135
|
-
bgmap=None,
|
|
136
|
-
verbose=0,
|
|
137
|
-
):
|
|
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
|
+
"""
|
|
138
289
|
QtWidgets.QWidget.__init__(self)
|
|
139
290
|
self.map = map
|
|
140
291
|
self.mapname = self.map.label
|
|
@@ -268,16 +419,128 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
268
419
|
self.enableView()
|
|
269
420
|
self.updateAllViews()
|
|
270
421
|
|
|
271
|
-
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
|
+
"""
|
|
272
448
|
return int(np.round(self.offsetx + self.impixpervoxx * xpos))
|
|
273
449
|
|
|
274
|
-
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
|
+
"""
|
|
275
480
|
return int(np.round(self.offsety + self.impixpervoxy * ypos))
|
|
276
481
|
|
|
277
|
-
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
|
+
"""
|
|
278
511
|
return int(np.round(self.offsetz + self.impixpervoxz * zpos))
|
|
279
512
|
|
|
280
|
-
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
|
+
"""
|
|
281
544
|
thepos = (xpix - self.offsetx) / self.impixpervoxx
|
|
282
545
|
if thepos > self.xdim - 1:
|
|
283
546
|
thepos = self.xdim - 1
|
|
@@ -285,7 +548,36 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
285
548
|
thepos = 0
|
|
286
549
|
return int(np.round(thepos))
|
|
287
550
|
|
|
288
|
-
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
|
+
"""
|
|
289
581
|
thepos = (ypix - self.offsety) / self.impixpervoxy
|
|
290
582
|
if thepos > self.ydim - 1:
|
|
291
583
|
thepos = self.ydim - 1
|
|
@@ -293,7 +585,40 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
293
585
|
thepos = 0
|
|
294
586
|
return int(np.round(thepos))
|
|
295
587
|
|
|
296
|
-
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
|
+
"""
|
|
297
622
|
thepos = (zpix - self.offsetz) / self.impixpervoxz
|
|
298
623
|
if thepos > self.zdim - 1:
|
|
299
624
|
thepos = self.zdim - 1
|
|
@@ -301,7 +626,35 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
301
626
|
thepos = 0
|
|
302
627
|
return int(np.round(thepos))
|
|
303
628
|
|
|
304
|
-
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
|
+
"""
|
|
305
658
|
if self.tdim == 1:
|
|
306
659
|
axdata = self.map.maskeddata[:, :, self.zpos]
|
|
307
660
|
else:
|
|
@@ -354,18 +707,123 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
354
707
|
self.sagviewvLine.setValue(self.yvox2pix(self.ypos))
|
|
355
708
|
self.sagviewhLine.setValue(self.zvox2pix(self.zpos))
|
|
356
709
|
|
|
357
|
-
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
|
+
"""
|
|
358
756
|
im = self.applyLUT(data, mask, theLUT, self.map.dispmin, self.map.dispmax)
|
|
359
757
|
thefgwin.setImage(im.astype("float"))
|
|
360
758
|
if background is not None:
|
|
361
759
|
thebgwin.setImage(background.astype("float"), autoLevels=True)
|
|
362
760
|
|
|
363
|
-
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
|
+
"""
|
|
364
793
|
self.map = themap
|
|
365
794
|
self.tdim = self.map.tdim
|
|
366
795
|
self.mapname = self.map.label
|
|
367
796
|
|
|
368
|
-
def enableView(self):
|
|
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
|
+
"""
|
|
369
827
|
if self.button is not None:
|
|
370
828
|
self.button.setText(self.map.label)
|
|
371
829
|
self.button.setDisabled(False)
|
|
@@ -374,7 +832,47 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
374
832
|
self.corview.show()
|
|
375
833
|
self.sagview.show()
|
|
376
834
|
|
|
377
|
-
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
|
+
"""
|
|
378
876
|
offset = dispmin
|
|
379
877
|
if dispmax - dispmin > 0:
|
|
380
878
|
scale = len(theLUT) / (dispmax - dispmin)
|
|
@@ -387,7 +885,48 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
387
885
|
mappeddata[:, :, 3][np.where(mask < 1)] = 0
|
|
388
886
|
return mappeddata
|
|
389
887
|
|
|
390
|
-
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
|
+
"""
|
|
391
930
|
xpix = self.xvox2pix(self.xpos)
|
|
392
931
|
ypix = self.yvox2pix(self.ypos)
|
|
393
932
|
zpix = self.zvox2pix(self.zpos)
|
|
@@ -398,60 +937,332 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
398
937
|
self.sagviewvLine.setValue(ypix)
|
|
399
938
|
self.sagviewhLine.setValue(zpix)
|
|
400
939
|
|
|
401
|
-
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
|
+
"""
|
|
402
969
|
self.buttonisdown = False
|
|
403
970
|
self.updateCursors()
|
|
404
971
|
self.updateAllViews()
|
|
405
972
|
|
|
406
|
-
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
|
+
"""
|
|
407
1006
|
if self.buttonisdown:
|
|
408
1007
|
self.xpos = self.xpix2vox(event.pos().x() - 1)
|
|
409
1008
|
self.ypos = self.ypix2vox(self.imgsize - event.pos().y() + 1)
|
|
410
1009
|
self.updateAllViews()
|
|
411
1010
|
self.updated.emit()
|
|
412
1011
|
|
|
413
|
-
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
|
+
"""
|
|
414
1044
|
if self.buttonisdown:
|
|
415
1045
|
self.xpos = self.xpix2vox(event.pos().x() - 1)
|
|
416
1046
|
self.zpos = self.zpix2vox(self.imgsize - event.pos().y() + 1)
|
|
417
1047
|
self.updateAllViews()
|
|
418
1048
|
self.updated.emit()
|
|
419
1049
|
|
|
420
|
-
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
|
+
"""
|
|
421
1079
|
if self.buttonisdown:
|
|
422
1080
|
self.ypos = self.ypix2vox(event.pos().x() - 1)
|
|
423
1081
|
self.zpos = self.zpix2vox(self.imgsize - event.pos().y() + 1)
|
|
424
1082
|
self.updateAllViews()
|
|
425
1083
|
self.updated.emit()
|
|
426
1084
|
|
|
427
|
-
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
|
+
"""
|
|
428
1114
|
if self.verbose > 1:
|
|
429
1115
|
print(event)
|
|
430
1116
|
self.updateAllViews()
|
|
431
1117
|
self.updated.emit()
|
|
432
1118
|
|
|
433
|
-
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
|
+
"""
|
|
434
1152
|
self.xpos = self.xpix2vox(event.pos().x() - 1)
|
|
435
1153
|
self.ypos = self.ypix2vox(self.imgsize - event.pos().y() + 1)
|
|
436
1154
|
self.buttonisdown = True
|
|
437
1155
|
self.updateAllViews()
|
|
438
1156
|
self.updated.emit()
|
|
439
1157
|
|
|
440
|
-
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
|
+
"""
|
|
441
1190
|
self.xpos = self.xpix2vox(event.pos().x() - 1)
|
|
442
1191
|
self.zpos = self.zpix2vox(self.imgsize - event.pos().y() + 1)
|
|
443
1192
|
self.buttonisdown = True
|
|
444
1193
|
self.updateAllViews()
|
|
445
1194
|
self.updated.emit()
|
|
446
1195
|
|
|
447
|
-
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
|
+
"""
|
|
448
1229
|
self.ypos = self.ypix2vox(event.pos().x() - 1)
|
|
449
1230
|
self.zpos = self.zpix2vox(self.imgsize - event.pos().y() + 1)
|
|
450
1231
|
self.buttonisdown = True
|
|
451
1232
|
self.updateAllViews()
|
|
452
1233
|
self.updated.emit()
|
|
453
1234
|
|
|
454
|
-
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
|
+
"""
|
|
455
1266
|
self.xpos = int(xpos)
|
|
456
1267
|
self.ypos = int(ypos)
|
|
457
1268
|
self.zpos = int(zpos)
|
|
@@ -459,7 +1270,37 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
459
1270
|
if emitsignal:
|
|
460
1271
|
self.updated.emit()
|
|
461
1272
|
|
|
462
|
-
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
|
+
"""
|
|
463
1304
|
if tpos > self.tdim - 1:
|
|
464
1305
|
self.tpos = int(self.tdim - 1)
|
|
465
1306
|
else:
|
|
@@ -469,13 +1310,103 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
469
1310
|
if emitsignal:
|
|
470
1311
|
self.updated.emit()
|
|
471
1312
|
|
|
472
|
-
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
|
+
"""
|
|
473
1345
|
if self.tdim > 1:
|
|
474
1346
|
return self.map.maskeddata[self.xpos, self.ypos, self.zpos, self.tpos]
|
|
475
1347
|
else:
|
|
476
1348
|
return self.map.maskeddata[self.xpos, self.ypos, self.zpos]
|
|
477
1349
|
|
|
478
|
-
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
|
+
"""
|
|
479
1410
|
if PILexists:
|
|
480
1411
|
if self.verbose > 1:
|
|
481
1412
|
print("using PIL to save ", name)
|
|
@@ -524,7 +1455,55 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
524
1455
|
fg_img.save(os.path.join(savedir, name + "_fg.png"))
|
|
525
1456
|
bg_img.save(os.path.join(savedir, name + "_bg.png"))
|
|
526
1457
|
|
|
527
|
-
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
|
+
"""
|
|
528
1507
|
if self.verbose > 1:
|
|
529
1508
|
print("saving main window")
|
|
530
1509
|
mydialog = QtWidgets.QFileDialog()
|
|
@@ -617,7 +1596,31 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
617
1596
|
FILE.writelines(str(self.map.dispmin) + "\t" + str(self.map.dispmax))
|
|
618
1597
|
# img_colorbar.save(thedir + self.map.name + '_colorbar.png')
|
|
619
1598
|
|
|
620
|
-
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
|
+
"""
|
|
621
1624
|
if self.map is not None:
|
|
622
1625
|
# print('OrthoImageItem[', self.map.name, ']: map is set')
|
|
623
1626
|
pass
|