dcscope 2.22.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.
Files changed (267) hide show
  1. dcscope/__init__.py +17 -0
  2. dcscope/__main__.py +44 -0
  3. dcscope/_version.py +21 -0
  4. dcscope/extensions.py +250 -0
  5. dcscope/gui/__init__.py +2 -0
  6. dcscope/gui/analysis/__init__.py +10 -0
  7. dcscope/gui/analysis/ana_basins.py +110 -0
  8. dcscope/gui/analysis/ana_basins.ui +143 -0
  9. dcscope/gui/analysis/ana_filter.py +341 -0
  10. dcscope/gui/analysis/ana_filter.ui +364 -0
  11. dcscope/gui/analysis/ana_log.py +122 -0
  12. dcscope/gui/analysis/ana_log.ui +100 -0
  13. dcscope/gui/analysis/ana_meta.py +207 -0
  14. dcscope/gui/analysis/ana_meta.ui +141 -0
  15. dcscope/gui/analysis/ana_plot.py +638 -0
  16. dcscope/gui/analysis/ana_plot.ui +1060 -0
  17. dcscope/gui/analysis/ana_slot.py +504 -0
  18. dcscope/gui/analysis/ana_slot.ui +684 -0
  19. dcscope/gui/analysis/ana_tables.py +227 -0
  20. dcscope/gui/analysis/ana_tables.ui +195 -0
  21. dcscope/gui/analysis/ana_view.py +69 -0
  22. dcscope/gui/analysis/ana_view.ui +269 -0
  23. dcscope/gui/analysis/dlg_slot_reorder.py +55 -0
  24. dcscope/gui/analysis/dlg_slot_reorder.ui +138 -0
  25. dcscope/gui/bulk/__init__.py +2 -0
  26. dcscope/gui/bulk/bulk_emodulus.py +200 -0
  27. dcscope/gui/bulk/bulk_emodulus.ui +245 -0
  28. dcscope/gui/compute/__init__.py +3 -0
  29. dcscope/gui/compute/comp_lme4.py +115 -0
  30. dcscope/gui/compute/comp_lme4.ui +194 -0
  31. dcscope/gui/compute/comp_lme4_dataset.py +51 -0
  32. dcscope/gui/compute/comp_lme4_dataset.ui +92 -0
  33. dcscope/gui/compute/comp_lme4_results.py +120 -0
  34. dcscope/gui/compute/comp_lme4_results.ui +268 -0
  35. dcscope/gui/compute/comp_stats.py +223 -0
  36. dcscope/gui/compute/comp_stats.ui +187 -0
  37. dcscope/gui/dcor/__init__.py +304 -0
  38. dcscope/gui/dcor/dcor.ui +118 -0
  39. dcscope/gui/export/__init__.py +3 -0
  40. dcscope/gui/export/e2data.py +394 -0
  41. dcscope/gui/export/e2data.ui +367 -0
  42. dcscope/gui/export/e2filter.py +76 -0
  43. dcscope/gui/export/e2filter.ui +111 -0
  44. dcscope/gui/export/e2plot.py +94 -0
  45. dcscope/gui/export/e2plot.ui +175 -0
  46. dcscope/gui/main.py +1089 -0
  47. dcscope/gui/main.ui +579 -0
  48. dcscope/gui/matrix/__init__.py +4 -0
  49. dcscope/gui/matrix/block_matrix.py +141 -0
  50. dcscope/gui/matrix/block_matrix.ui +207 -0
  51. dcscope/gui/matrix/data_matrix.py +574 -0
  52. dcscope/gui/matrix/dm_dataset.py +116 -0
  53. dcscope/gui/matrix/dm_dataset.ui +348 -0
  54. dcscope/gui/matrix/dm_element.py +111 -0
  55. dcscope/gui/matrix/dm_element.ui +169 -0
  56. dcscope/gui/matrix/dm_filter.py +115 -0
  57. dcscope/gui/matrix/dm_filter.ui +287 -0
  58. dcscope/gui/matrix/plot_matrix.py +316 -0
  59. dcscope/gui/matrix/pm_element.py +39 -0
  60. dcscope/gui/matrix/pm_plot.py +86 -0
  61. dcscope/gui/matrix/pm_plot.ui +249 -0
  62. dcscope/gui/pipeline_plot.py +797 -0
  63. dcscope/gui/pipeline_plot.ui +66 -0
  64. dcscope/gui/preferences.py +380 -0
  65. dcscope/gui/preferences.ui +554 -0
  66. dcscope/gui/quick_view/__init__.py +1 -0
  67. dcscope/gui/quick_view/qv_main.py +1072 -0
  68. dcscope/gui/quick_view/qv_main.ui +1297 -0
  69. dcscope/gui/quick_view/qv_scatter.py +284 -0
  70. dcscope/gui/quick_view/qv_style.css +10 -0
  71. dcscope/gui/update.py +90 -0
  72. dcscope/gui/widgets/__init__.py +15 -0
  73. dcscope/gui/widgets/bg_thread.py +29 -0
  74. dcscope/gui/widgets/bulk_list.py +79 -0
  75. dcscope/gui/widgets/bulk_list.ui +95 -0
  76. dcscope/gui/widgets/double_spin_box_nan.py +75 -0
  77. dcscope/gui/widgets/feature_combobox.py +140 -0
  78. dcscope/gui/widgets/get_path.py +42 -0
  79. dcscope/gui/widgets/key_value_table_widget.css +12 -0
  80. dcscope/gui/widgets/key_value_table_widget.py +75 -0
  81. dcscope/gui/widgets/mdi_subwindow_wo_close.py +12 -0
  82. dcscope/gui/widgets/qrangeslider.py +262 -0
  83. dcscope/gui/widgets/rangecontrol.py +308 -0
  84. dcscope/gui/widgets/rangecontrol.ui +136 -0
  85. dcscope/gui/widgets/simple_image_view.py +55 -0
  86. dcscope/gui/widgets/simple_plot_widget.py +113 -0
  87. dcscope/gui/widgets/so_colorbaritem.py +29 -0
  88. dcscope/gui/widgets/wait_cursor.py +33 -0
  89. dcscope/idiom.py +26 -0
  90. dcscope/img/__init__.py +2 -0
  91. dcscope/img/icon-theme/breeze/COPYING-ICONS +209 -0
  92. dcscope/img/icon-theme/breeze/COPYING.LIB +510 -0
  93. dcscope/img/icon-theme/breeze/README +5 -0
  94. dcscope/img/icon-theme/breeze/actions/16/application-exit.svg +17 -0
  95. dcscope/img/icon-theme/breeze/actions/16/code-context.svg +13 -0
  96. dcscope/img/icon-theme/breeze/actions/16/dialog-cancel.svg +13 -0
  97. dcscope/img/icon-theme/breeze/actions/16/dialog-close.svg +17 -0
  98. dcscope/img/icon-theme/breeze/actions/16/dialog-messages.svg +13 -0
  99. dcscope/img/icon-theme/breeze/actions/16/dialog-ok-apply.svg +13 -0
  100. dcscope/img/icon-theme/breeze/actions/16/dialog-ok.svg +13 -0
  101. dcscope/img/icon-theme/breeze/actions/16/document-open-folder.svg +13 -0
  102. dcscope/img/icon-theme/breeze/actions/16/document-open.svg +13 -0
  103. dcscope/img/icon-theme/breeze/actions/16/document-save.svg +13 -0
  104. dcscope/img/icon-theme/breeze/actions/16/documentinfo.svg +12 -0
  105. dcscope/img/icon-theme/breeze/actions/16/draw-watercolor.svg +13 -0
  106. dcscope/img/icon-theme/breeze/actions/16/edit-clear-all.svg +13 -0
  107. dcscope/img/icon-theme/breeze/actions/16/edit-clear.svg +13 -0
  108. dcscope/img/icon-theme/breeze/actions/16/edit-paste.svg +13 -0
  109. dcscope/img/icon-theme/breeze/actions/16/globe.svg +16 -0
  110. dcscope/img/icon-theme/breeze/actions/16/gtk-preferences.svg +13 -0
  111. dcscope/img/icon-theme/breeze/actions/16/list-add.svg +13 -0
  112. dcscope/img/icon-theme/breeze/actions/16/messagebox_warning.svg +20 -0
  113. dcscope/img/icon-theme/breeze/actions/16/object-columns.svg +13 -0
  114. dcscope/img/icon-theme/breeze/actions/16/object-order-lower.svg +13 -0
  115. dcscope/img/icon-theme/breeze/actions/16/object-rows.svg +13 -0
  116. dcscope/img/icon-theme/breeze/actions/16/office-chart-line-stacked.svg +13 -0
  117. dcscope/img/icon-theme/breeze/actions/16/office-chart-ring.svg +13 -0
  118. dcscope/img/icon-theme/breeze/actions/16/office-chart-scatter.svg +13 -0
  119. dcscope/img/icon-theme/breeze/actions/16/path-mode-polyline.svg +13 -0
  120. dcscope/img/icon-theme/breeze/actions/16/preferences-activities.svg +13 -0
  121. dcscope/img/icon-theme/breeze/actions/16/remove.svg +10 -0
  122. dcscope/img/icon-theme/breeze/actions/16/search.svg +13 -0
  123. dcscope/img/icon-theme/breeze/actions/16/show-grid.svg +13 -0
  124. dcscope/img/icon-theme/breeze/actions/16/special_paste.svg +13 -0
  125. dcscope/img/icon-theme/breeze/actions/16/tools-wizard.svg +13 -0
  126. dcscope/img/icon-theme/breeze/actions/16/view-calendar-list.svg +13 -0
  127. dcscope/img/icon-theme/breeze/actions/16/view-filter.svg +13 -0
  128. dcscope/img/icon-theme/breeze/actions/16/view-list-tree.svg +13 -0
  129. dcscope/img/icon-theme/breeze/actions/16/view-statistics.svg +13 -0
  130. dcscope/img/icon-theme/breeze/actions/16/visibility.svg +21 -0
  131. dcscope/img/icon-theme/breeze/actions/22/application-exit.svg +13 -0
  132. dcscope/img/icon-theme/breeze/actions/22/code-context.svg +14 -0
  133. dcscope/img/icon-theme/breeze/actions/22/dialog-cancel.svg +14 -0
  134. dcscope/img/icon-theme/breeze/actions/22/dialog-close.svg +10 -0
  135. dcscope/img/icon-theme/breeze/actions/22/dialog-messages.svg +14 -0
  136. dcscope/img/icon-theme/breeze/actions/22/dialog-ok-apply.svg +14 -0
  137. dcscope/img/icon-theme/breeze/actions/22/dialog-ok.svg +14 -0
  138. dcscope/img/icon-theme/breeze/actions/22/document-open-folder.svg +14 -0
  139. dcscope/img/icon-theme/breeze/actions/22/document-open.svg +14 -0
  140. dcscope/img/icon-theme/breeze/actions/22/document-save.svg +14 -0
  141. dcscope/img/icon-theme/breeze/actions/22/documentinfo.svg +14 -0
  142. dcscope/img/icon-theme/breeze/actions/22/draw-watercolor.svg +14 -0
  143. dcscope/img/icon-theme/breeze/actions/22/edit-clear-all.svg +14 -0
  144. dcscope/img/icon-theme/breeze/actions/22/edit-clear.svg +14 -0
  145. dcscope/img/icon-theme/breeze/actions/22/edit-paste.svg +14 -0
  146. dcscope/img/icon-theme/breeze/actions/22/globe.svg +12 -0
  147. dcscope/img/icon-theme/breeze/actions/22/gtk-preferences.svg +13 -0
  148. dcscope/img/icon-theme/breeze/actions/22/list-add.svg +14 -0
  149. dcscope/img/icon-theme/breeze/actions/22/messagebox_warning.svg +17 -0
  150. dcscope/img/icon-theme/breeze/actions/22/object-columns.svg +14 -0
  151. dcscope/img/icon-theme/breeze/actions/22/object-order-lower.svg +17 -0
  152. dcscope/img/icon-theme/breeze/actions/22/object-rows.svg +17 -0
  153. dcscope/img/icon-theme/breeze/actions/22/office-chart-line-stacked.svg +17 -0
  154. dcscope/img/icon-theme/breeze/actions/22/office-chart-ring.svg +17 -0
  155. dcscope/img/icon-theme/breeze/actions/22/office-chart-scatter.svg +17 -0
  156. dcscope/img/icon-theme/breeze/actions/22/path-mode-polyline.svg +17 -0
  157. dcscope/img/icon-theme/breeze/actions/22/preferences-activities.svg +14 -0
  158. dcscope/img/icon-theme/breeze/actions/22/remove.svg +10 -0
  159. dcscope/img/icon-theme/breeze/actions/22/special_paste.svg +14 -0
  160. dcscope/img/icon-theme/breeze/actions/22/tools-wizard.svg +14 -0
  161. dcscope/img/icon-theme/breeze/actions/22/view-calendar-list.svg +14 -0
  162. dcscope/img/icon-theme/breeze/actions/22/view-filter.svg +14 -0
  163. dcscope/img/icon-theme/breeze/actions/22/view-list-tree.svg +14 -0
  164. dcscope/img/icon-theme/breeze/actions/22/view-statistics.svg +14 -0
  165. dcscope/img/icon-theme/breeze/actions/22/visibility.svg +14 -0
  166. dcscope/img/icon-theme/breeze/actions/24/application-exit.svg +12 -0
  167. dcscope/img/icon-theme/breeze/actions/24/code-context.svg +12 -0
  168. dcscope/img/icon-theme/breeze/actions/24/dialog-cancel.svg +12 -0
  169. dcscope/img/icon-theme/breeze/actions/24/dialog-close.svg +10 -0
  170. dcscope/img/icon-theme/breeze/actions/24/dialog-messages.svg +12 -0
  171. dcscope/img/icon-theme/breeze/actions/24/dialog-ok-apply.svg +12 -0
  172. dcscope/img/icon-theme/breeze/actions/24/dialog-ok.svg +14 -0
  173. dcscope/img/icon-theme/breeze/actions/24/document-open-folder.svg +12 -0
  174. dcscope/img/icon-theme/breeze/actions/24/document-open.svg +12 -0
  175. dcscope/img/icon-theme/breeze/actions/24/document-save.svg +12 -0
  176. dcscope/img/icon-theme/breeze/actions/24/documentinfo.svg +14 -0
  177. dcscope/img/icon-theme/breeze/actions/24/draw-watercolor.svg +12 -0
  178. dcscope/img/icon-theme/breeze/actions/24/edit-clear-all.svg +14 -0
  179. dcscope/img/icon-theme/breeze/actions/24/edit-clear.svg +12 -0
  180. dcscope/img/icon-theme/breeze/actions/24/edit-paste.svg +12 -0
  181. dcscope/img/icon-theme/breeze/actions/24/globe.svg +14 -0
  182. dcscope/img/icon-theme/breeze/actions/24/gtk-preferences.svg +13 -0
  183. dcscope/img/icon-theme/breeze/actions/24/list-add.svg +12 -0
  184. dcscope/img/icon-theme/breeze/actions/24/messagebox_warning.svg +13 -0
  185. dcscope/img/icon-theme/breeze/actions/24/object-columns.svg +12 -0
  186. dcscope/img/icon-theme/breeze/actions/24/object-order-lower.svg +15 -0
  187. dcscope/img/icon-theme/breeze/actions/24/object-rows.svg +15 -0
  188. dcscope/img/icon-theme/breeze/actions/24/office-chart-line-stacked.svg +15 -0
  189. dcscope/img/icon-theme/breeze/actions/24/office-chart-ring.svg +15 -0
  190. dcscope/img/icon-theme/breeze/actions/24/office-chart-scatter.svg +15 -0
  191. dcscope/img/icon-theme/breeze/actions/24/path-mode-polyline.svg +15 -0
  192. dcscope/img/icon-theme/breeze/actions/24/preferences-activities.svg +13 -0
  193. dcscope/img/icon-theme/breeze/actions/24/remove.svg +10 -0
  194. dcscope/img/icon-theme/breeze/actions/24/special_paste.svg +12 -0
  195. dcscope/img/icon-theme/breeze/actions/24/tools-wizard.svg +12 -0
  196. dcscope/img/icon-theme/breeze/actions/24/view-calendar-list.svg +12 -0
  197. dcscope/img/icon-theme/breeze/actions/24/view-filter.svg +12 -0
  198. dcscope/img/icon-theme/breeze/actions/24/view-list-tree.svg +12 -0
  199. dcscope/img/icon-theme/breeze/actions/24/view-statistics.svg +12 -0
  200. dcscope/img/icon-theme/breeze/actions/24/visibility.svg +14 -0
  201. dcscope/img/icon-theme/breeze/actions/32/application-exit.svg +8 -0
  202. dcscope/img/icon-theme/breeze/actions/32/dialog-cancel.svg +13 -0
  203. dcscope/img/icon-theme/breeze/actions/32/dialog-messages.svg +13 -0
  204. dcscope/img/icon-theme/breeze/actions/32/dialog-ok-apply.svg +1 -0
  205. dcscope/img/icon-theme/breeze/actions/32/dialog-ok.svg +1 -0
  206. dcscope/img/icon-theme/breeze/actions/32/document-open-folder.svg +13 -0
  207. dcscope/img/icon-theme/breeze/actions/32/document-open.svg +13 -0
  208. dcscope/img/icon-theme/breeze/actions/32/document-save.svg +18 -0
  209. dcscope/img/icon-theme/breeze/actions/32/gtk-preferences.svg +17 -0
  210. dcscope/img/icon-theme/breeze/actions/32/object-order-lower.svg +18 -0
  211. dcscope/img/icon-theme/breeze/actions/32/view-filter.svg +18 -0
  212. dcscope/img/icon-theme/breeze/actions/32/view-list-tree.svg +18 -0
  213. dcscope/img/icon-theme/breeze/places/16/folder-cloud.svg +13 -0
  214. dcscope/img/icon-theme/breeze/places/16/folder.svg +13 -0
  215. dcscope/img/icon-theme/breeze/places/22/folder-cloud.svg +13 -0
  216. dcscope/img/icon-theme/breeze/places/22/folder.svg +13 -0
  217. dcscope/img/icon-theme/breeze/places/24/folder-cloud.svg +12 -0
  218. dcscope/img/icon-theme/breeze/places/24/folder.svg +12 -0
  219. dcscope/img/icon-theme/breeze/places/32/folder-cloud.svg +35 -0
  220. dcscope/img/icon-theme/breeze/places/32/folder.svg +30 -0
  221. dcscope/img/icon-theme/breeze/places/64/folder-cloud.svg +35 -0
  222. dcscope/img/icon-theme/breeze/places/64/folder.svg +30 -0
  223. dcscope/img/icon-theme/breeze/status/16/dialog-error.svg +9 -0
  224. dcscope/img/icon-theme/breeze/status/16/dialog-information.svg +9 -0
  225. dcscope/img/icon-theme/breeze/status/16/dialog-question.svg +7 -0
  226. dcscope/img/icon-theme/breeze/status/16/dialog-warning.svg +9 -0
  227. dcscope/img/icon-theme/breeze/status/22/dialog-error.svg +9 -0
  228. dcscope/img/icon-theme/breeze/status/22/dialog-information.svg +9 -0
  229. dcscope/img/icon-theme/breeze/status/22/dialog-question.svg +7 -0
  230. dcscope/img/icon-theme/breeze/status/22/dialog-warning.svg +9 -0
  231. dcscope/img/icon-theme/breeze/status/24/dialog-error.svg +13 -0
  232. dcscope/img/icon-theme/breeze/status/24/dialog-information.svg +13 -0
  233. dcscope/img/icon-theme/breeze/status/24/dialog-question.svg +9 -0
  234. dcscope/img/icon-theme/breeze/status/24/dialog-warning.svg +1 -0
  235. dcscope/img/icon-theme/breeze/status/64/dialog-error.svg +25 -0
  236. dcscope/img/icon-theme/breeze/status/64/dialog-information.svg +25 -0
  237. dcscope/img/icon-theme/breeze/status/64/dialog-question.svg +25 -0
  238. dcscope/img/icon-theme/breeze/status/64/dialog-warning.svg +25 -0
  239. dcscope/img/icon-theme/collect_icons.py +124 -0
  240. dcscope/img/icon-theme/dcscope/dcor.png +0 -0
  241. dcscope/img/icon-theme/dcscope/edit-copy-anew.svg +13 -0
  242. dcscope/img/icon-theme/dcscope/emodulus.svg +69 -0
  243. dcscope/img/icon-theme/dcscope/filter_ray.svg +54 -0
  244. dcscope/img/icon-theme/dcscope/region_channel.svg +86 -0
  245. dcscope/img/icon-theme/dcscope/region_reservoir.svg +89 -0
  246. dcscope/img/icon-theme/dcscope/rlang.svg +108 -0
  247. dcscope/img/icon-theme/dcscope/statistical_significance.svg +106 -0
  248. dcscope/img/icon-theme/index.theme +81 -0
  249. dcscope/img/icon.png +0 -0
  250. dcscope/img/icon.svg +73 -0
  251. dcscope/img/splash.png +0 -0
  252. dcscope/meta_tool.py +143 -0
  253. dcscope/pipeline/__init__.py +5 -0
  254. dcscope/pipeline/core.py +632 -0
  255. dcscope/pipeline/dataslot.py +270 -0
  256. dcscope/pipeline/filter.py +161 -0
  257. dcscope/pipeline/filter_ray.py +170 -0
  258. dcscope/pipeline/plot.py +187 -0
  259. dcscope/plot_cache.py +79 -0
  260. dcscope/session.py +379 -0
  261. dcscope/util.py +34 -0
  262. dcscope-2.22.1.dist-info/METADATA +95 -0
  263. dcscope-2.22.1.dist-info/RECORD +267 -0
  264. dcscope-2.22.1.dist-info/WHEEL +5 -0
  265. dcscope-2.22.1.dist-info/entry_points.txt +2 -0
  266. dcscope-2.22.1.dist-info/licenses/LICENSE +621 -0
  267. dcscope-2.22.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,316 @@
