pymodaq 4.2.4__py3-none-any.whl → 5.0.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.

Potentially problematic release.


This version of pymodaq might be problematic. Click here for more details.

Files changed (399) hide show
  1. pymodaq/__init__.py +30 -23
  2. pymodaq/control_modules/daq_move.py +27 -14
  3. pymodaq/control_modules/daq_move_ui.py +28 -12
  4. pymodaq/control_modules/daq_viewer.py +38 -28
  5. pymodaq/control_modules/daq_viewer_ui.py +6 -6
  6. pymodaq/control_modules/mocks.py +1 -1
  7. pymodaq/control_modules/move_utility_classes.py +19 -10
  8. pymodaq/control_modules/utils.py +18 -12
  9. pymodaq/control_modules/viewer_utility_classes.py +13 -4
  10. pymodaq/dashboard.py +164 -115
  11. pymodaq/examples/custom_app.py +13 -16
  12. pymodaq/examples/custom_viewer.py +6 -6
  13. pymodaq/examples/function_plotter.py +13 -12
  14. pymodaq/examples/parameter_ex.py +50 -25
  15. pymodaq/examples/tcp_client.py +1 -1
  16. pymodaq/extensions/__init__.py +1 -1
  17. pymodaq/extensions/bayesian/bayesian_optimisation.py +15 -12
  18. pymodaq/extensions/bayesian/utils.py +10 -10
  19. pymodaq/extensions/console.py +10 -13
  20. pymodaq/extensions/{daq_logger.py → daq_logger/daq_logger.py} +36 -56
  21. pymodaq/{utils/db/db_logger → extensions/daq_logger/db}/db_logger.py +16 -15
  22. pymodaq/{utils/db/db_logger → extensions/daq_logger/db}/db_logger_models.py +2 -0
  23. pymodaq/{utils/h5modules → extensions/daq_logger}/h5logging.py +7 -8
  24. pymodaq/extensions/daq_scan.py +153 -247
  25. pymodaq/extensions/daq_scan_ui.py +11 -9
  26. pymodaq/extensions/h5browser.py +8 -8
  27. pymodaq/extensions/pid/__init__.py +6 -3
  28. pymodaq/extensions/pid/daq_move_PID.py +4 -2
  29. pymodaq/extensions/pid/pid_controller.py +15 -12
  30. pymodaq/extensions/pid/utils.py +10 -5
  31. pymodaq/extensions/utils.py +5 -3
  32. pymodaq/post_treatment/load_and_plot.py +10 -7
  33. pymodaq/resources/preset_default.xml +1 -1
  34. pymodaq/utils/array_manipulation.py +4 -384
  35. pymodaq/utils/calibration_camera.py +12 -9
  36. pymodaq/utils/chrono_timer.py +7 -5
  37. pymodaq/utils/config.py +3 -450
  38. pymodaq/utils/daq_utils.py +6 -708
  39. pymodaq/utils/data.py +9 -2774
  40. pymodaq/utils/exceptions.py +0 -4
  41. pymodaq/utils/gui_utils/__init__.py +8 -8
  42. pymodaq/utils/gui_utils/loader_utils.py +38 -0
  43. pymodaq/utils/gui_utils/utils.py +6 -138
  44. pymodaq/utils/h5modules/__init__.py +0 -4
  45. pymodaq/utils/h5modules/module_saving.py +15 -8
  46. pymodaq/utils/leco/__init__.py +2 -2
  47. pymodaq/utils/leco/daq_move_LECODirector.py +2 -2
  48. pymodaq/utils/leco/daq_xDviewer_LECODirector.py +2 -2
  49. pymodaq/utils/leco/director_utils.py +2 -2
  50. pymodaq/utils/leco/leco_director.py +3 -3
  51. pymodaq/utils/leco/pymodaq_listener.py +2 -2
  52. pymodaq/utils/leco/utils.py +1 -1
  53. pymodaq/utils/logger.py +4 -76
  54. pymodaq/utils/managers/batchscan_manager.py +16 -19
  55. pymodaq/utils/managers/modules_manager.py +10 -7
  56. pymodaq/utils/managers/overshoot_manager.py +3 -5
  57. pymodaq/utils/managers/preset_manager.py +37 -15
  58. pymodaq/utils/managers/preset_manager_utils.py +11 -9
  59. pymodaq/utils/managers/remote_manager.py +12 -10
  60. pymodaq/utils/math_utils.py +4 -572
  61. pymodaq/utils/parameter/__init__.py +4 -11
  62. pymodaq/utils/parameter/utils.py +4 -299
  63. pymodaq/utils/scanner/scan_config.py +1 -1
  64. pymodaq/utils/scanner/scan_factory.py +16 -12
  65. pymodaq/utils/{plotting → scanner}/scan_selector.py +19 -20
  66. pymodaq/utils/scanner/scanner.py +10 -8
  67. pymodaq/utils/scanner/scanners/_1d_scanners.py +8 -5
  68. pymodaq/utils/scanner/scanners/_2d_scanners.py +5 -5
  69. pymodaq/utils/scanner/scanners/sequential.py +8 -8
  70. pymodaq/utils/scanner/scanners/tabular.py +9 -9
  71. pymodaq/utils/scanner/utils.py +6 -4
  72. pymodaq/utils/svg/svg_viewer2D.py +3 -4
  73. pymodaq/utils/tcp_ip/serializer.py +64 -16
  74. pymodaq/utils/tcp_ip/tcp_server_client.py +10 -8
  75. {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/METADATA +5 -3
  76. pymodaq-5.0.0.dist-info/RECORD +123 -0
  77. pymodaq/post_treatment/process_to_scalar.py +0 -263
  78. pymodaq/resources/QtDesigner_Ressources/Icon_Library/1d.png +0 -0
  79. pymodaq/resources/QtDesigner_Ressources/Icon_Library/2d.png +0 -0
  80. pymodaq/resources/QtDesigner_Ressources/Icon_Library/3d.png +0 -0
  81. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Add2.png +0 -0
  82. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Add_Step.png +0 -0
  83. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Approve.png +0 -0
  84. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Approve_All.png +0 -0
  85. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Browse_Dir_Path.png +0 -0
  86. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Calculator.png +0 -0
  87. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnGroup.png +0 -0
  88. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnNum.png +0 -0
  89. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnText.png +0 -0
  90. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnTime.png +0 -0
  91. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnWave.png +0 -0
  92. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Close3.png +0 -0
  93. pymodaq/resources/QtDesigner_Ressources/Icon_Library/CollapseAll.png +0 -0
  94. pymodaq/resources/QtDesigner_Ressources/Icon_Library/CollapseAll_32.png +0 -0
  95. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ColorPicker.png +0 -0
  96. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Contract.png +0 -0
  97. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Create.png +0 -0
  98. pymodaq/resources/QtDesigner_Ressources/Icon_Library/DeleteLayer.png +0 -0
  99. pymodaq/resources/QtDesigner_Ressources/Icon_Library/EditOpen.png +0 -0
  100. pymodaq/resources/QtDesigner_Ressources/Icon_Library/EditRedo.png +0 -0
  101. pymodaq/resources/QtDesigner_Ressources/Icon_Library/EditUndo.png +0 -0
  102. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Ellipse.png +0 -0
  103. pymodaq/resources/QtDesigner_Ressources/Icon_Library/EllipseFilled.png +0 -0
  104. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Error.png +0 -0
  105. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ErrorMessage.png +0 -0
  106. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Error_16.png +0 -0
  107. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Exit.png +0 -0
  108. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Expand.png +0 -0
  109. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ExpandAll.png +0 -0
  110. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ExpandAll_32.png +0 -0
  111. pymodaq/resources/QtDesigner_Ressources/Icon_Library/FFT.png +0 -0
  112. pymodaq/resources/QtDesigner_Ressources/Icon_Library/HLM.ico +0 -0
  113. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Help.png +0 -0
  114. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Help_32.png +0 -0
  115. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Histogram.png +0 -0
  116. pymodaq/resources/QtDesigner_Ressources/Icon_Library/LUT_LookUpTable.png +0 -0
  117. pymodaq/resources/QtDesigner_Ressources/Icon_Library/MagnifyingGlass.png +0 -0
  118. pymodaq/resources/QtDesigner_Ressources/Icon_Library/MagnifyingGlass_24.png +0 -0
  119. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Marker.png +0 -0
  120. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Math.png +0 -0
  121. pymodaq/resources/QtDesigner_Ressources/Icon_Library/MeasurementStudio_32.png +0 -0
  122. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Move.png +0 -0
  123. pymodaq/resources/QtDesigner_Ressources/Icon_Library/MoveDown.png +0 -0
  124. pymodaq/resources/QtDesigner_Ressources/Icon_Library/MoveUp.png +0 -0
  125. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Multiply.png +0 -0
  126. pymodaq/resources/QtDesigner_Ressources/Icon_Library/NewFile.png +0 -0
  127. pymodaq/resources/QtDesigner_Ressources/Icon_Library/NewLayer.png +0 -0
  128. pymodaq/resources/QtDesigner_Ressources/Icon_Library/New_File.png +0 -0
  129. pymodaq/resources/QtDesigner_Ressources/Icon_Library/New_Folder.png +0 -0
  130. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open.png +0 -0
  131. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_1D.png +0 -0
  132. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_2D.png +0 -0
  133. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_File.png +0 -0
  134. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_File_32.png +0 -0
  135. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_sim.png +0 -0
  136. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Options.png +0 -0
  137. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Oscilloscope.png +0 -0
  138. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Oscilloscope_16.png +0 -0
  139. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Pass.png +0 -0
  140. pymodaq/resources/QtDesigner_Ressources/Icon_Library/RGB.png +0 -0
  141. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Rectangle.png +0 -0
  142. pymodaq/resources/QtDesigner_Ressources/Icon_Library/RectangleFilled.png +0 -0
  143. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Redo.png +0 -0
  144. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Refresh.png +0 -0
  145. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Refresh2.png +0 -0
  146. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Refresh_32.png +0 -0
  147. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Region.png +0 -0
  148. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Rendezvous.png +0 -0
  149. pymodaq/resources/QtDesigner_Ressources/Icon_Library/SELECT.png +0 -0
  150. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Save.png +0 -0
  151. pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAll.png +0 -0
  152. pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAll_32.png +0 -0
  153. pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAs.png +0 -0
  154. pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAs_32.png +0 -0
  155. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Save_24.png +0 -0
  156. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Save_32.png +0 -0
  157. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Search.png +0 -0
  158. pymodaq/resources/QtDesigner_Ressources/Icon_Library/SelectPolygon.png +0 -0
  159. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Select_24.png +0 -0
  160. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Settings.png +0 -0
  161. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snap&Save.png +0 -0
  162. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot.png +0 -0
  163. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot2.png +0 -0
  164. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot2_16.png +0 -0
  165. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot2_32.png +0 -0
  166. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Spreadsheet.png +0 -0
  167. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Statistics.png +0 -0
  168. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Statistics2.png +0 -0
  169. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Status.png +0 -0
  170. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Subtract.png +0 -0
  171. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Vision.png +0 -0
  172. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Volts.png +0 -0
  173. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Wait2.png +0 -0
  174. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_1_1.png +0 -0
  175. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_in.png +0 -0
  176. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_out.png +0 -0
  177. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_to_Selection.png +0 -0
  178. pymodaq/resources/QtDesigner_Ressources/Icon_Library/abort.png +0 -0
  179. pymodaq/resources/QtDesigner_Ressources/Icon_Library/advanced2.png +0 -0
  180. pymodaq/resources/QtDesigner_Ressources/Icon_Library/autoscale.png +0 -0
  181. pymodaq/resources/QtDesigner_Ressources/Icon_Library/b_icon.png +0 -0
  182. pymodaq/resources/QtDesigner_Ressources/Icon_Library/back.png +0 -0
  183. pymodaq/resources/QtDesigner_Ressources/Icon_Library/bg_icon.png +0 -0
  184. pymodaq/resources/QtDesigner_Ressources/Icon_Library/camera.png +0 -0
  185. pymodaq/resources/QtDesigner_Ressources/Icon_Library/camera_snap.png +0 -0
  186. pymodaq/resources/QtDesigner_Ressources/Icon_Library/cartesian.png +0 -0
  187. pymodaq/resources/QtDesigner_Ressources/Icon_Library/clear2.png +0 -0
  188. pymodaq/resources/QtDesigner_Ressources/Icon_Library/clear_ROI.png +0 -0
  189. pymodaq/resources/QtDesigner_Ressources/Icon_Library/close2.png +0 -0
  190. pymodaq/resources/QtDesigner_Ressources/Icon_Library/cluster2.png +0 -0
  191. pymodaq/resources/QtDesigner_Ressources/Icon_Library/color.png +0 -0
  192. pymodaq/resources/QtDesigner_Ressources/Icon_Library/color2.png +0 -0
  193. pymodaq/resources/QtDesigner_Ressources/Icon_Library/continuous.png +0 -0
  194. pymodaq/resources/QtDesigner_Ressources/Icon_Library/data.png +0 -0
  195. pymodaq/resources/QtDesigner_Ressources/Icon_Library/delay.png +0 -0
  196. pymodaq/resources/QtDesigner_Ressources/Icon_Library/download.png +0 -0
  197. pymodaq/resources/QtDesigner_Ressources/Icon_Library/download2.png +0 -0
  198. pymodaq/resources/QtDesigner_Ressources/Icon_Library/error2.png +0 -0
  199. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ethernet.png +0 -0
  200. pymodaq/resources/QtDesigner_Ressources/Icon_Library/exit2.png +0 -0
  201. pymodaq/resources/QtDesigner_Ressources/Icon_Library/fan.png +0 -0
  202. pymodaq/resources/QtDesigner_Ressources/Icon_Library/filter2.png +0 -0
  203. pymodaq/resources/QtDesigner_Ressources/Icon_Library/g_icon.png +0 -0
  204. pymodaq/resources/QtDesigner_Ressources/Icon_Library/gear2.png +0 -0
  205. pymodaq/resources/QtDesigner_Ressources/Icon_Library/go_to.png +0 -0
  206. pymodaq/resources/QtDesigner_Ressources/Icon_Library/go_to_1.png +0 -0
  207. pymodaq/resources/QtDesigner_Ressources/Icon_Library/go_to_2.png +0 -0
  208. pymodaq/resources/QtDesigner_Ressources/Icon_Library/grab.png +0 -0
  209. pymodaq/resources/QtDesigner_Ressources/Icon_Library/graph.png +0 -0
  210. pymodaq/resources/QtDesigner_Ressources/Icon_Library/greenLight2.png +0 -0
  211. pymodaq/resources/QtDesigner_Ressources/Icon_Library/greenLight2_32.png +0 -0
  212. pymodaq/resources/QtDesigner_Ressources/Icon_Library/green_light.png +0 -0
  213. pymodaq/resources/QtDesigner_Ressources/Icon_Library/grey_icon.png +0 -0
  214. pymodaq/resources/QtDesigner_Ressources/Icon_Library/greyscale.png +0 -0
  215. pymodaq/resources/QtDesigner_Ressources/Icon_Library/help1.png +0 -0
  216. pymodaq/resources/QtDesigner_Ressources/Icon_Library/help1_32.png +0 -0
  217. pymodaq/resources/QtDesigner_Ressources/Icon_Library/home2.png +0 -0
  218. pymodaq/resources/QtDesigner_Ressources/Icon_Library/information2.png +0 -0
  219. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ini.png +0 -0
  220. pymodaq/resources/QtDesigner_Ressources/Icon_Library/integrator.png +0 -0
  221. pymodaq/resources/QtDesigner_Ressources/Icon_Library/joystick.png +0 -0
  222. pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_green.png +0 -0
  223. pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_green_16.png +0 -0
  224. pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_red.png +0 -0
  225. pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_red_16.png +0 -0
  226. pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_yellow.png +0 -0
  227. pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_yellow_16.png +0 -0
  228. pymodaq/resources/QtDesigner_Ressources/Icon_Library/limiter.png +0 -0
  229. pymodaq/resources/QtDesigner_Ressources/Icon_Library/load_ROI.png +0 -0
  230. pymodaq/resources/QtDesigner_Ressources/Icon_Library/meshPlot.png +0 -0
  231. pymodaq/resources/QtDesigner_Ressources/Icon_Library/meter.png +0 -0
  232. pymodaq/resources/QtDesigner_Ressources/Icon_Library/meter2.png +0 -0
  233. pymodaq/resources/QtDesigner_Ressources/Icon_Library/meter_32.png +0 -0
  234. pymodaq/resources/QtDesigner_Ressources/Icon_Library/move_contour.png +0 -0
  235. pymodaq/resources/QtDesigner_Ressources/Icon_Library/move_straight_line.png +0 -0
  236. pymodaq/resources/QtDesigner_Ressources/Icon_Library/movie.png +0 -0
  237. pymodaq/resources/QtDesigner_Ressources/Icon_Library/multi_point.png +0 -0
  238. pymodaq/resources/QtDesigner_Ressources/Icon_Library/multiplexer.png +0 -0
  239. pymodaq/resources/QtDesigner_Ressources/Icon_Library/new.png +0 -0
  240. pymodaq/resources/QtDesigner_Ressources/Icon_Library/openArrow.png +0 -0
  241. pymodaq/resources/QtDesigner_Ressources/Icon_Library/openTree.png +0 -0
  242. pymodaq/resources/QtDesigner_Ressources/Icon_Library/oscilloscope2.png +0 -0
  243. pymodaq/resources/QtDesigner_Ressources/Icon_Library/oscilloscope3.png +0 -0
  244. pymodaq/resources/QtDesigner_Ressources/Icon_Library/overlay.png +0 -0
  245. pymodaq/resources/QtDesigner_Ressources/Icon_Library/pass2.png +0 -0
  246. pymodaq/resources/QtDesigner_Ressources/Icon_Library/pass2_16.png +0 -0
  247. pymodaq/resources/QtDesigner_Ressources/Icon_Library/pass_32.png +0 -0
  248. pymodaq/resources/QtDesigner_Ressources/Icon_Library/pause.png +0 -0
  249. pymodaq/resources/QtDesigner_Ressources/Icon_Library/permute.png +0 -0
  250. pymodaq/resources/QtDesigner_Ressources/Icon_Library/phase.png +0 -0
  251. pymodaq/resources/QtDesigner_Ressources/Icon_Library/play.png +0 -0
  252. pymodaq/resources/QtDesigner_Ressources/Icon_Library/polar.png +0 -0
  253. pymodaq/resources/QtDesigner_Ressources/Icon_Library/pole_zero.png +0 -0
  254. pymodaq/resources/QtDesigner_Ressources/Icon_Library/powerMeter.png +0 -0
  255. pymodaq/resources/QtDesigner_Ressources/Icon_Library/powerSwitch.png +0 -0
  256. pymodaq/resources/QtDesigner_Ressources/Icon_Library/powerSwitch_16.png +0 -0
  257. pymodaq/resources/QtDesigner_Ressources/Icon_Library/print2.png +0 -0
  258. pymodaq/resources/QtDesigner_Ressources/Icon_Library/print2_32.png +0 -0
  259. pymodaq/resources/QtDesigner_Ressources/Icon_Library/properties.png +0 -0
  260. pymodaq/resources/QtDesigner_Ressources/Icon_Library/r_icon.png +0 -0
  261. pymodaq/resources/QtDesigner_Ressources/Icon_Library/radiocontrolbutton.png +0 -0
  262. pymodaq/resources/QtDesigner_Ressources/Icon_Library/read2.png +0 -0
  263. pymodaq/resources/QtDesigner_Ressources/Icon_Library/red_light.png +0 -0
  264. pymodaq/resources/QtDesigner_Ressources/Icon_Library/remove.png +0 -0
  265. pymodaq/resources/QtDesigner_Ressources/Icon_Library/reset.png +0 -0
  266. pymodaq/resources/QtDesigner_Ressources/Icon_Library/rgb_icon.png +0 -0
  267. pymodaq/resources/QtDesigner_Ressources/Icon_Library/robot.png +0 -0
  268. pymodaq/resources/QtDesigner_Ressources/Icon_Library/rotation2.png +0 -0
  269. pymodaq/resources/QtDesigner_Ressources/Icon_Library/run2.png +0 -0
  270. pymodaq/resources/QtDesigner_Ressources/Icon_Library/run_all.png +0 -0
  271. pymodaq/resources/QtDesigner_Ressources/Icon_Library/saturation.png +0 -0
  272. pymodaq/resources/QtDesigner_Ressources/Icon_Library/saveTree.png +0 -0
  273. pymodaq/resources/QtDesigner_Ressources/Icon_Library/save_ROI.png +0 -0
  274. pymodaq/resources/QtDesigner_Ressources/Icon_Library/scale_horizontally.png +0 -0
  275. pymodaq/resources/QtDesigner_Ressources/Icon_Library/scale_vertically.png +0 -0
  276. pymodaq/resources/QtDesigner_Ressources/Icon_Library/search2.png +0 -0
  277. pymodaq/resources/QtDesigner_Ressources/Icon_Library/select2.png +0 -0
  278. pymodaq/resources/QtDesigner_Ressources/Icon_Library/select_all.png +0 -0
  279. pymodaq/resources/QtDesigner_Ressources/Icon_Library/select_all2.png +0 -0
  280. pymodaq/resources/QtDesigner_Ressources/Icon_Library/select_none.png +0 -0
  281. pymodaq/resources/QtDesigner_Ressources/Icon_Library/sequence.png +0 -0
  282. pymodaq/resources/QtDesigner_Ressources/Icon_Library/sequence2.png +0 -0
  283. pymodaq/resources/QtDesigner_Ressources/Icon_Library/snap.png +0 -0
  284. pymodaq/resources/QtDesigner_Ressources/Icon_Library/sort_ascend.png +0 -0
  285. pymodaq/resources/QtDesigner_Ressources/Icon_Library/spectrumAnalyzer.png +0 -0
  286. pymodaq/resources/QtDesigner_Ressources/Icon_Library/start.png +0 -0
  287. pymodaq/resources/QtDesigner_Ressources/Icon_Library/status_cancelled.png +0 -0
  288. pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop.png +0 -0
  289. pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop2.png +0 -0
  290. pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop3.png +0 -0
  291. pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop_all.png +0 -0
  292. pymodaq/resources/QtDesigner_Ressources/Icon_Library/sum.png +0 -0
  293. pymodaq/resources/QtDesigner_Ressources/Icon_Library/surfacePlot.png +0 -0
  294. pymodaq/resources/QtDesigner_Ressources/Icon_Library/tree.png +0 -0
  295. pymodaq/resources/QtDesigner_Ressources/Icon_Library/updateTree.png +0 -0
  296. pymodaq/resources/QtDesigner_Ressources/Icon_Library/utility2.png +0 -0
  297. pymodaq/resources/QtDesigner_Ressources/Icon_Library/utility_small.png +0 -0
  298. pymodaq/resources/QtDesigner_Ressources/Icon_Library/vector.png +0 -0
  299. pymodaq/resources/QtDesigner_Ressources/Icon_Library/verify.png +0 -0
  300. pymodaq/resources/QtDesigner_Ressources/Icon_Library/video.png +0 -0
  301. pymodaq/resources/QtDesigner_Ressources/Icon_Library/wait.png +0 -0
  302. pymodaq/resources/QtDesigner_Ressources/Icon_Library/waterfallPlot.png +0 -0
  303. pymodaq/resources/QtDesigner_Ressources/Icon_Library/watershed.png +0 -0
  304. pymodaq/resources/QtDesigner_Ressources/Icon_Library/yellow_light.png +0 -0
  305. pymodaq/resources/QtDesigner_Ressources/Icon_Library/zip_file.png +0 -0
  306. pymodaq/resources/QtDesigner_Ressources/Icon_Library/zoomAuto.png +0 -0
  307. pymodaq/resources/QtDesigner_Ressources/Icon_Library/zoomReset.png +0 -0
  308. pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.bat +0 -2
  309. pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.qrc +0 -234
  310. pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources_rc.py +0 -127150
  311. pymodaq/resources/QtDesigner_Ressources/icons.svg +0 -142
  312. pymodaq/resources/VERSION +0 -1
  313. pymodaq/resources/config_template.toml +0 -94
  314. pymodaq/resources/triangulation_data.npy +0 -0
  315. pymodaq/utils/abstract/__init__.py +0 -48
  316. pymodaq/utils/db/__init__.py +0 -0
  317. pymodaq/utils/db/db_logger/__init__.py +0 -0
  318. pymodaq/utils/enums.py +0 -76
  319. pymodaq/utils/factory.py +0 -82
  320. pymodaq/utils/gui_utils/custom_app.py +0 -133
  321. pymodaq/utils/gui_utils/dock.py +0 -107
  322. pymodaq/utils/gui_utils/file_io.py +0 -93
  323. pymodaq/utils/gui_utils/layout.py +0 -34
  324. pymodaq/utils/gui_utils/list_picker.py +0 -38
  325. pymodaq/utils/gui_utils/widgets/__init__.py +0 -5
  326. pymodaq/utils/gui_utils/widgets/label.py +0 -24
  327. pymodaq/utils/gui_utils/widgets/lcd.py +0 -111
  328. pymodaq/utils/gui_utils/widgets/push.py +0 -149
  329. pymodaq/utils/gui_utils/widgets/qled.py +0 -62
  330. pymodaq/utils/gui_utils/widgets/spinbox.py +0 -24
  331. pymodaq/utils/gui_utils/widgets/table.py +0 -263
  332. pymodaq/utils/gui_utils/widgets/tree_layout.py +0 -188
  333. pymodaq/utils/gui_utils/widgets/tree_toml.py +0 -102
  334. pymodaq/utils/h5modules/backends.py +0 -1022
  335. pymodaq/utils/h5modules/browsing.py +0 -625
  336. pymodaq/utils/h5modules/data_saving.py +0 -1105
  337. pymodaq/utils/h5modules/exporter.py +0 -119
  338. pymodaq/utils/h5modules/exporters/__init__.py +0 -0
  339. pymodaq/utils/h5modules/exporters/base.py +0 -111
  340. pymodaq/utils/h5modules/exporters/flimj.py +0 -63
  341. pymodaq/utils/h5modules/exporters/hyperspy.py +0 -143
  342. pymodaq/utils/h5modules/saving.py +0 -866
  343. pymodaq/utils/h5modules/utils.py +0 -115
  344. pymodaq/utils/managers/action_manager.py +0 -489
  345. pymodaq/utils/managers/parameter_manager.py +0 -282
  346. pymodaq/utils/managers/roi_manager.py +0 -726
  347. pymodaq/utils/messenger.py +0 -66
  348. pymodaq/utils/parameter/ioxml.py +0 -542
  349. pymodaq/utils/parameter/pymodaq_ptypes/__init__.py +0 -38
  350. pymodaq/utils/parameter/pymodaq_ptypes/bool.py +0 -31
  351. pymodaq/utils/parameter/pymodaq_ptypes/date.py +0 -126
  352. pymodaq/utils/parameter/pymodaq_ptypes/filedir.py +0 -143
  353. pymodaq/utils/parameter/pymodaq_ptypes/itemselect.py +0 -265
  354. pymodaq/utils/parameter/pymodaq_ptypes/led.py +0 -44
  355. pymodaq/utils/parameter/pymodaq_ptypes/list.py +0 -150
  356. pymodaq/utils/parameter/pymodaq_ptypes/numeric.py +0 -18
  357. pymodaq/utils/parameter/pymodaq_ptypes/pixmap.py +0 -175
  358. pymodaq/utils/parameter/pymodaq_ptypes/slide.py +0 -145
  359. pymodaq/utils/parameter/pymodaq_ptypes/table.py +0 -135
  360. pymodaq/utils/parameter/pymodaq_ptypes/tableview.py +0 -149
  361. pymodaq/utils/parameter/pymodaq_ptypes/text.py +0 -142
  362. pymodaq/utils/plotting/__init__.py +0 -0
  363. pymodaq/utils/plotting/data_viewers/__init__.py +0 -10
  364. pymodaq/utils/plotting/data_viewers/base.py +0 -286
  365. pymodaq/utils/plotting/data_viewers/viewer.py +0 -274
  366. pymodaq/utils/plotting/data_viewers/viewer0D.py +0 -298
  367. pymodaq/utils/plotting/data_viewers/viewer1D.py +0 -826
  368. pymodaq/utils/plotting/data_viewers/viewer1Dbasic.py +0 -231
  369. pymodaq/utils/plotting/data_viewers/viewer2D.py +0 -1118
  370. pymodaq/utils/plotting/data_viewers/viewer2D_basic.py +0 -146
  371. pymodaq/utils/plotting/data_viewers/viewerND.py +0 -800
  372. pymodaq/utils/plotting/gant_chart.py +0 -123
  373. pymodaq/utils/plotting/image_viewer.py +0 -97
  374. pymodaq/utils/plotting/items/__init__.py +0 -0
  375. pymodaq/utils/plotting/items/axis_scaled.py +0 -93
  376. pymodaq/utils/plotting/items/crosshair.py +0 -94
  377. pymodaq/utils/plotting/items/image.py +0 -388
  378. pymodaq/utils/plotting/navigator.py +0 -353
  379. pymodaq/utils/plotting/plotter/plotter.py +0 -94
  380. pymodaq/utils/plotting/plotter/plotters/__init__.py +0 -0
  381. pymodaq/utils/plotting/plotter/plotters/matplotlib_plotters.py +0 -134
  382. pymodaq/utils/plotting/plotter/plotters/qt_plotters.py +0 -78
  383. pymodaq/utils/plotting/utils/__init__.py +0 -0
  384. pymodaq/utils/plotting/utils/axes_viewer.py +0 -88
  385. pymodaq/utils/plotting/utils/filter.py +0 -585
  386. pymodaq/utils/plotting/utils/lineout.py +0 -226
  387. pymodaq/utils/plotting/utils/plot_utils.py +0 -579
  388. pymodaq/utils/plotting/utils/signalND.py +0 -1347
  389. pymodaq/utils/plotting/widgets.py +0 -76
  390. pymodaq/utils/qvariant.py +0 -12
  391. pymodaq/utils/slicing.py +0 -63
  392. pymodaq/utils/units.py +0 -216
  393. pymodaq-4.2.4.dist-info/RECORD +0 -438
  394. /pymodaq/{post_treatment/daq_analysis → extensions/daq_logger}/__init__.py +0 -0
  395. /pymodaq/{utils/abstract/logger.py → extensions/daq_logger/abstract.py} +0 -0
  396. /pymodaq/{resources/QtDesigner_Ressources → extensions/daq_logger/db}/__init__.py +0 -0
  397. {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/WHEEL +0 -0
  398. {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/entry_points.txt +0 -0
  399. {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,1118 +0,0 @@
1
- from collections import OrderedDict
2
- import copy
3
- import datetime
4
- import numpy as np
5
- import sys
6
- from typing import Union, Iterable, List, Dict
7
-
8
- import pymodaq.utils.messenger
9
- from qtpy import QtCore, QtGui, QtWidgets
10
- from qtpy.QtCore import QObject, Slot, Signal, Qt
11
- import pyqtgraph as pg
12
- from pyqtgraph.graphicsItems.GradientEditorItem import Gradients
13
- from pyqtgraph import ROI as pgROI
14
-
15
- from pymodaq.utils.data import (Axis, DataToExport, DataFromRoi, DataFromPlugins, DataRaw,
16
- DataDistribution, DataWithAxes)
17
- from pymodaq.utils.logger import set_logger, get_module_name
18
- from pymodaq.utils.managers.roi_manager import ROIManager, SimpleRectROI
19
- from pymodaq.utils.managers.action_manager import ActionManager
20
- from pymodaq.utils.plotting.widgets import ImageWidget
21
-
22
- from pymodaq.utils.plotting.data_viewers.viewer import ViewerBase
23
- from pymodaq.utils.plotting.data_viewers.viewer1D import Viewer1D
24
- from pymodaq.utils.plotting.data_viewers.viewer0D import Viewer0D
25
- from pymodaq.utils.plotting.items.image import UniformImageItem, SpreadImageItem
26
- from pymodaq.utils.plotting.items.axis_scaled import AXIS_POSITIONS, AxisItem_Scaled
27
- from pymodaq.utils.plotting.items.crosshair import Crosshair
28
- from pymodaq.utils.plotting.utils.filter import Filter2DFromCrosshair, Filter2DFromRois
29
- import pymodaq.utils.daq_utils as utils
30
- from pymodaq.utils.plotting.utils.plot_utils import make_dashed_pens, RoiInfo
31
-
32
-
33
- logger = set_logger(get_module_name(__file__))
34
-
35
- Gradients.update(OrderedDict([
36
- ('red', {'ticks': [(0.0, (0, 0, 0, 255)), (1.0, (255, 0, 0, 255))], 'mode': 'rgb'}),
37
- ('green', {'ticks': [(0.0, (0, 0, 0, 255)), (1.0, (0, 255, 0, 255))], 'mode': 'rgb'}),
38
- ('blue', {'ticks': [(0.0, (0, 0, 0, 255)), (1.0, (0, 0, 255, 255))], 'mode': 'rgb'}),
39
- ('spread', {'ticks': [(0.0, (0, 0, 0, 255)), (1.0, (255, 255, 255, 255))], 'mode': 'rgb'}),]))
40
-
41
- COLORS_DICT = dict(red=(255, 0, 0), green=(0, 255, 0), blue=(0, 0, 255), spread=(128, 128, 128))
42
-
43
-
44
-
45
- IMAGE_TYPES = ['red', 'green', 'blue']
46
- COLOR_LIST = utils.plot_colors
47
- crosshair_pens = make_dashed_pens(color=(255, 255, 0))
48
-
49
-
50
- def image_item_factory(item_type='uniform', axisOrder='row-major', pen='r'):
51
- if item_type == 'uniform':
52
- image = UniformImageItem(pen=pen)
53
- image.setOpts(axisOrder=axisOrder)
54
- elif item_type == 'spread':
55
- image = SpreadImageItem(pen=pen)
56
- image.setCompositionMode(QtGui.QPainter.CompositionMode_Plus)
57
- return image
58
-
59
-
60
- def histogram_factory(image_item=None, gradient='red'):
61
- """
62
- Create a pyqtgraph HistogramLUTWidget widget (histogram) and link it to the corresponding image_item
63
- Parameters
64
- ----------
65
- image_item: (ImageItem) the image item to be linked with the histogram
66
- gradient: (str) either 'red', 'green', 'blue', 'spread' or one of the Gradients
67
-
68
- Returns
69
- -------
70
- HistogramLUTWidget instance
71
- """
72
-
73
- if gradient not in Gradients:
74
- raise KeyError(f'Possible gradient are {Gradients} not {gradient}')
75
-
76
- histo = pg.HistogramLUTWidget()
77
- if image_item is not None:
78
- histo.setImageItem(image_item)
79
-
80
- histo.gradient.loadPreset(gradient)
81
- return histo
82
-
83
-
84
- class ImageDisplayer(QObject):
85
- """
86
- This Object deals with the display of 2D data with a plotitem
87
- """
88
-
89
- updated_item = Signal(dict)
90
-
91
- def __init__(self, plotitem, data_distribution: DataDistribution):
92
- super().__init__()
93
- self._plotitem = plotitem
94
- self._plotitem.addLegend()
95
- self.show_legend(False)
96
- self.display_type = data_distribution
97
- self._image_items = dict([])
98
- self._autolevels = False
99
- self._data: DataWithAxes = None
100
-
101
- self.update_display_items()
102
-
103
- def show_legend(self, show=True):
104
- self.legend.setVisible(show)
105
-
106
- @property
107
- def legend(self):
108
- return self._plotitem.legend
109
-
110
- def get_images(self):
111
- return self._image_items
112
-
113
- def get_image(self, name):
114
- if name not in self._image_items:
115
- raise KeyError(f'The image {name} is not defined in {self.__class__.__name__}')
116
- else:
117
- return self._image_items[name]
118
-
119
- @property
120
- def labels(self):
121
- if self._data is None:
122
- return []
123
- else:
124
- return self._data.labels
125
-
126
- @property
127
- def autolevels(self):
128
- return self._autolevels
129
-
130
- @Slot(bool)
131
- def set_autolevels(self, isautolevel):
132
- self._autolevels = isautolevel
133
-
134
- def update_data(self, dwa: DataWithAxes):
135
- if dwa.labels != self.labels:
136
- self.update_display_items(dwa.labels)
137
- if dwa.distribution != self.display_type:
138
- self.display_type = dwa.distribution
139
- self._data = dwa
140
- for ind_data, data_array in enumerate(dwa.data):
141
- if data_array.size > 0:
142
- if self.display_type == 'uniform':
143
- self._image_items[IMAGE_TYPES[ind_data]].setImage(data_array, self.autolevels)
144
- else:
145
- nav_axes = dwa.get_nav_axes()
146
- data_array = np.stack((nav_axes[0].get_data(),
147
- nav_axes[1].get_data(),
148
- data_array), axis=0).T
149
- self._image_items[IMAGE_TYPES[ind_data]].setImage(data_array, self.autolevels)
150
-
151
- def update_display_items(self, labels: List[str] = None):
152
- while len(self._image_items) > 0:
153
- self._plotitem.removeItem(self._image_items.pop(next(iter(self._image_items))))
154
- if labels is None:
155
- labels = []
156
- while len(labels) != len(IMAGE_TYPES):
157
- labels.append(IMAGE_TYPES[len(labels)])
158
-
159
- for ind, img_key in enumerate(IMAGE_TYPES):
160
- self._image_items[img_key] = image_item_factory(self.display_type, pen=img_key[0])
161
- self._plotitem.addItem(self._image_items[img_key])
162
- if ind < len(labels):
163
- self.legend.addItem(self._image_items[img_key], labels[ind])
164
- self.updated_item.emit(self._image_items)
165
-
166
- def update_image_visibility(self, are_items_visible):
167
- if len(are_items_visible) != len(self._image_items):
168
- raise ValueError(f'The length of the argument is not equal with the number of images')
169
- for ind, key in enumerate(IMAGE_TYPES):
170
- self._image_items[key].setVisible(are_items_visible[ind])
171
-
172
-
173
- class Histogrammer(QObject):
174
- gradient_changed = Signal()
175
-
176
- def __init__(self, histogram_container: QtWidgets.QWidget, histogram_refs=IMAGE_TYPES):
177
- super().__init__()
178
- self._histograms = dict([])
179
- self._histogram_refs = histogram_refs
180
- self._histogram_container = histogram_container
181
- self.setup_histograms()
182
- self._autolevels = False
183
-
184
- def setup_histograms(self):
185
- for histo_key in self._histogram_refs:
186
- self._histograms[histo_key] = histogram_factory(None, gradient=histo_key)
187
- self.add_histogram(self._histograms[histo_key])
188
- self._histograms[histo_key].setVisible(False)
189
- self._histograms[histo_key].item.sigLookupTableChanged.connect(lambda: self.gradient_changed.emit())
190
-
191
- def get_histograms(self):
192
- return self._histograms
193
-
194
- def get_histogram(self, name):
195
- if name not in self.get_histograms():
196
- raise KeyError(f'The histogram {name} is not defined in {self.__class__.__name__}')
197
- else:
198
- return self._histograms[name]
199
-
200
- @property
201
- def autolevels(self):
202
- return self._autolevels
203
-
204
- @Slot(bool)
205
- def set_autolevels(self, isautolevels=True):
206
- self._autolevels = isautolevels
207
- for histo in self._histograms.values():
208
- histo.region.setVisible(not isautolevels)
209
-
210
- @Slot(bool)
211
- def activated(self, histo_action_checked):
212
- if histo_action_checked:
213
- for histo in self._histograms.values():
214
- histo.regionChanged()
215
-
216
- def affect_histo_to_imageitems(self, image_items):
217
- # TODO: if self._histogram_refs doesn't contains the same refs as image_items, we have an issue...
218
- for img_key in self._histogram_refs:
219
- self._histograms[img_key].setImageItem(image_items[img_key])
220
-
221
- def add_histogram(self, histogram):
222
- if self._histogram_container.layout() is None:
223
- self._histogram_container.setLayout(QtWidgets.QHBoxLayout())
224
- self._histogram_container.layout().addWidget(histogram)
225
-
226
- def show_hide_histogram(self, checked, are_items_visible):
227
- for ind_histo, histo_name in enumerate(self._histogram_refs):
228
- self._histograms[histo_name].setVisible(are_items_visible[ind_histo] and checked)
229
-
230
- def set_gradient(self, histo='red', gradient='grey'):
231
- """
232
- Change the color gradient of the specified histogram
233
- Parameters
234
- ----------
235
- histo: (str) either 'red', 'green', 'blue', 'spread' or 'all'
236
- gradient: (str or Gradient)
237
- """
238
- if gradient in Gradients:
239
- if histo == 'all':
240
- for key in self._histogram_refs:
241
- self._histograms[key].item.gradient.loadPreset(gradient)
242
- else:
243
- self._histograms[histo].item.gradient.loadPreset(gradient)
244
-
245
-
246
- class IsoCurver(QObject):
247
- def __init__(self, image_source, histogram_parent):
248
- super().__init__()
249
- self._histogram_parent = histogram_parent
250
- self.setup_iso_curve()
251
- self.update_image_source(image_source)
252
- self.update_histogram_parent(histogram_parent)
253
- self.show_hide_iso(False)
254
-
255
- def setup_iso_curve(self, parent_image_item='red'):
256
- # # Isocurve drawing
257
- self._isocurve_item = pg.IsocurveItem(level=0.8, pen='g', axisOrder='row-major')
258
- self._isocurve_item.setZValue(5)
259
-
260
- # # Draggable line for setting isocurve level
261
- self._isoLine = pg.InfiniteLine(angle=0, movable=True, pen='g')
262
- self._isoLine.setValue(0.8)
263
- self._isoLine.setZValue(1000) # bring iso line above contrast controls
264
-
265
- self._isoLine.sigDragged.connect(self.update_isocurve)
266
-
267
- def update_image_source(self, image_source):
268
- self._isocurve_item.setParentItem(image_source)
269
-
270
- def update_histogram_parent(self, histogram):
271
- if histogram != self._histogram_parent:
272
- histogram.vb.removeItem(self._isoLine)
273
- self._histogram_parent = histogram
274
- histogram.vb.addItem(self._isoLine)
275
- histogram.vb.setMouseEnabled(y=False) # makes user interaction a little easier
276
-
277
- def update_isocurve(self):
278
- self._isocurve_item.setLevel(self._isoLine.value())
279
-
280
- def set_isocurve_data(self, data):
281
- self._isocurve_item.setData(data)
282
-
283
- @Slot(bool)
284
- def show_hide_iso(self, show=True):
285
- if show:
286
- self._isocurve_item.show()
287
- self._isoLine.show()
288
- else:
289
- self._isocurve_item.hide()
290
- self._isoLine.hide()
291
-
292
-
293
- class View2D(ActionManager, QtCore.QObject):
294
-
295
- lineout_types = ['hor', 'ver', 'int']
296
-
297
- def __init__(self, parent_widget=None):
298
- QtCore.QObject.__init__(self)
299
- ActionManager.__init__(self, toolbar=QtWidgets.QToolBar())
300
-
301
- self.ROIselect = SimpleRectROI([0, 0], [10, 10], centered=True, sideScalers=True)
302
-
303
- self._lineout_widgets = {widg_key: QtWidgets.QWidget() for widg_key in self.lineout_types}
304
- self.lineout_viewers: Dict[str, Viewer1D] = dict(hor=Viewer1D(self._lineout_widgets['hor'], show_toolbar=False, no_margins=True),
305
- ver=Viewer1D(self._lineout_widgets['ver'], show_toolbar=False, no_margins=True,
306
- flip_axes=True),
307
- int=Viewer0D(self._lineout_widgets['int'], show_toolbar=False, no_margins=True))
308
-
309
- self.setup_actions()
310
-
311
- self.parent_widget = parent_widget
312
- if self.parent_widget is None:
313
- self.parent_widget = QtWidgets.QWidget()
314
- self.parent_widget.show()
315
-
316
- self.image_widget = ImageWidget()
317
- self.roi_manager = ROIManager(self.image_widget, '2D')
318
-
319
- self.roi_target: Union[pgROI, Crosshair] = None
320
-
321
- self.setup_widgets()
322
-
323
- self.histogrammer = Histogrammer(self.widget_histo)
324
- self.data_displayer: ImageDisplayer = None
325
- self.isocurver: IsoCurver = None
326
-
327
- self.crosshair = Crosshair(self.image_widget)
328
-
329
- self.connect_things()
330
- self.prepare_ui()
331
-
332
- self.set_axis_label('bottom', label='', units='Pxls')
333
- self.set_axis_label('left', label='', units='Pxls')
334
-
335
- self.set_image_displayer(DataDistribution['uniform'])
336
-
337
- def clear_plot_item(self):
338
- for item in self.plotitem.items[:]:
339
- if isinstance(item, SpreadImageItem) or isinstance(item, UniformImageItem):
340
- self.plotitem.removeItem(item)
341
-
342
- def set_image_displayer(self, data_distribution: DataDistribution):
343
- self.clear_plot_item()
344
- self.data_displayer = ImageDisplayer(self.plotitem, data_distribution)
345
- self.isocurver = IsoCurver(self.data_displayer.get_image('red'), self.histogrammer.get_histogram('red'))
346
- self.connect_action('isocurve', self.isocurver.show_hide_iso)
347
- self.data_displayer.updated_item.connect(self.histogrammer.affect_histo_to_imageitems)
348
- self.connect_action('autolevels', self.data_displayer.set_autolevels)
349
- for key in IMAGE_TYPES:
350
- self.connect_action(key, self.notify_visibility_data_displayer)
351
-
352
- self.histogrammer.affect_histo_to_imageitems(self.data_displayer.get_images())
353
-
354
- if data_distribution.name == 'uniform':
355
- self.roi_target = pgROI(pos=(0, 0), size=(20, 20), movable=False, rotatable=False,
356
- resizable=False)
357
- self.plotitem.addItem(self.roi_target)
358
-
359
- elif data_distribution.name == 'spread':
360
- self.roi_target = Crosshair(self.image_widget, pen=(255, 255, 255))
361
- self.roi_target.setVisible(False)
362
-
363
- def show_roi_target(self, show=True):
364
- self.roi_target.setVisible(show)
365
-
366
- def move_scale_roi_target(self, pos=None, size=None):
367
- """
368
- Move and scale the target ROI (used to display a particular area,
369
- for instance the currently scanned points
370
- during a scan
371
- Parameters
372
- ----------
373
- pos: (iterable) setting the central position of the ROI in the view
374
- size: (iterable) setting the size of the ROI
375
- """
376
- if isinstance(self.roi_target, pgROI):
377
- if size is not None:
378
- x_offset, x_scaling, y_offset, y_scaling = self._get_axis_scaling_offset()
379
- size = list(np.divide(list(size), [x_scaling, y_scaling]))
380
- if list(self.roi_target.size()) != size:
381
- self.roi_target.setSize(size, center=(0.5, 0.5))
382
-
383
- if pos is not None:
384
- pos = self.unscale_axis(*list(pos))
385
- pos = list(pos)
386
- if list(self.roi_target.pos()) != pos:
387
- self.roi_target.setPos(pos)
388
-
389
- else:
390
- self.roi_target.set_crosshair_position(*list(pos))
391
-
392
- def setup_widgets(self):
393
- vertical_layout = QtWidgets.QVBoxLayout()
394
- vertical_layout.setContentsMargins(5, 5, 5, 5)
395
- self.parent_widget.setLayout(vertical_layout)
396
- splitter_vertical = QtWidgets.QSplitter(QtCore.Qt.Vertical)
397
- vertical_layout.addWidget(splitter_vertical)
398
- splitter_vertical.addWidget(self.toolbar)
399
-
400
- self.graphs_widget = QtWidgets.QWidget()
401
- self.graphs_widget.setLayout(QtWidgets.QHBoxLayout())
402
- self.graphs_widget.layout().setContentsMargins(0, 0, 0, 0)
403
- self.setup_graphs(self.graphs_widget.layout())
404
- splitter_vertical.addWidget(self.graphs_widget)
405
-
406
- self.plotitem.addItem(self.ROIselect)
407
-
408
- self.splitter_VLeft.splitterMoved[int, int].connect(self.move_right_splitter)
409
- self.splitter_VRight.splitterMoved[int, int].connect(self.move_left_splitter)
410
-
411
- self.splitter_VLeft.setSizes([1, 0])
412
- self.splitter_VRight.setSizes([1, 0])
413
-
414
- def setup_graphs(self, graphs_layout):
415
- self.splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
416
- graphs_layout.addWidget(self.splitter)
417
-
418
- self.widget_histo = QtWidgets.QWidget()
419
- graphs_layout.addWidget(self.widget_histo)
420
- self.widget_histo.setLayout(QtWidgets.QHBoxLayout())
421
-
422
- self.splitter_VLeft = QtWidgets.QSplitter(QtCore.Qt.Vertical)
423
- self.splitter_VRight = QtWidgets.QSplitter(QtCore.Qt.Vertical)
424
-
425
- self.splitter.addWidget(self.splitter_VLeft)
426
- self.splitter.addWidget(self.splitter_VRight)
427
-
428
- self.splitter_VLeft.addWidget(self.image_widget)
429
- self.splitter_VLeft.addWidget(self._lineout_widgets['hor'])
430
- self.splitter_VRight.addWidget(self._lineout_widgets['ver'])
431
- self.splitter_VRight.addWidget(self._lineout_widgets['int'])
432
-
433
- self.image_widget.add_scaled_axis('right')
434
- self.image_widget.add_scaled_axis('top')
435
- self.image_widget.add_scaled_axis('left')
436
- self.image_widget.add_scaled_axis('bottom')
437
- self.splitter.addWidget(self.roi_manager.roiwidget)
438
- self.roi_manager.roiwidget.setVisible(False)
439
-
440
- def setup_actions(self):
441
-
442
- self.add_action('position', '(,)')
443
- self.add_action('red', 'Red Channel', 'r_icon', tip='Show/Hide Red Channel', checkable=True)
444
- self.add_action('green', 'Green Channel', 'g_icon', tip='Show/Hide Green Channel', checkable=True)
445
- self.add_action('blue', 'Blue Channel', 'b_icon', tip='Show/Hide Blue Channel', checkable=True)
446
- self.get_action('red').setChecked(True)
447
- self.get_action('green').setChecked(True)
448
- self.get_action('blue').setChecked(True)
449
-
450
- self.add_action('autolevels', 'AutoLevels', 'autoscale',
451
- tip='Scale Histogram to Min/Max intensity', checkable=True)
452
- self.add_action('auto_levels_sym', 'AutoLevels Sym.', 'autoscale',
453
- tip='Make the autoscale of the histograms symetric with respect to 0', checkable=True)
454
-
455
- self.add_action('histo', 'Histogram', 'Histogram', tip='Show/Hide Histogram', checkable=True)
456
- self.add_action('roi', 'ROI', 'Region', tip='Show/Hide ROI Manager', checkable=True)
457
- self.add_action('isocurve', 'IsoCurve', 'meshPlot', tip='Show/Hide Isocurve', checkable=True)
458
- self.add_action('aspect_ratio', 'Aspect Ratio', 'Zoom_1_1', tip='Fix Aspect Ratio', checkable=True, checked=True)
459
- self.add_action('crosshair', 'CrossHair', 'reset', tip='Show/Hide data Crosshair', checkable=True)
460
- self.add_action('ROIselect', 'ROI Select', 'Select_24',
461
- tip='Show/Hide ROI selection area', checkable=True)
462
- self.add_action('flip_ud', 'Flip UD', 'scale_vertically',
463
- tip='Flip the image up/down', checkable=True)
464
- self.add_action('flip_lr', 'Flip LR', 'scale_horizontally',
465
- tip='Flip the image left/right', checkable=True)
466
- self.add_action('rotate', 'Rotate', 'rotation2',
467
- tip='Rotate the image', checkable=True)
468
- self.add_action('legend', 'Legend', 'RGB',
469
- tip='Show the legend', checkable=True)
470
-
471
- def update_colors(self, colors: list):
472
- for ind, roi_name in enumerate(self.roi_manager.ROIs):
473
- self.lineout_viewers['hor'].update_colors(make_dashed_pens(colors[ind]), displayer=roi_name)
474
- self.lineout_viewers['ver'].update_colors(make_dashed_pens(colors[ind]), displayer=roi_name)
475
- self.lineout_viewers['int'].update_colors(make_dashed_pens(colors[ind]), displayer=roi_name)
476
-
477
- def connect_things(self):
478
- self.connect_action('histo', self.histogrammer.activated)
479
- self.connect_action('autolevels', self.histogrammer.set_autolevels)
480
- self.roi_manager.new_ROI_signal.connect(self.update_roi_channels)
481
- self.roi_manager.new_ROI_signal.connect(self.add_roi_displayer)
482
- self.roi_manager.new_ROI_signal.connect(self.lineout_viewers['int'].get_action('clear').click)
483
- self.roi_manager.remove_ROI_signal.connect(self.remove_roi_displayer)
484
- self.roi_manager.color_signal.connect(self.update_colors)
485
- self.connect_action('isocurve', self.get_action('histo').trigger)
486
-
487
- self.connect_action('aspect_ratio', self.lock_aspect_ratio)
488
- self.connect_action('histo', self.show_hide_histogram)
489
- self.connect_action('roi', self.show_lineout_widgets)
490
- self.connect_action('roi', self.roi_clicked)
491
- self.connect_action('ROIselect', self.show_ROI_select)
492
- self.connect_action('crosshair', self.show_hide_crosshair)
493
- self.connect_action('crosshair', self.show_lineout_widgets)
494
- self.connect_action('legend', self.show_legend)
495
-
496
- def show_legend(self, show=True):
497
- self.data_displayer.show_legend(show)
498
-
499
- @Slot(int, str, str)
500
- def add_roi_displayer(self, index, roi_type='', roi_name=''):
501
- color = self.roi_manager.ROIs[roi_name].color
502
- self.lineout_viewers['hor'].view.add_data_displayer(roi_name, make_dashed_pens(color))
503
- self.lineout_viewers['ver'].view.add_data_displayer(roi_name, make_dashed_pens(color))
504
- self.lineout_viewers['int'].view.add_data_displayer(roi_name, make_dashed_pens(color))
505
-
506
- @Slot(str)
507
- def remove_roi_displayer(self, roi_name=''):
508
- self.lineout_viewers['hor'].view.remove_data_displayer(roi_name)
509
- self.lineout_viewers['ver'].view.remove_data_displayer(roi_name)
510
- self.lineout_viewers['int'].view.remove_data_displayer(roi_name)
511
-
512
- @Slot(int, str, str)
513
- def update_roi_channels(self, index, roi_type=''):
514
- """Update the use_channel setting each time a ROI is added"""
515
- self.roi_manager.update_use_channel(self.data_displayer.labels.copy())
516
-
517
- def prepare_ui(self):
518
- self.ROIselect.setVisible(False)
519
- self.show_hide_crosshair(False)
520
- self.show_lineout_widgets()
521
-
522
- @Slot(DataRaw)
523
- def display_images(self, datas):
524
- self.data_displayer.update_data(datas)
525
- if self.is_action_checked('isocurve'):
526
- self.isocurver.set_isocurve_data(datas.data[0])
527
-
528
- def display_roi_lineouts(self, roi_dte: DataToExport):
529
- if len(roi_dte) > 0:
530
- for lineout_type in self.lineout_types:
531
- for displayer_name in self.lineout_viewers[lineout_type].view.other_data_displayers:
532
- dwa = roi_dte.get_data_from_name_origin(lineout_type, displayer_name)
533
- if dwa is not None:
534
- self.lineout_viewers[lineout_type].view.display_data(dwa.deepcopy(),
535
- displayer=displayer_name)
536
-
537
- def display_crosshair_lineouts(self, crosshair_dte: DataToExport):
538
- for lineout_type in self.lineout_types:
539
- dwa = crosshair_dte.get_data_from_name(lineout_type)
540
- if dwa is not None:
541
- self.lineout_viewers[lineout_type].view.display_data(dwa, displayer='crosshair')
542
-
543
- def show_lineout_widgets(self):
544
- state = self.is_action_checked('roi') or self.is_action_checked('crosshair')
545
- if state:
546
- self.prepare_image_widget_for_lineouts()
547
- else:
548
- self.prepare_image_widget_for_lineouts(1)
549
-
550
- @Slot(bool)
551
- def roi_clicked(self, isroichecked=True):
552
- self.roi_manager.roiwidget.setVisible(isroichecked)
553
-
554
- for k, roi in self.roi_manager.ROIs.items():
555
- roi.setVisible(isroichecked)
556
-
557
- def get_visible_images(self):
558
- are_items_visible = []
559
- for key in IMAGE_TYPES:
560
- are_items_visible.append(self.is_action_visible(key) and self.is_action_checked(key))
561
- return are_items_visible
562
-
563
- def notify_visibility_data_displayer(self):
564
- are_items_visible = self.get_visible_images()
565
- self.data_displayer.update_image_visibility(are_items_visible)
566
-
567
- @Slot(bool)
568
- def show_hide_histogram(self, show=True):
569
- are_items_visible = self.get_visible_images()
570
- self.histogrammer.show_hide_histogram(show, are_items_visible)
571
-
572
- def prepare_image_widget_for_lineouts(self, ratio=0.7):
573
- QtGui.QGuiApplication.processEvents()
574
- self.splitter_VRight.splitterMoved[int, int].emit(int(ratio * self.parent_widget.height()), 1)
575
- self.splitter.moveSplitter(int(ratio * self.parent_widget.width()), 1)
576
- self.splitter_VLeft.moveSplitter(int(ratio * self.parent_widget.height()), 1)
577
- self.splitter_VLeft.splitterMoved[int, int].emit(int(ratio * self.parent_widget.height()), 1)
578
- QtGui.QGuiApplication.processEvents()
579
-
580
- def collapse_lineout_widgets(self):
581
- self.prepare_image_widget_for_lineouts(ratio=1)
582
-
583
- def get_view_range(self):
584
- return self.image_widget.view.viewRange()
585
-
586
- def get_data_at(self, name='red', xy=(0, 0)):
587
- return self.data_displayer.get_image(name).get_val_at(xy)
588
-
589
- def lock_aspect_ratio(self):
590
- lock = self.is_action_checked('aspect_ratio')
591
- self.plotitem.vb.setAspectLocked(lock=lock, ratio=1)
592
-
593
- @Slot(int, int)
594
- def move_left_splitter(self, pos, index):
595
- self.splitter_VLeft.blockSignals(True)
596
- self.splitter_VLeft.moveSplitter(pos, index)
597
- self.splitter_VLeft.blockSignals(False)
598
-
599
- @Slot(int, int)
600
- def move_right_splitter(self, pos, index):
601
- self.splitter_VRight.blockSignals(True)
602
- self.splitter_VRight.moveSplitter(pos, index)
603
- self.splitter_VRight.blockSignals(False)
604
-
605
- def get_double_clicked(self):
606
- return self.image_widget.view.sig_double_clicked
607
-
608
- def get_axis(self, position='left') -> AxisItem_Scaled:
609
- if position not in AXIS_POSITIONS:
610
- raise KeyError(f'{position} is not a possible position for Axis: {AXIS_POSITIONS}')
611
- return self.image_widget.getAxis(position)
612
-
613
- @property
614
- def plotitem(self):
615
- return self.image_widget.plotitem
616
-
617
- def get_crosshair_signal(self):
618
- """Convenience function from the Crosshair"""
619
- return self.crosshair.crosshair_dragged
620
-
621
- def get_crosshair_position(self):
622
- """Convenience function from the Crosshair"""
623
- return self.crosshair.get_positions()
624
-
625
- def set_crosshair_position(self, *positions):
626
- """Convenience function from the Crosshair"""
627
- self.crosshair.set_crosshair_position(*positions)
628
-
629
- @Slot(bool)
630
- def show_hide_crosshair(self, show=True):
631
- self.crosshair.setVisible(show)
632
- self.set_action_visible('position', show)
633
- self.crosshair.setVisible(show)
634
- if show:
635
- self.lineout_viewers['hor'].view.add_data_displayer('crosshair', plot_colors=crosshair_pens)
636
- self.lineout_viewers['ver'].view.add_data_displayer('crosshair', plot_colors=crosshair_pens)
637
- self.lineout_viewers['int'].view.add_data_displayer('crosshair', plot_colors=crosshair_pens)
638
- range = self.get_view_range()
639
- self.set_crosshair_position(np.mean(np.array(range[0])), np.mean(np.array(range[0])))
640
- else:
641
- self.lineout_viewers['hor'].view.remove_data_displayer('crosshair')
642
- self.lineout_viewers['ver'].view.remove_data_displayer('crosshair')
643
- self.lineout_viewers['int'].view.remove_data_displayer('crosshair')
644
- logger.debug(f'Crosshair visible?: {self.crosshair.isVisible()}')
645
-
646
- def show_ROI_select(self):
647
- self.ROIselect.setVisible(self.is_action_checked('ROIselect'))
648
- rect = self.data_displayer.get_image('red').boundingRect()
649
- self.ROIselect.setPos(rect.center()-QtCore.QPointF(rect.width() * 2 / 3, rect.height() * 2 / 3)/2)
650
- self.ROIselect.setSize(rect.size() * 2 / 3)
651
-
652
- def set_image_labels(self, labels: List[str]):
653
- if self.data_displayer.labels != labels:
654
- action_names =['red', 'green', 'blue']
655
- for action_name, label in zip(action_names[:len(labels)], labels):
656
- self.get_action(action_name).setToolTip('Show/Hide'
657
- f' - '
658
- f'{label}')
659
-
660
- def set_axis_label(self, position, label='', units=''):
661
- """
662
- Convenience method to set label and unit of any view axes
663
- Parameters
664
- ----------
665
- position: (str) any of AXIS_POSITIONS
666
- label: (str) text of the axis label
667
- units: (str) units of the axis label
668
- """
669
- axis = self.get_axis(position)
670
- axis.setLabel(text=label, units=units)
671
-
672
- def get_axis_label(self, position):
673
- axis = self.get_axis(position)
674
- return axis.axis_label, axis.axis_units
675
-
676
- def set_axis_scaling(self, position='top', scaling=1, offset=0, label='', units='Pxls'):
677
- """
678
- Method used to update the scaling of the right and top axes in order to translate pixels to real coordinates
679
- Parameters
680
- ----------
681
- position: (str) axis position either one of AXIS_POSITIONS
682
- scaling: (float) scaling of the axis
683
- offset: (float) offset of the axis
684
- label: (str) text of the axis label
685
- units: (str) units of the axis label
686
- """
687
- if scaling is None:
688
- scaling = 1
689
- if offset is None:
690
- offset = 0
691
- self.get_axis(position).axis_scaling = scaling
692
- self.get_axis(position).axis_offset = offset
693
- self.set_axis_label(position, label=label, units=units)
694
-
695
- def scale_axis(self, xaxis, yaxis):
696
- """scale view coordinates from the regular axes to the scaled/offset ones"""
697
- x_offset, x_scaling, y_offset, y_scaling = self._get_axis_scaling_offset()
698
- return xaxis * x_scaling + x_offset, yaxis * y_scaling + y_offset
699
-
700
- def unscale_axis(self, xaxis, yaxis):
701
- """scale view coordinates from the scaled/offset axes to the regular ones"""
702
- x_offset, x_scaling, y_offset, y_scaling = self._get_axis_scaling_offset()
703
- return (xaxis - x_offset) / x_scaling, (yaxis - y_offset) / y_scaling
704
-
705
- def _get_axis_scaling_offset(self):
706
- x_offset = self.get_axis('top').axis_offset
707
- x_scaling = self.get_axis('top').axis_scaling
708
- y_offset = self.get_axis('right').axis_offset
709
- y_scaling = self.get_axis('right').axis_scaling
710
- return x_offset, x_scaling, y_offset, y_scaling
711
-
712
-
713
- class Viewer2D(ViewerBase):
714
- """Object managing plotting and manipulation of 2D data using a View2D"""
715
-
716
- def __init__(self, parent: QtWidgets.QWidget = None, title=''):
717
- super().__init__(parent, title)
718
-
719
- self.just_init = True
720
-
721
- self._datas = None
722
- self.isdata = dict([])
723
- self._is_gradient_manually_set = False
724
-
725
- self.view = View2D(parent)
726
- self.filter_from_rois = Filter2DFromRois(self.view.roi_manager, self.view.data_displayer.get_image('red'),
727
- IMAGE_TYPES)
728
- self.filter_from_rois.register_activation_signal(self.view.get_action('roi').triggered)
729
- self.filter_from_rois.register_target_slot(self.process_roi_lineouts)
730
-
731
- self.filter_from_crosshair = Filter2DFromCrosshair(self.view.crosshair, self.view.data_displayer.get_images(),
732
- IMAGE_TYPES)
733
- self.filter_from_crosshair.register_activation_signal(self.view.get_action('crosshair').triggered)
734
- self.filter_from_crosshair.register_target_slot(self.process_crosshair_lineouts)
735
-
736
- self.prepare_connect_ui()
737
-
738
- @property
739
- def roi_manager(self):
740
- """Convenience method """
741
- return self.view.roi_manager
742
-
743
- @property
744
- def roi_target(self) -> pgROI:
745
- return self.view.roi_target
746
-
747
- def move_roi_target(self, pos: Iterable[float] = None, size: Iterable[float] = (1, 1)):
748
- """move a specific read only ROI at the given position on the viewer"""
749
- self.view.move_scale_roi_target(pos, size)
750
-
751
- @property
752
- def crosshair(self):
753
- """Convenience method """
754
- return self.view.crosshair
755
-
756
- @property
757
- def image_widget(self):
758
- """Convenience method """
759
- return self.view.image_widget
760
-
761
- def get_data_at(self):
762
- """Convenience method """
763
- return self.view.get_data_at()
764
-
765
- def set_crosshair_position(self, xpos, ypos):
766
- """Convenience method to set the crosshair positions"""
767
- self.view.crosshair.set_crosshair_position(xpos=xpos, ypos=ypos)
768
-
769
- def activate_roi(self, activate=True):
770
- """Activate the Roi manager using the corresponding action"""
771
- self.view.set_action_checked('roi', activate)
772
- self.view.get_action('roi').triggered.emit(activate)
773
-
774
- def roi_changed(self, *args, **kwargs):
775
- self.filter_from_rois.filter_data(self._datas)
776
-
777
- def crosshair_changed(self):
778
- self.filter_from_crosshair.filter_data(self._datas)
779
-
780
- def set_gradient(self, image_key, gradient):
781
- """convenience function"""
782
- self.view.histogrammer.set_gradient(image_key, gradient)
783
-
784
- def _show_data(self, data: DataFromPlugins):
785
- """Data to be plotted and eventually filtered using ROI...
786
-
787
- Parameters
788
- ----------
789
- data: DataFromPlugins
790
-
791
- """
792
-
793
- if len(data) == 1 and not self._is_gradient_manually_set:
794
- self.set_gradient('red', 'grey')
795
- if len(data) > 3:
796
- logger.warning('Cannot plot on 2D plot more than 3 channels')
797
- data.data = data.data[:3]
798
- self.view.set_image_labels(data.labels)
799
- if data.distribution != self.view.data_displayer.display_type:
800
- self.view.set_image_displayer(data.distribution)
801
- self.filter_from_crosshair.set_graph_items(self.view.data_displayer.get_images())
802
-
803
- self.get_axes_from_view(data) # in case axes were not specified into data, one try to get them from the view
804
-
805
- self.isdata['red'] = len(data) > 0
806
- self.isdata['green'] = len(data) > 1
807
- self.isdata['blue'] = len(data) > 2
808
-
809
- self.update_data()
810
-
811
- self.set_visible_items()
812
- if not self.view.is_action_checked('roi'):
813
- self.data_to_export_signal.emit(self.data_to_export)
814
-
815
- self.autolevels_first()
816
-
817
- def autolevels_first(self):
818
- if self.just_init and not self.is_action_checked('autolevels'):
819
- self.get_action('autolevels').trigger()
820
- self.update_data()
821
- self.get_action('autolevels').trigger()
822
- self.just_init = False
823
-
824
- def get_axes_from_view(self, data: DataWithAxes):
825
- """Obtain axes info from the view
826
-
827
- Only for uniform data
828
- """
829
- if data.distribution == DataDistribution['uniform']:
830
- if data.get_axis_from_index(0)[0] is None:
831
- axis_view = self.view.get_axis('right')
832
- axis = Axis(axis_view.axis_label, units=axis_view.axis_units,
833
- scaling=axis_view.axis_scaling, offset=axis_view.axis_offset, index=0)
834
- axis.create_linear_data(data.shape[0])
835
- data.axes.append(axis)
836
- if data.get_axis_from_index(1)[0] is None:
837
- axis_view = self.view.get_axis('top')
838
- axis = Axis(axis_view.axis_label, units=axis_view.axis_units,
839
- scaling=axis_view.axis_scaling, offset=axis_view.axis_offset, index=1)
840
- axis.create_linear_data(data.shape[1])
841
- data.axes.append(axis)
842
-
843
- def update_data(self):
844
- if self._raw_data is not None:
845
- self._datas = self.set_image_transform()
846
- if self._datas.distribution.name == 'uniform':
847
- self.x_axis = self._datas.get_axis_from_index(1)[0]
848
- self.y_axis = self._datas.get_axis_from_index(0)[0]
849
- else:
850
- self.x_axis = self._datas.get_axis_from_index(0)[0]
851
- self.y_axis = self._datas.get_axis_from_index(0)[1]
852
- self.view.display_images(self._datas)
853
-
854
- if self.view.is_action_checked('roi'):
855
- self.roi_changed()
856
-
857
- if self.view.is_action_checked('crosshair'):
858
- self.crosshair_changed()
859
-
860
- def set_image_transform(self) -> DataRaw:
861
- """
862
- Deactivate some tool buttons if data type is "spread" then apply transform_image
863
- """
864
- data = copy.deepcopy(self._raw_data)
865
- self.view.set_action_visible('flip_ud', data.distribution != 'spread')
866
- self.view.set_action_visible('flip_lr', data.distribution != 'spread')
867
- self.view.set_action_visible('rotate', data.distribution != 'spread')
868
- if data.distribution != 'spread':
869
- for ind_data in range(len(data)):
870
- data.data[ind_data] = self.transform_image(data.data[ind_data])
871
- return data
872
-
873
- def transform_image(self, data):
874
- if self.view.is_action_checked('flip_ud'):
875
- data = np.flipud(data)
876
- if self.view.is_action_checked('flip_lr'):
877
- data = np.fliplr(data)
878
- if self.view.is_action_checked('rotate'):
879
- data = np.flipud(np.transpose(data))
880
- return data
881
-
882
- def set_visible_items(self):
883
- for key in IMAGE_TYPES:
884
- self.view.set_action_visible(key, self.isdata[key])
885
-
886
- self.view.notify_visibility_data_displayer()
887
-
888
- def show_roi(self, show=True, show_roi_widget=True):
889
- """convenience function to control roi"""
890
- if show == (not self.view.is_action_checked('roi')):
891
- self.view.get_action('roi').trigger()
892
-
893
- self.view.roi_manager.roiwidget.setVisible(show_roi_widget)
894
-
895
- def update_crosshair_data(self, crosshair_dte: DataToExport):
896
- try:
897
- posx, posy = self.view.get_crosshair_position()
898
- (posx_scaled, posy_scaled) = self.view.scale_axis(posx, posy)
899
-
900
- dat = f'({posx_scaled:.1e}{posy_scaled:.1e})\n'
901
- dwa_int = crosshair_dte.get_data_from_name('int')
902
- if dwa_int is not None:
903
- for ind_data in range(len(dwa_int)):
904
- dat += f' {dwa_int.labels[ind_data]}:{float(dwa_int[ind_data][0]):.1e}\n'
905
-
906
- self.view.set_action_text('position', dat)
907
-
908
- except Exception as e:
909
- logger.warning(str(e))
910
-
911
- def prepare_connect_ui(self):
912
- self.view.ROIselect.sigRegionChangeFinished.connect(self.selected_region_changed)
913
-
914
- self.roi_manager.roi_changed.connect(self.roi_changed)
915
- self.roi_manager.roi_value_changed.connect(self.roi_changed)
916
-
917
- self.view.connect_action('flip_ud', slot=self.update_data)
918
- self.view.connect_action('flip_lr', slot=self.update_data)
919
- self.view.connect_action('rotate', slot=self.update_data)
920
- self.view.connect_action('autolevels', slot=self.update_data)
921
- self.view.connect_action('isocurve', slot=self.update_data)
922
- self.view.histogrammer.gradient_changed.connect(lambda: setattr(self, '_is_gradient_manually_set', True))
923
-
924
- # todo : self.view.lineout_plotter.roi_changed.connect(self.roi_changed)
925
- self.view.get_crosshair_signal().connect(self.crosshair_changed)
926
-
927
- self.view.get_double_clicked().connect(self.double_clicked)
928
-
929
- def selected_region_changed(self):
930
- if self.view.is_action_checked('ROIselect'):
931
- pos = self.view.ROIselect.pos()
932
- size = self.view.ROIselect.size()
933
- # self.ROI_select_signal.emit(QtCore.QRectF(pos[0], pos[1], size[0], size[1]))
934
- self.roi_select_signal.emit(RoiInfo.info_from_rect_roi(self.view.ROIselect))
935
-
936
- @Slot(float, float)
937
- def double_clicked(self, posx, posy):
938
- if self.view.is_action_checked('crosshair'):
939
- self.view.crosshair.set_crosshair_position(posx, posy)
940
- self.crosshair_changed()
941
- #scale positions of double_click with respect to real axes
942
- posx, posy = self.view.scale_axis(posx, posy)
943
- self.sig_double_clicked.emit(posx, posy)
944
-
945
-
946
- @property
947
- def x_axis(self):
948
- return self.view.get_axis('top')
949
-
950
- @x_axis.setter
951
- def x_axis(self, axis: Axis = None):
952
- if axis is not None:
953
- self.view.set_axis_scaling('top', scaling=axis.scaling, offset=axis.offset,
954
- label=axis.label, units=axis.units)
955
-
956
- @property
957
- def y_axis(self):
958
- return self.view.get_axis('right')
959
-
960
- @y_axis.setter
961
- def y_axis(self, axis: Axis = None):
962
- if axis is not None:
963
- self.view.set_axis_scaling('right', scaling=axis.scaling, offset=axis.offset,
964
- label=axis.label, units=axis.units)
965
-
966
- @Slot(DataToExport)
967
- def process_crosshair_lineouts(self, dte):
968
- self.view.display_crosshair_lineouts(dte)
969
- self.update_crosshair_data(dte)
970
- self.crosshair_dragged.emit(*self.view.scale_axis(*self.view.crosshair.get_positions()))
971
-
972
- def process_roi_lineouts(self, roi_dte: DataToExport):
973
- if len(roi_dte) > 0:
974
- self.view.display_roi_lineouts(roi_dte)
975
- roi_dte_bis = roi_dte.deepcopy()
976
- for dwa in roi_dte_bis.data:
977
- if dwa.name == 'hor':
978
- dwa.name = f'Hlineout_{dwa.origin}'
979
- elif dwa.name == 'ver':
980
- dwa.name = f'Vlineout_{dwa.origin}'
981
- elif dwa.name == 'int':
982
- dwa.name = f'Integrated_{dwa.origin}'
983
- self.data_to_export.append(roi_dte_bis)
984
-
985
- self.measure_data_dict = dict([])
986
-
987
- for roi_name in roi_dte_bis.get_origins():
988
- dwa = roi_dte_bis.get_data_from_name_origin(f'Integrated_{roi_name}', roi_name)
989
- for ind, data_array in enumerate(dwa.data):
990
- self.measure_data_dict[f'{dwa.labels[ind]}:'] = float(data_array[0])
991
-
992
- QtWidgets.QApplication.processEvents()
993
-
994
- self.view.roi_manager.settings.child('measurements').setValue(self.measure_data_dict)
995
- if not self._display_temporary:
996
- self.data_to_export_signal.emit(self.data_to_export)
997
- self.ROI_changed.emit()
998
-
999
-
1000
- def main_spread():
1001
- app = QtWidgets.QApplication(sys.argv)
1002
- widget = QtWidgets.QWidget()
1003
- prog = Viewer2D(widget)
1004
- widget.show()
1005
-
1006
- def print_data(data: DataToExport):
1007
- print(data)
1008
- print('******')
1009
- print(data.get_data_from_dim('Data1D'))
1010
-
1011
-
1012
- prog.data_to_export_signal.connect(print_data)
1013
-
1014
- data_spread = np.load('../../../resources/triangulation_data.npy')
1015
- # data_shuffled = data
1016
- # np.random.shuffle(data_shuffled)
1017
- # prog.show_data(utils.DataFromPlugins(name='mydata', distribution='spread',
1018
- # data=[data, data_shuffled]))
1019
-
1020
- prog.view.get_action('histo').trigger()
1021
- prog.view.get_action('autolevels').trigger()
1022
-
1023
- prog.show_data(DataFromPlugins(name='mydata', distribution='spread', data=[data_spread],
1024
- axes=[]))
1025
-
1026
- sys.exit(app.exec_())
1027
-
1028
-
1029
- def main(data_distribution='uniform'):
1030
- """either 'uniform' or 'spread'"""
1031
-
1032
- app = QtWidgets.QApplication(sys.argv)
1033
- widget = QtWidgets.QWidget()
1034
-
1035
- widget_button = QtWidgets.QWidget()
1036
- widget_button.setLayout(QtWidgets.QHBoxLayout())
1037
- button = QtWidgets.QPushButton('New Data')
1038
- ndata = QtWidgets.QSpinBox()
1039
- widget_button.layout().addWidget(button)
1040
- widget_button.layout().addWidget(ndata)
1041
-
1042
- def print_data(data: DataToExport):
1043
- print(data)
1044
- print('******')
1045
- print(data.get_data_from_dim('Data1D'))
1046
-
1047
- if data_distribution == 'uniform':
1048
- data_to_plot = generate_uniform_data()
1049
-
1050
- elif data_distribution == 'spread':
1051
- data_spread = np.load('../../../resources/triangulation_data.npy')
1052
- data_to_plot = DataFromPlugins(name='mydata', distribution='spread', data=[data_spread[:,2]],
1053
- nav_indexes=(0,),
1054
- axes=[Axis('xaxis', units='xpxl', data=data_spread[:,0], index=0, spread_order=0),
1055
- Axis('yaxis', units='ypxl', data=data_spread[:,1], index=0, spread_order=1),])
1056
-
1057
- prog = Viewer2D(widget)
1058
- widget.show()
1059
- prog.data_to_export_signal.connect(print_data)
1060
-
1061
- prog.view.get_action('histo').trigger()
1062
- prog.view.get_action('autolevels').trigger()
1063
-
1064
- prog.show_data(data_to_plot)
1065
-
1066
- prog.view.show_roi_target(True)
1067
- prog.view.move_scale_roi_target((50, 40), (10, 20))
1068
-
1069
- button.clicked.connect(lambda: plot_data(prog, ndata.value()))
1070
- widget_button.show()
1071
- QtWidgets.QApplication.processEvents()
1072
- sys.exit(app.exec_())
1073
-
1074
-
1075
- def generate_uniform_data() -> DataFromPlugins:
1076
- from pymodaq.utils.math_utils import gauss2D
1077
- Nx = 100
1078
- Ny = 2 * Nx
1079
- data_random = np.random.normal(size=(Ny, Nx))
1080
- x = 0.5 * np.linspace(-Nx / 2, Nx / 2 - 1, Nx)
1081
- y = 0.2 * np.linspace(-Ny / 2, Ny / 2 - 1, Ny)
1082
- data_red = 3 * np.sin(x / 5) ** 2 * gauss2D(x, 5, Nx / 10, y, -1, Ny / 10, 1, 90) + 0.2 * data_random
1083
- data_green = 10 * gauss2D(x, -20, Nx / 10, y, -10, Ny / 20, 1, 0)
1084
- data_green[70:80, 7:12] = np.nan
1085
-
1086
- data_to_plot = DataFromPlugins(name='mydata', distribution='uniform',
1087
- data=[data_red, data_green, data_red-data_green],
1088
- labels = ['myreddata', 'mygreendata'],
1089
- axes=[Axis('xaxis', units='xpxl', data=x, index=1),
1090
- Axis('yaxis', units='ypxl', data=y, index=0), ])
1091
- return data_to_plot
1092
-
1093
-
1094
- def plot_data(viewer2D: Viewer2D, ndata: int = 2):
1095
- if ndata > 0:
1096
- dwa = generate_uniform_data()
1097
- dwa.data = dwa.data[0:ndata]
1098
- viewer2D.show_data(dwa)
1099
-
1100
-
1101
- def print_roi_select(rect):
1102
- print(rect)
1103
-
1104
-
1105
- def main_view():
1106
- app = QtWidgets.QApplication(sys.argv)
1107
-
1108
- form = QtWidgets.QWidget()
1109
- prog = View2D(form)
1110
- form.show()
1111
- sys.exit(app.exec_())
1112
-
1113
-
1114
- if __name__ == '__main__': # pragma: no cover
1115
-
1116
- #main_view()
1117
- main('uniform')
1118
- #main('spread')