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.
Files changed (42) hide show
  1. pumpia/__init__.py +0 -0
  2. pumpia/contrib/__init__.py +0 -0
  3. pumpia/contrib/example/__init__.py +0 -0
  4. pumpia/contrib/example/collection.py +61 -0
  5. pumpia/contrib/example/example.py +136 -0
  6. pumpia/contrib/example/module.py +72 -0
  7. pumpia/file_handling/__init__.py +0 -0
  8. pumpia/file_handling/dicom_structures.py +985 -0
  9. pumpia/file_handling/dicom_tags.py +775 -0
  10. pumpia/image_handling/__init__.py +0 -0
  11. pumpia/image_handling/image_structures.py +714 -0
  12. pumpia/image_handling/image_validators.py +24 -0
  13. pumpia/image_handling/roi_structures.py +2423 -0
  14. pumpia/module_handling/__init__.py +0 -0
  15. pumpia/module_handling/context.py +118 -0
  16. pumpia/module_handling/in_outs/__init__.py +0 -0
  17. pumpia/module_handling/in_outs/groups.py +30 -0
  18. pumpia/module_handling/in_outs/roi_ios.py +324 -0
  19. pumpia/module_handling/in_outs/simple.py +632 -0
  20. pumpia/module_handling/in_outs/viewer_ios.py +102 -0
  21. pumpia/module_handling/manager.py +893 -0
  22. pumpia/module_handling/module_collections.py +793 -0
  23. pumpia/module_handling/modules.py +844 -0
  24. pumpia/utilities/__init__.py +0 -0
  25. pumpia/utilities/array_utils.py +557 -0
  26. pumpia/utilities/dicom_utils.py +82 -0
  27. pumpia/utilities/feature_utils.py +401 -0
  28. pumpia/utilities/string_validators.py +101 -0
  29. pumpia/utilities/tkinter_utils.py +83 -0
  30. pumpia/utilities/typing.py +6 -0
  31. pumpia/widgets/__init__.py +0 -0
  32. pumpia/widgets/context_managers.py +988 -0
  33. pumpia/widgets/entry_boxes.py +553 -0
  34. pumpia/widgets/scrolled_window.py +216 -0
  35. pumpia/widgets/tables.py +305 -0
  36. pumpia/widgets/typing.py +39 -0
  37. pumpia/widgets/variables.py +54 -0
  38. pumpia/widgets/viewers.py +1493 -0
  39. pumpia-0.1.0.dist-info/METADATA +52 -0
  40. pumpia-0.1.0.dist-info/RECORD +42 -0
  41. pumpia-0.1.0.dist-info/WHEEL +4 -0
  42. 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