1
+ import copy
2
+
3
+ from PyQt6 import QtCore, QtWidgets
4
+
5
+ from ... import pipeline
6
+
7
+ from .pm_element import MatrixElement
8
+ from .pm_plot import MatrixPlot
9
+
10
+
11
+ class PlotMatrix(QtWidgets.QWidget):
12
+ plot_modify_clicked = QtCore.pyqtSignal(str)
13
+ matrix_changed = QtCore.pyqtSignal()
14
+
15
+ def __init__(self, *args, **kwargs):
16
+ super(PlotMatrix, self).__init__(*args, **kwargs)
17
+
18
+ self.glo = None
19
+ self._reset_layout(init=True)
20
+
21
+ # used for toggling between all active, all inactive and semi state
22
+ self.semi_states_plot = {}
23
+
24
+ def read_pipeline_state(self):
25
+ """State of the current plot matrix"""
26
+ # plots
27
+ plots = []
28
+ for pw in self.plot_widgets:
29
+ pw_state = pw.read_pipeline_state()
30
+ plot = pipeline.Plot._instances[pw_state["identifier"]]
31
+ plots.append(plot.__getstate__())
32
+ # elements
33
+ mestates = {}
34
+ dm = self.data_matrix
35
+ for dw in dm.dataset_widgets:
36
+ idict = {}
37
+ for pw in self.plot_widgets:
38
+ me = self.get_matrix_element(dw.identifier, pw.identifier)
39
+ idict[pw.identifier] = me.read_pipeline_state()["active"]
40
+ mestates[dw.identifier] = idict
41
+ state = {"elements": mestates,
42
+ "plots": plots}
43
+ return state
44
+
45
+ def write_pipeline_state(self, state):
46
+ self.setUpdatesEnabled(False)
47
+ self.blockSignals(True)
48
+ self.clear()
49
+ # plot states
50
+ for jj in range(len(state["plots"])):
51
+ plot_id = state["plots"][jj]["identifier"]
52
+ pw_state = {"identifier": plot_id,
53
+ "name": state["plots"][jj]["layout"]["name"],
54
+ }
55
+ self.add_plot(state=pw_state)
56
+ # make sure elements exist
57
+ self.fill_elements()
58
+ # element states
59
+ for slot_id in state["elements"]:
60
+ ds_d = state["elements"][slot_id]
61
+ for plot_id in ds_d:
62
+ el = self.get_matrix_element(slot_id, plot_id)
63
+ el_state = el.read_pipeline_state()
64
+ el_state["active"] = ds_d[plot_id]
65
+ el.write_pipeline_state(el_state)
66
+ self.blockSignals(False)
67
+ self.setUpdatesEnabled(True)
68
+
69
+ def _reset_layout(self, init=False):
70
+ if self.glo is not None:
71
+ # send old layout to Nirvana eventually
72
+ layout = self.glo
73
+ self.glo = None
74
+ self.old_layout = QtWidgets.QWidget()
75
+ self.old_layout.setLayout(layout)
76
+ self.old_layout.hide()
77
+ self.old_layout.deleteLater()
78
+ # add new layout
79
+ self.glo = QtWidgets.QGridLayout()
80
+ self.glo.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeft)
81
+ self.glo.setSpacing(2)
82
+ self.glo.setContentsMargins(0, 0, 0, 0)
83
+ self.setLayout(self.glo)
84
+
85
+ @property
86
+ def data_matrix(self):
87
+ for ch in self.parent().children():
88
+ if ch.__class__.__name__ == "DataMatrix":
89
+ break
90
+ else:
91
+ raise KeyError("DataMatrix not found!")
92
+ return ch
93
+
94
+ @property
95
+ def element_widget_dict(self):
96
+ els = {}
97
+ for ii, ws in enumerate(self.data_matrix.dataset_widgets):
98
+ elsd = {}
99
+ for jj, wf in enumerate(self.plot_widgets):
100
+ it = self.glo.itemAtPosition(ii+1, jj)
101
+ elsd[wf.identifier] = it.widget()
102
+ els[ws.identifier] = elsd
103
+ return els
104
+
105
+ @property
106
+ def element_width(self):
107
+ """Data matrix element width (without 2px spacing)"""
108
+ return self.data_matrix.element_width
109
+
110
+ @property
111
+ def num_datasets(self):
112
+ dm = self.data_matrix
113
+ return dm.num_datasets
114
+
115
+ @property
116
+ def num_plots(self):
117
+ count = 0
118
+ for jj in range(self.glo.columnCount()):
119
+ if self.glo.itemAtPosition(0, jj) is not None:
120
+ count += 1
121
+ return count
122
+
123
+ @property
124
+ def plot_widgets(self):
125
+ plots = []
126
+ for jj in range(self.glo.columnCount()):
127
+ item = self.glo.itemAtPosition(0, jj)
128
+ if item is not None:
129
+ ps = item.widget()
130
+ plots.append(ps)
131
+ return plots
132
+
133
+ def add_plot(self, identifier=None, state=None):
134
+ self.setUpdatesEnabled(False)
135
+ mp = MatrixPlot(identifier=identifier, state=state)
136
+ mp.option_action.connect(self.on_option_plot)
137
+ mp.active_toggled.connect(self.toggle_plot_active)
138
+ mp.modify_clicked.connect(self.plot_modify_clicked.emit)
139
+ self.glo.addWidget(mp, 0, self.num_plots)
140
+ self.fill_elements()
141
+ self.adjust_size()
142
+ self.setUpdatesEnabled(True)
143
+ self.publish_matrix()
144
+ return mp
145
+
146
+ def adjust_size(self):
147
+ ncols = self.num_plots
148
+ nrows = self.data_matrix.num_datasets
149
+ if ncols and nrows:
150
+ width1 = self.glo.itemAt(0).widget().width()
151
+ width = (width1 + 2)*ncols - 2
152
+ height = self.data_matrix.sizeHint().height()
153
+ self.setMinimumSize(width, height)
154
+ self.setFixedSize(width, height)
155
+ QtWidgets.QApplication.processEvents(
156
+ QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 300)
157
+ self.setMinimumSize(width, height)
158
+ self.setFixedSize(width, height)
159
+
160
+ @QtCore.pyqtSlot()
161
+ def changed_element(self):
162
+ self.publish_matrix()
163
+
164
+ def clear(self):
165
+ """Reset layout"""
166
+ self._reset_layout()
167
+ self.semi_states_plot = {}
168
+
169
+ def fill_elements(self):
170
+ # add widgets
171
+ for ii in range(self.num_datasets):
172
+ for jj in range(self.num_plots):
173
+ if self.glo.itemAtPosition(ii+1, jj) is None:
174
+ me = MatrixElement()
175
+ me.element_changed.connect(self.changed_element)
176
+ self.glo.addWidget(me, ii+1, jj)
177
+ # make sure enabled/disabled is honored
178
+ dstate = self.data_matrix.read_pipeline_state()
179
+ pstate = self.read_pipeline_state()
180
+ for slot_state in dstate["slots"]:
181
+ slot_id = slot_state["identifier"]
182
+ if slot_id not in dstate["slots used"]:
183
+ for plot_state in pstate["plots"]:
184
+ plot_id = plot_state["identifier"]
185
+ me = self.get_matrix_element(slot_id, plot_id)
186
+ mstate = me.read_pipeline_state()
187
+ mstate["enabled"] = False
188
+ me.write_pipeline_state(mstate)
189
+
190
+ def get_matrix_element(self, dataset_id, plot_id):
191
+ """Return matrix element matching dataset and plot identifiers"""
192
+ ncols = self.glo.columnCount()
193
+ nrows = self.glo.rowCount()
194
+ for ii in range(1, nrows):
195
+ dw = self.data_matrix.glo.itemAtPosition(ii, 0).widget()
196
+ if dw.identifier == dataset_id:
197
+ for jj in range(ncols):
198
+ f = self.glo.itemAtPosition(0, jj).widget()
199
+ if f.identifier == plot_id:
200
+ break
201
+ else:
202
+ raise KeyError("Plot '{}' not found!".format(plot_id))
203
+ break
204
+ else:
205
+ raise KeyError("Dataset '{}' not found!".format(dataset_id))
206
+ return self.glo.itemAtPosition(ii, jj).widget()
207
+
208
+ def get_plot_index(self, plot_id):
209
+ for ii, pw in enumerate(self.plot_widgets):
210
+ if pw.identifier == plot_id:
211
+ break
212
+ else:
213
+ raise KeyError("Dataset '{}' not found!".format(plot_id))
214
+ return ii
215
+
216
+ def get_plot_widget_state(self, plot_id, ret_index=False):
217
+ ii = self.get_plot_index(plot_id)
218
+ pw = self.plot_widgets[ii]
219
+ if ret_index:
220
+ return pw.read_pipeline_state(), ii
221
+ else:
222
+ return pw.read_pipeline_state()
223
+
224
+ @QtCore.pyqtSlot(str)
225
+ def on_option_plot(self, option):
226
+ """Plot option logic (remove, duplicate)"""
227
+ pw_state = self.sender().read_pipeline_state()
228
+ plot_id = pw_state["identifier"]
229
+ plot_index = self.get_plot_index(plot_id)
230
+ state = self.read_pipeline_state()
231
+ if option == "remove":
232
+ state["plots"].pop(plot_index)
233
+ for ds_key in state["elements"]:
234
+ state["elements"][ds_key].pop(plot_id)
235
+ else: # duplicate
236
+ plot = pipeline.Plot()
237
+ new_state = copy.deepcopy(state["plots"][plot_index])
238
+ new_state["identifier"] = plot.identifier
239
+ new_state["layout"]["name"] = plot.name
240
+ state["plots"].insert(plot_index+1, new_state)
241
+ plot.__setstate__(new_state)
242
+ self.write_pipeline_state(state)
243
+ self.publish_matrix()
244
+
245
+ def publish_matrix(self):
246
+ """Publish state via self.matrix_changed signal for Pipeline"""
247
+ if not self.signalsBlocked():
248
+ self.matrix_changed.emit()
249
+
250
+ @QtCore.pyqtSlot(bool)
251
+ def toggle_dataset_enable(self, enabled):
252
+ sender = self.sender()
253
+ sid = sender.identifier
254
+ state = self.read_pipeline_state()
255
+ for p_key in state["elements"][sid]:
256
+ # update element widget
257
+ me = self.get_matrix_element(sid, p_key)
258
+ mstate = me.read_pipeline_state()
259
+ mstate["enabled"] = enabled
260
+ me.write_pipeline_state(mstate)
261
+ self.publish_matrix()
262
+
263
+ @QtCore.pyqtSlot()
264
+ def toggle_plot_active(self):
265
+ """Switch between all active, all inactive, previous state
266
+
267
+ Modifies the matrix elements for a plot/column,
268
+ which is defined by the signal sender :class:`MatrixPlot`.
269
+ Cyclic toggling order: semi -> all -> none
270
+ """
271
+ sender = self.sender()
272
+ plot_id = sender.identifier
273
+
274
+ states = self.read_pipeline_state()["elements"]
275
+ state = {}
276
+ for slot_id in states:
277
+ state[slot_id] = states[slot_id][plot_id]
278
+
279
+ num_actives = sum(list(state.values()))
280
+
281
+ # update state according to the scheme in the docstring
282
+ if num_actives == 0:
283
+ if plot_id in self.semi_states_plot:
284
+ # use semi state
285
+ oldstate = self.semi_states_plot[plot_id]
286
+ for slot_id in oldstate:
287
+ if slot_id in state:
288
+ state[slot_id] = oldstate[slot_id]
289
+ else:
290
+ # toggle all to active
291
+ for slot_id in state:
292
+ state[slot_id] = True
293
+ elif num_actives == len(state):
294
+ # toggle all to inactive
295
+ for slot_id in state:
296
+ state[slot_id] = False
297
+ else:
298
+ # save semi state
299
+ self.semi_states_plot[plot_id] = copy.deepcopy(state)
300
+ # toggle all to active
301
+ for slot_id in state:
302
+ state[slot_id] = True
303
+
304
+ for slot_id in state:
305
+ me = self.get_matrix_element(slot_id, plot_id)
306
+ me.set_active(state[slot_id])
307
+ self.publish_matrix()
308
+
309
+ def update_content(self):
310
+ ncols = self.glo.columnCount()
311
+ nrows = self.glo.rowCount()
312
+ for ii in range(nrows):
313
+ for jj in range(ncols):
314
+ item = self.glo.itemAtPosition(ii, jj)
315
+ if item is not None:
316
+ item.widget().update_content()
@@ -0,0 +1,39 @@
1
+ from . import dm_element
2
+
3
+
4
+ class MatrixElement(dm_element.MatrixElement):
5
+ def mousePressEvent(self, event):
6
+ # toggle selection
7
+ if not self.invalid:
8
+ self.active = not self.active
9
+ self.element_changed.emit()
10
+ self.update_content()
11
+ event.accept()
12
+
13
+ def update_content(self, quickview=False):
14
+ if self.invalid:
15
+ color = "#DCDCDC" # gray
16
+ label = "invalid"
17
+ tooltip = "Incompatible plot settings"
18
+ elif self.active and self.enabled:
19
+ color = "#86E7C1" # turquois
20
+ label = "active"
21
+ tooltip = "Click to deactivate"
22
+ elif self.active and not self.enabled:
23
+ color = "#C9DAD7" # gray-turquois
24
+ label = "active\n(unused)"
25
+ tooltip = "Click to deactivate"
26
+ elif not self.active and self.enabled:
27
+ color = "#EFEFEF" # light gray
28
+ label = "inactive"
29
+ tooltip = "Click to activate"
30
+ else:
31
+ color = "#DCDCDC" # gray
32
+ label = "inactive\n(unused)"
33
+ tooltip = "Click to activate"
34
+
35
+ self.label.setText(label)
36
+ self.setToolTip(tooltip)
37
+ self.label.setToolTip(tooltip)
38
+ self.setStyleSheet(
39
+ "background-color:{};color:black".format(color))
@@ -0,0 +1,86 @@
1
+ import importlib.resources
2
+
3
+ from PyQt6 import uic, QtCore, QtWidgets
4
+
5
+ from ... import pipeline
6
+
7
+
8
+ class MatrixPlot(QtWidgets.QWidget):
9
+ active_toggled = QtCore.pyqtSignal()
10
+ option_action = QtCore.pyqtSignal(str)
11
+ modify_clicked = QtCore.pyqtSignal(str)
12
+
13
+ def __init__(self, identifier=None, state=None, *args, **kwargs):
14
+ super(MatrixPlot, self).__init__(*args, **kwargs)
15
+ ref = importlib.resources.files("dcscope.gui.matrix") / "pm_plot.ui"
16
+ with importlib.resources.as_file(ref) as path_ui:
17
+ uic.loadUi(path_ui, self)
18
+
19
+ # options button
20
+ menu = QtWidgets.QMenu()
21
+ menu.addAction('duplicate', self.action_duplicate)
22
+ menu.addAction('remove', self.action_remove)
23
+ self.toolButton_opt.setMenu(menu)
24
+
25
+ # toggle all active, all inactive, semi state
26
+ self.toolButton_toggle.clicked.connect(self.active_toggled.emit)
27
+ self.toolButton_modify.clicked.connect(self.on_modify)
28
+
29
+ if state is None:
30
+ plot = pipeline.Plot._instances[identifier]
31
+ self.identifier = identifier
32
+ self.name = plot.name
33
+ # set tooltip/label
34
+ self.update_content()
35
+ else:
36
+ self.write_pipeline_state(state)
37
+
38
+ def read_pipeline_state(self):
39
+ state = {"name": self.name,
40
+ "identifier": self.identifier,
41
+ }
42
+ return state
43
+
44
+ def write_pipeline_state(self, state):
45
+ self.identifier = state["identifier"]
46
+ self.name = state["name"]
47
+ self.update_content()
48
+
49
+ @property
50
+ def name(self):
51
+ plot = pipeline.Plot._instances[self.identifier]
52
+ return plot.name
53
+
54
+ @name.setter
55
+ def name(self, text):
56
+ plot = pipeline.Plot._instances[self.identifier]
57
+ plot.name = text
58
+
59
+ def action_duplicate(self):
60
+ self.option_action.emit("duplicate")
61
+
62
+ def action_remove(self):
63
+ self.option_action.emit("remove")
64
+
65
+ def on_modify(self):
66
+ self.modify_clicked.emit(self.identifier)
67
+
68
+ def set_label_string(self, string):
69
+ if self.label.fontMetrics().boundingRect(string).width() < 60:
70
+ nstring = string
71
+ else:
72
+ nstring = string + "..."
73
+ while True:
74
+ width = self.label.fontMetrics().boundingRect(nstring).width()
75
+ if width > 60:
76
+ nstring = nstring[:-4] + "..."
77
+ else:
78
+ break
79
+ self.label.setText(nstring)
80
+
81
+ @QtCore.pyqtSlot()
82
+ def update_content(self):
83
+ """Reset tool tips and title"""
84
+ self.label.setToolTip(self.name)
85
+ self.set_label_string(self.name)
86
+ self.update()
@@ -0,0 +1,249 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ui version="4.0">
3
+ <class>Form</class>
4
+ <widget class="QWidget" name="Form">
5
+ <property name="enabled">
6
+ <bool>true</bool>
7
+ </property>
8
+ <property name="geometry">
9
+ <rect>
10
+ <x>0</x>
11
+ <y>0</y>
12
+ <width>94</width>
13
+ <height>110</height>
14
+ </rect>
15
+ </property>
16
+ <property name="sizePolicy">
17
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
18
+ <horstretch>0</horstretch>
19
+ <verstretch>0</verstretch>
20
+ </sizepolicy>
21
+ </property>
22
+ <property name="maximumSize">
23
+ <size>
24
+ <width>120</width>
25
+ <height>120</height>
26
+ </size>
27
+ </property>
28
+ <property name="font">
29
+ <font>
30
+ <pointsize>9</pointsize>
31
+ </font>
32
+ </property>
33
+ <property name="windowTitle">
34
+ <string>Form</string>
35
+ </property>
36
+ <property name="autoFillBackground">
37
+ <bool>false</bool>
38
+ </property>
39
+ <property name="styleSheet">
40
+ <string notr="true">background-color:#86B5E7; color:black</string>
41
+ </property>
42
+ <layout class="QVBoxLayout" name="verticalLayout">
43
+ <property name="spacing">
44
+ <number>0</number>
45
+ </property>
46
+ <property name="sizeConstraint">
47
+ <enum>QLayout::SetFixedSize</enum>
48
+ </property>
49
+ <property name="leftMargin">
50
+ <number>0</number>
51
+ </property>
52
+ <property name="topMargin">
53
+ <number>0</number>
54
+ </property>
55
+ <property name="rightMargin">
56
+ <number>0</number>
57
+ </property>
58
+ <property name="bottomMargin">
59
+ <number>0</number>
60
+ </property>
61
+ <item>
62
+ <widget class="QWidget" name="widget" native="true">
63
+ <property name="sizePolicy">
64
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
65
+ <horstretch>0</horstretch>
66
+ <verstretch>0</verstretch>
67
+ </sizepolicy>
68
+ </property>
69
+ <property name="minimumSize">
70
+ <size>
71
+ <width>80</width>
72
+ <height>80</height>
73
+ </size>
74
+ </property>
75
+ <property name="maximumSize">
76
+ <size>
77
+ <width>16777215</width>
78
+ <height>16777215</height>
79
+ </size>
80
+ </property>
81
+ <property name="layoutDirection">
82
+ <enum>Qt::LeftToRight</enum>
83
+ </property>
84
+ <layout class="QVBoxLayout" name="verticalLayout_2">
85
+ <property name="spacing">
86
+ <number>2</number>
87
+ </property>
88
+ <property name="sizeConstraint">
89
+ <enum>QLayout::SetFixedSize</enum>
90
+ </property>
91
+ <property name="leftMargin">
92
+ <number>2</number>
93
+ </property>
94
+ <property name="topMargin">
95
+ <number>2</number>
96
+ </property>
97
+ <property name="rightMargin">
98
+ <number>2</number>
99
+ </property>
100
+ <property name="bottomMargin">
101
+ <number>2</number>
102
+ </property>
103
+ <item alignment="Qt::AlignHCenter">
104
+ <widget class="QLabel" name="label">
105
+ <property name="sizePolicy">
106
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
107
+ <horstretch>0</horstretch>
108
+ <verstretch>0</verstretch>
109
+ </sizepolicy>
110
+ </property>
111
+ <property name="font">
112
+ <font>
113
+ <pointsize>9</pointsize>
114
+ </font>
115
+ </property>
116
+ <property name="text">
117
+ <string>Name</string>
118
+ </property>
119
+ <property name="alignment">
120
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
121
+ </property>
122
+ </widget>
123
+ </item>
124
+ <item>
125
+ <widget class="QToolButton" name="toolButton_modify">
126
+ <property name="sizePolicy">
127
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
128
+ <horstretch>0</horstretch>
129
+ <verstretch>0</verstretch>
130
+ </sizepolicy>
131
+ </property>
132
+ <property name="font">
133
+ <font>
134
+ <pointsize>9</pointsize>
135
+ </font>
136
+ </property>
137
+ <property name="toolTip">
138
+ <string>Modify this plot in Analysis View</string>
139
+ </property>
140
+ <property name="text">
141
+ <string>edit</string>
142
+ </property>
143
+ <property name="icon">
144
+ <iconset theme="tools-wizard">
145
+ <normaloff>.</normaloff>.</iconset>
146
+ </property>
147
+ <property name="toolButtonStyle">
148
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
149
+ </property>
150
+ <property name="autoRaise">
151
+ <bool>true</bool>
152
+ </property>
153
+ </widget>
154
+ </item>
155
+ <item>
156
+ <layout class="QHBoxLayout" name="horizontalLayout">
157
+ <property name="spacing">
158
+ <number>0</number>
159
+ </property>
160
+ <property name="leftMargin">
161
+ <number>0</number>
162
+ </property>
163
+ <property name="topMargin">
164
+ <number>0</number>
165
+ </property>
166
+ <property name="rightMargin">
167
+ <number>0</number>
168
+ </property>
169
+ <item>
170
+ <widget class="QToolButton" name="toolButton_toggle">
171
+ <property name="sizePolicy">
172
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
173
+ <horstretch>0</horstretch>
174
+ <verstretch>0</verstretch>
175
+ </sizepolicy>
176
+ </property>
177
+ <property name="toolTip">
178
+ <string>Include/Exclude all Datasets for this plot</string>
179
+ </property>
180
+ <property name="text">
181
+ <string>c</string>
182
+ </property>
183
+ <property name="icon">
184
+ <iconset theme="object-columns">
185
+ <normaloff>.</normaloff>.</iconset>
186
+ </property>
187
+ <property name="autoRaise">
188
+ <bool>true</bool>
189
+ </property>
190
+ </widget>
191
+ </item>
192
+ <item>
193
+ <spacer name="horizontalSpacer">
194
+ <property name="orientation">
195
+ <enum>Qt::Horizontal</enum>
196
+ </property>
197
+ <property name="sizeHint" stdset="0">
198
+ <size>
199
+ <width>0</width>
200
+ <height>20</height>
201
+ </size>
202
+ </property>
203
+ </spacer>
204
+ </item>
205
+ <item>
206
+ <widget class="QToolButton" name="toolButton_opt">
207
+ <property name="sizePolicy">
208
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
209
+ <horstretch>0</horstretch>
210
+ <verstretch>0</verstretch>
211
+ </sizepolicy>
212
+ </property>
213
+ <property name="maximumSize">
214
+ <size>
215
+ <width>50</width>
216
+ <height>16777215</height>
217
+ </size>
218
+ </property>
219
+ <property name="text">
220
+ <string>...</string>
221
+ </property>
222
+ <property name="icon">
223
+ <iconset theme="preferences-activities">
224
+ <normaloff>.</normaloff>.</iconset>
225
+ </property>
226
+ <property name="popupMode">
227
+ <enum>QToolButton::InstantPopup</enum>
228
+ </property>
229
+ <property name="toolButtonStyle">
230
+ <enum>Qt::ToolButtonIconOnly</enum>
231
+ </property>
232
+ <property name="autoRaise">
233
+ <bool>true</bool>
234
+ </property>
235
+ <property name="arrowType">
236
+ <enum>Qt::NoArrow</enum>
237
+ </property>
238
+ </widget>
239
+ </item>
240
+ </layout>
241
+ </item>
242
+ </layout>
243
+ </widget>
244
+ </item>
245
+ </layout>
246
+ </widget>
247
+ <resources/>
248
+ <connections/>
249
+ </ui>