pumpia 0.1.0__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.
- pumpia/__init__.py +0 -0
- pumpia/contrib/__init__.py +0 -0
- pumpia/contrib/example/__init__.py +0 -0
- pumpia/contrib/example/collection.py +61 -0
- pumpia/contrib/example/example.py +136 -0
- pumpia/contrib/example/module.py +72 -0
- pumpia/file_handling/__init__.py +0 -0
- pumpia/file_handling/dicom_structures.py +985 -0
- pumpia/file_handling/dicom_tags.py +775 -0
- pumpia/image_handling/__init__.py +0 -0
- pumpia/image_handling/image_structures.py +714 -0
- pumpia/image_handling/image_validators.py +24 -0
- pumpia/image_handling/roi_structures.py +2423 -0
- pumpia/module_handling/__init__.py +0 -0
- pumpia/module_handling/context.py +118 -0
- pumpia/module_handling/in_outs/__init__.py +0 -0
- pumpia/module_handling/in_outs/groups.py +30 -0
- pumpia/module_handling/in_outs/roi_ios.py +324 -0
- pumpia/module_handling/in_outs/simple.py +632 -0
- pumpia/module_handling/in_outs/viewer_ios.py +102 -0
- pumpia/module_handling/manager.py +893 -0
- pumpia/module_handling/module_collections.py +793 -0
- pumpia/module_handling/modules.py +844 -0
- pumpia/utilities/__init__.py +0 -0
- pumpia/utilities/array_utils.py +557 -0
- pumpia/utilities/dicom_utils.py +82 -0
- pumpia/utilities/feature_utils.py +401 -0
- pumpia/utilities/string_validators.py +101 -0
- pumpia/utilities/tkinter_utils.py +83 -0
- pumpia/utilities/typing.py +6 -0
- pumpia/widgets/__init__.py +0 -0
- pumpia/widgets/context_managers.py +988 -0
- pumpia/widgets/entry_boxes.py +553 -0
- pumpia/widgets/scrolled_window.py +216 -0
- pumpia/widgets/tables.py +305 -0
- pumpia/widgets/typing.py +39 -0
- pumpia/widgets/variables.py +54 -0
- pumpia/widgets/viewers.py +1493 -0
- pumpia-0.1.0.dist-info/METADATA +52 -0
- pumpia-0.1.0.dist-info/RECORD +42 -0
- pumpia-0.1.0.dist-info/WHEEL +4 -0
- pumpia-0.1.0.dist-info/licenses/LICENSE +29 -0
pumpia/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from pumpia.contrib.example.module import ExampleModule
|
|
2
|
+
from pumpia.module_handling.module_collections import (BaseCollection,
|
|
3
|
+
OutputFrame,
|
|
4
|
+
WindowGroup)
|
|
5
|
+
from pumpia.module_handling.in_outs.viewer_ios import ArrayViewerIO
|
|
6
|
+
from pumpia.module_handling.in_outs.groups import IOGroup
|
|
7
|
+
from pumpia.widgets.viewers import BaseViewer
|
|
8
|
+
from pumpia.image_handling.image_structures import ImageCollection
|
|
9
|
+
from pumpia.utilities.tkinter_utils import tk_copy
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ExampleCollection(BaseCollection):
|
|
13
|
+
"""
|
|
14
|
+
An example collection.
|
|
15
|
+
|
|
16
|
+
This collection demonstrates the use of the PumpIA collections.
|
|
17
|
+
It has 2 viewers in the main window and loads 2 `ExampleModule` instances into a second window.
|
|
18
|
+
"""
|
|
19
|
+
viewer1 = ArrayViewerIO(row=0, column=0)
|
|
20
|
+
viewer2 = ArrayViewerIO(row=0, column=1, main=True)
|
|
21
|
+
|
|
22
|
+
module1 = ExampleModule()
|
|
23
|
+
module2 = ExampleModule()
|
|
24
|
+
|
|
25
|
+
average_output = OutputFrame()
|
|
26
|
+
|
|
27
|
+
# makes sure the two modules are in the same window in the collection
|
|
28
|
+
group = WindowGroup([module1, module2])
|
|
29
|
+
|
|
30
|
+
def load_outputs(self):
|
|
31
|
+
self.average_output.register_output(self.module1.average, verbose_name="Average 1")
|
|
32
|
+
self.average_output.register_output(self.module2.average, verbose_name="Average 2")
|
|
33
|
+
IOGroup([self.module1.size, self.module2.size])
|
|
34
|
+
|
|
35
|
+
def on_image_load(self, viewer: BaseViewer) -> None:
|
|
36
|
+
# loads the image loaded into a viewer into the relevant modules viewer
|
|
37
|
+
# if the image is an ImageCollection then only loads the first image into the module
|
|
38
|
+
if viewer is self.viewer1:
|
|
39
|
+
if self.viewer1.image is not None:
|
|
40
|
+
image = self.viewer1.image
|
|
41
|
+
if isinstance(image, ImageCollection):
|
|
42
|
+
self.module1.viewer.load_image(image.image_set[0])
|
|
43
|
+
else:
|
|
44
|
+
self.module1.viewer.load_image(image)
|
|
45
|
+
|
|
46
|
+
elif viewer is self.viewer2:
|
|
47
|
+
if self.viewer2.image is not None:
|
|
48
|
+
image = self.viewer2.image
|
|
49
|
+
if isinstance(image, ImageCollection):
|
|
50
|
+
self.module2.viewer.load_image(image.image_set[0])
|
|
51
|
+
else:
|
|
52
|
+
self.module2.viewer.load_image(image)
|
|
53
|
+
|
|
54
|
+
def load_commands(self):
|
|
55
|
+
self.register_command("Copy Averages", self.copy_averages)
|
|
56
|
+
|
|
57
|
+
def copy_averages(self):
|
|
58
|
+
"""
|
|
59
|
+
Copy the values of the averages to the clipboard, comma seperated.
|
|
60
|
+
"""
|
|
61
|
+
tk_copy(", ".join([str(self.module1.average.value), str(self.module2.average.value)]))
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Example
|
|
3
|
+
"""
|
|
4
|
+
import math
|
|
5
|
+
|
|
6
|
+
from pumpia.module_handling.modules import BaseModule
|
|
7
|
+
from pumpia.module_handling.module_collections import (BaseCollection,
|
|
8
|
+
OutputFrame,
|
|
9
|
+
WindowGroup)
|
|
10
|
+
from pumpia.module_handling.in_outs.roi_ios import BaseInputROI, InputEllipseROI
|
|
11
|
+
from pumpia.module_handling.in_outs.viewer_ios import ArrayViewerIO
|
|
12
|
+
from pumpia.module_handling.in_outs.simple import PercInput, FloatOutput, IntOutput
|
|
13
|
+
from pumpia.module_handling.in_outs.groups import IOGroup
|
|
14
|
+
from pumpia.module_handling.context import SimpleContext
|
|
15
|
+
from pumpia.widgets.viewers import BaseViewer
|
|
16
|
+
from pumpia.image_handling.roi_structures import EllipseROI
|
|
17
|
+
from pumpia.image_handling.image_structures import ImageCollection
|
|
18
|
+
from pumpia.utilities.tkinter_utils import tk_copy
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ExampleModule(BaseModule):
|
|
22
|
+
"""
|
|
23
|
+
An Example Module.
|
|
24
|
+
|
|
25
|
+
This module demonstrates the use of the PumpIA modules.
|
|
26
|
+
It draws an ellipse ROI on an image based on the size of image and input from the user.
|
|
27
|
+
The analysis calculates the average pixel value within the ellipse,
|
|
28
|
+
or the root sum of squares of the means if a multisample image.
|
|
29
|
+
"""
|
|
30
|
+
viewer = ArrayViewerIO(row=0, column=0)
|
|
31
|
+
size = PercInput(80, verbose_name="Size (%)")
|
|
32
|
+
ellipse_roi = InputEllipseROI("Ellipse ROI")
|
|
33
|
+
|
|
34
|
+
width = IntOutput(verbose_name="Width (px)")
|
|
35
|
+
height = IntOutput(verbose_name="Height (px)")
|
|
36
|
+
average = FloatOutput()
|
|
37
|
+
|
|
38
|
+
def link_rois_viewers(self):
|
|
39
|
+
self.ellipse_roi.viewer = self.viewer
|
|
40
|
+
|
|
41
|
+
def draw_rois(self, context: SimpleContext, batch: bool = False):
|
|
42
|
+
if self.viewer.image is not None:
|
|
43
|
+
factor = self.size.value / 100
|
|
44
|
+
a = round(factor * context.width / 2)
|
|
45
|
+
b = round(factor * context.height / 2)
|
|
46
|
+
self.ellipse_roi.register_roi(EllipseROI(self.viewer.image,
|
|
47
|
+
round(context.xcent),
|
|
48
|
+
round(context.ycent),
|
|
49
|
+
a,
|
|
50
|
+
b,
|
|
51
|
+
slice_num=self.viewer.current_slice))
|
|
52
|
+
|
|
53
|
+
def post_roi_register(self, roi_input: BaseInputROI):
|
|
54
|
+
if self.ellipse_roi.roi is not None and self.manager is not None:
|
|
55
|
+
self.manager.add_roi(self.ellipse_roi.roi)
|
|
56
|
+
|
|
57
|
+
def analyse(self, batch: bool = False):
|
|
58
|
+
if self.ellipse_roi.roi is not None:
|
|
59
|
+
roi = self.ellipse_roi.roi
|
|
60
|
+
mean = roi.mean
|
|
61
|
+
if isinstance(mean, (float, int)):
|
|
62
|
+
self.average.value = mean
|
|
63
|
+
else:
|
|
64
|
+
self.average.value = math.sqrt(math.sumprod(mean, mean))
|
|
65
|
+
|
|
66
|
+
def on_image_load(self, viewer: BaseViewer) -> None:
|
|
67
|
+
if viewer is self.viewer:
|
|
68
|
+
image = self.viewer.image
|
|
69
|
+
if image is not None:
|
|
70
|
+
self.height.value = image.shape[1]
|
|
71
|
+
self.width.value = image.shape[2]
|
|
72
|
+
|
|
73
|
+
def load_commands(self):
|
|
74
|
+
self.register_command("Copy Average", self.copy_average)
|
|
75
|
+
|
|
76
|
+
def copy_average(self):
|
|
77
|
+
"""
|
|
78
|
+
Copy the value of the average to the clipboard.
|
|
79
|
+
"""
|
|
80
|
+
tk_copy(str(self.average.value))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class ExampleCollection(BaseCollection):
|
|
84
|
+
"""
|
|
85
|
+
An example collection.
|
|
86
|
+
|
|
87
|
+
This collection demonstrates the use of the PumpIA collections.
|
|
88
|
+
It has 2 viewers in the main window and loads 2 `ExampleModule` instances into a second window.
|
|
89
|
+
"""
|
|
90
|
+
viewer1 = ArrayViewerIO(row=0, column=0)
|
|
91
|
+
viewer2 = ArrayViewerIO(row=0, column=1, main=True)
|
|
92
|
+
|
|
93
|
+
module1 = ExampleModule()
|
|
94
|
+
module2 = ExampleModule()
|
|
95
|
+
|
|
96
|
+
average_output = OutputFrame()
|
|
97
|
+
|
|
98
|
+
# makes sure the two modules are in the same window in the collection
|
|
99
|
+
group = WindowGroup([module1, module2])
|
|
100
|
+
|
|
101
|
+
def load_outputs(self):
|
|
102
|
+
self.average_output.register_output(self.module1.average, verbose_name="Average 1")
|
|
103
|
+
self.average_output.register_output(self.module2.average, verbose_name="Average 2")
|
|
104
|
+
IOGroup([self.module1.size, self.module2.size])
|
|
105
|
+
|
|
106
|
+
def on_image_load(self, viewer: BaseViewer) -> None:
|
|
107
|
+
# loads the image loaded into a viewer into the relevant modules viewer
|
|
108
|
+
# if the image is an ImageCollection then only loads the first image into the module
|
|
109
|
+
if viewer is self.viewer1:
|
|
110
|
+
if self.viewer1.image is not None:
|
|
111
|
+
image = self.viewer1.image
|
|
112
|
+
if isinstance(image, ImageCollection):
|
|
113
|
+
self.module1.viewer.load_image(image.image_set[0])
|
|
114
|
+
else:
|
|
115
|
+
self.module1.viewer.load_image(image)
|
|
116
|
+
|
|
117
|
+
elif viewer is self.viewer2:
|
|
118
|
+
if self.viewer2.image is not None:
|
|
119
|
+
image = self.viewer2.image
|
|
120
|
+
if isinstance(image, ImageCollection):
|
|
121
|
+
self.module2.viewer.load_image(image.image_set[0])
|
|
122
|
+
else:
|
|
123
|
+
self.module2.viewer.load_image(image)
|
|
124
|
+
|
|
125
|
+
def load_commands(self):
|
|
126
|
+
self.register_command("Copy Averages", self.copy_averages)
|
|
127
|
+
|
|
128
|
+
def copy_averages(self):
|
|
129
|
+
"""
|
|
130
|
+
Copy the values of the averages to the clipboard, comma seperated.
|
|
131
|
+
"""
|
|
132
|
+
tk_copy(", ".join([str(self.module1.average.value), str(self.module2.average.value)]))
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
if __name__ == "__main__":
|
|
136
|
+
ExampleCollection.run()
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
from pumpia.widgets.viewers import BaseViewer
|
|
4
|
+
from pumpia.module_handling.modules import BaseModule
|
|
5
|
+
from pumpia.module_handling.in_outs.roi_ios import BaseInputROI, InputEllipseROI
|
|
6
|
+
from pumpia.module_handling.in_outs.viewer_ios import ArrayViewerIO
|
|
7
|
+
from pumpia.module_handling.in_outs.simple import PercInput, FloatOutput, IntOutput
|
|
8
|
+
from pumpia.module_handling.context import SimpleContext
|
|
9
|
+
from pumpia.image_handling.roi_structures import EllipseROI
|
|
10
|
+
from pumpia.utilities.tkinter_utils import tk_copy
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ExampleModule(BaseModule):
|
|
14
|
+
"""
|
|
15
|
+
An Example Module.
|
|
16
|
+
|
|
17
|
+
This module demonstrates the use of the PumpIA modules.
|
|
18
|
+
It draws an ellipse ROI on an image based on the size of image and input from the user.
|
|
19
|
+
The analysis calculates the average pixel value within the ellipse,
|
|
20
|
+
or the root sum of squares of the means if a multisample image.
|
|
21
|
+
"""
|
|
22
|
+
viewer = ArrayViewerIO(row=0, column=0)
|
|
23
|
+
size = PercInput(80, verbose_name="Size (%)")
|
|
24
|
+
ellipse_roi = InputEllipseROI("Ellipse ROI")
|
|
25
|
+
|
|
26
|
+
width = IntOutput(verbose_name="Width (px)")
|
|
27
|
+
height = IntOutput(verbose_name="Height (px)")
|
|
28
|
+
average = FloatOutput()
|
|
29
|
+
|
|
30
|
+
def link_rois_viewers(self):
|
|
31
|
+
self.ellipse_roi.viewer = self.viewer
|
|
32
|
+
|
|
33
|
+
def draw_rois(self, context: SimpleContext, batch: bool = False):
|
|
34
|
+
if self.viewer.image is not None:
|
|
35
|
+
factor = self.size.value / 100
|
|
36
|
+
a = round(factor * context.width / 2)
|
|
37
|
+
b = round(factor * context.height / 2)
|
|
38
|
+
self.ellipse_roi.register_roi(EllipseROI(self.viewer.image,
|
|
39
|
+
round(context.xcent),
|
|
40
|
+
round(context.ycent),
|
|
41
|
+
a,
|
|
42
|
+
b,
|
|
43
|
+
slice_num=self.viewer.current_slice))
|
|
44
|
+
|
|
45
|
+
def post_roi_register(self, roi_input: BaseInputROI):
|
|
46
|
+
if self.ellipse_roi.roi is not None and self.manager is not None:
|
|
47
|
+
self.manager.add_roi(self.ellipse_roi.roi)
|
|
48
|
+
|
|
49
|
+
def analyse(self, batch: bool = False):
|
|
50
|
+
if self.ellipse_roi.roi is not None:
|
|
51
|
+
roi = self.ellipse_roi.roi
|
|
52
|
+
mean = roi.mean
|
|
53
|
+
if isinstance(mean, (float, int)):
|
|
54
|
+
self.average.value = mean
|
|
55
|
+
else:
|
|
56
|
+
self.average.value = math.sqrt(math.sumprod(mean, mean))
|
|
57
|
+
|
|
58
|
+
def on_image_load(self, viewer: BaseViewer) -> None:
|
|
59
|
+
if viewer is self.viewer:
|
|
60
|
+
image = self.viewer.image
|
|
61
|
+
if image is not None:
|
|
62
|
+
self.height.value = image.shape[1]
|
|
63
|
+
self.width.value = image.shape[2]
|
|
64
|
+
|
|
65
|
+
def load_commands(self):
|
|
66
|
+
self.register_command("Copy Average", self.copy_average)
|
|
67
|
+
|
|
68
|
+
def copy_average(self):
|
|
69
|
+
"""
|
|
70
|
+
Copy the value of the average to the clipboard.
|
|
71
|
+
"""
|
|
72
|
+
tk_copy(str(self.average.value))
|
|
File without changes
|