datalab-platform 0.0.1.dev0__py3-none-any.whl → 1.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.
Files changed (496) hide show
  1. datalab/__init__.py +35 -2
  2. datalab/adapters_metadata/__init__.py +31 -0
  3. datalab/adapters_metadata/base_adapter.py +316 -0
  4. datalab/adapters_metadata/common.py +422 -0
  5. datalab/adapters_metadata/geometry_adapter.py +98 -0
  6. datalab/adapters_metadata/table_adapter.py +84 -0
  7. datalab/adapters_plotpy/__init__.py +54 -0
  8. datalab/adapters_plotpy/annotations.py +124 -0
  9. datalab/adapters_plotpy/base.py +110 -0
  10. datalab/adapters_plotpy/converters.py +86 -0
  11. datalab/adapters_plotpy/factories.py +80 -0
  12. datalab/adapters_plotpy/objects/__init__.py +0 -0
  13. datalab/adapters_plotpy/objects/base.py +197 -0
  14. datalab/adapters_plotpy/objects/image.py +157 -0
  15. datalab/adapters_plotpy/objects/scalar.py +565 -0
  16. datalab/adapters_plotpy/objects/signal.py +264 -0
  17. datalab/adapters_plotpy/roi/__init__.py +0 -0
  18. datalab/adapters_plotpy/roi/base.py +146 -0
  19. datalab/adapters_plotpy/roi/factory.py +93 -0
  20. datalab/adapters_plotpy/roi/image.py +207 -0
  21. datalab/adapters_plotpy/roi/signal.py +72 -0
  22. datalab/app.py +98 -0
  23. datalab/config.py +817 -0
  24. datalab/control/__init__.py +0 -0
  25. datalab/control/baseproxy.py +776 -0
  26. datalab/control/proxy.py +343 -0
  27. datalab/control/remote.py +1005 -0
  28. datalab/data/doc/DataLab_en.pdf +0 -0
  29. datalab/data/doc/DataLab_fr.pdf +0 -0
  30. datalab/data/icons/analysis/delete_results.svg +109 -0
  31. datalab/data/icons/analysis/fw1e2.svg +156 -0
  32. datalab/data/icons/analysis/fwhm.svg +156 -0
  33. datalab/data/icons/analysis/histogram.svg +49 -0
  34. datalab/data/icons/analysis/peak_detect.svg +160 -0
  35. datalab/data/icons/analysis/plot_results.svg +151 -0
  36. datalab/data/icons/analysis/show_results.svg +83 -0
  37. datalab/data/icons/analysis/stats.svg +49 -0
  38. datalab/data/icons/analysis.svg +120 -0
  39. datalab/data/icons/apply.svg +3 -0
  40. datalab/data/icons/check_all.svg +15 -0
  41. datalab/data/icons/collapse.svg +44 -0
  42. datalab/data/icons/collapse_selection.svg +63 -0
  43. datalab/data/icons/console.svg +101 -0
  44. datalab/data/icons/create/1d-normal.svg +8 -0
  45. datalab/data/icons/create/1d-poisson.svg +9 -0
  46. datalab/data/icons/create/1d-uniform.svg +8 -0
  47. datalab/data/icons/create/1d-zero.svg +57 -0
  48. datalab/data/icons/create/2d-gaussian.svg +56 -0
  49. datalab/data/icons/create/2d-normal.svg +38 -0
  50. datalab/data/icons/create/2d-poisson.svg +38 -0
  51. datalab/data/icons/create/2d-ramp.svg +90 -0
  52. datalab/data/icons/create/2d-sinc.svg +62 -0
  53. datalab/data/icons/create/2d-uniform.svg +38 -0
  54. datalab/data/icons/create/2d-zero.svg +13 -0
  55. datalab/data/icons/create/checkerboard.svg +39 -0
  56. datalab/data/icons/create/cosine.svg +12 -0
  57. datalab/data/icons/create/exponential.svg +55 -0
  58. datalab/data/icons/create/gaussian.svg +12 -0
  59. datalab/data/icons/create/grating.svg +29 -0
  60. datalab/data/icons/create/linear_chirp.svg +7 -0
  61. datalab/data/icons/create/logistic.svg +7 -0
  62. datalab/data/icons/create/lorentzian.svg +12 -0
  63. datalab/data/icons/create/planck.svg +12 -0
  64. datalab/data/icons/create/polynomial.svg +7 -0
  65. datalab/data/icons/create/pulse.svg +12 -0
  66. datalab/data/icons/create/ring.svg +18 -0
  67. datalab/data/icons/create/sawtooth.svg +7 -0
  68. datalab/data/icons/create/siemens.svg +35 -0
  69. datalab/data/icons/create/sinc.svg +12 -0
  70. datalab/data/icons/create/sine.svg +7 -0
  71. datalab/data/icons/create/square.svg +7 -0
  72. datalab/data/icons/create/square_pulse.svg +7 -0
  73. datalab/data/icons/create/step.svg +7 -0
  74. datalab/data/icons/create/step_pulse.svg +12 -0
  75. datalab/data/icons/create/triangle.svg +7 -0
  76. datalab/data/icons/create/voigt.svg +12 -0
  77. datalab/data/icons/edit/annotations.svg +72 -0
  78. datalab/data/icons/edit/annotations_copy.svg +114 -0
  79. datalab/data/icons/edit/annotations_delete.svg +83 -0
  80. datalab/data/icons/edit/annotations_edit.svg +98 -0
  81. datalab/data/icons/edit/annotations_export.svg +85 -0
  82. datalab/data/icons/edit/annotations_import.svg +85 -0
  83. datalab/data/icons/edit/annotations_paste.svg +100 -0
  84. datalab/data/icons/edit/copy_titles.svg +109 -0
  85. datalab/data/icons/edit/delete.svg +84 -0
  86. datalab/data/icons/edit/delete_all.svg +214 -0
  87. datalab/data/icons/edit/duplicate.svg +64 -0
  88. datalab/data/icons/edit/goto_source.svg +60 -0
  89. datalab/data/icons/edit/metadata.svg +60 -0
  90. datalab/data/icons/edit/metadata_add.svg +80 -0
  91. datalab/data/icons/edit/metadata_copy.svg +96 -0
  92. datalab/data/icons/edit/metadata_delete.svg +62 -0
  93. datalab/data/icons/edit/metadata_export.svg +68 -0
  94. datalab/data/icons/edit/metadata_import.svg +68 -0
  95. datalab/data/icons/edit/metadata_paste.svg +79 -0
  96. datalab/data/icons/edit/move_down.svg +55 -0
  97. datalab/data/icons/edit/move_up.svg +54 -0
  98. datalab/data/icons/edit/new_group.svg +76 -0
  99. datalab/data/icons/edit/recompute.svg +60 -0
  100. datalab/data/icons/edit/rename.svg +49 -0
  101. datalab/data/icons/edit.svg +16 -0
  102. datalab/data/icons/expand.svg +44 -0
  103. datalab/data/icons/expand_selection.svg +63 -0
  104. datalab/data/icons/fit/cdf_fit.svg +56 -0
  105. datalab/data/icons/fit/exponential_fit.svg +55 -0
  106. datalab/data/icons/fit/gaussian_fit.svg +62 -0
  107. datalab/data/icons/fit/interactive_fit.svg +101 -0
  108. datalab/data/icons/fit/linear_fit.svg +57 -0
  109. datalab/data/icons/fit/lorentzian_fit.svg +209 -0
  110. datalab/data/icons/fit/multigaussian_fit.svg +85 -0
  111. datalab/data/icons/fit/multilorentzian_fit.svg +85 -0
  112. datalab/data/icons/fit/piecewiseexponential_fit.svg +209 -0
  113. datalab/data/icons/fit/planckian_fit.svg +62 -0
  114. datalab/data/icons/fit/polynomial_fit.svg +59 -0
  115. datalab/data/icons/fit/sigmoid_fit.svg +56 -0
  116. datalab/data/icons/fit/sinusoidal_fit.svg +72 -0
  117. datalab/data/icons/fit/twohalfgaussian_fit.svg +63 -0
  118. datalab/data/icons/fit/voigt_fit.svg +57 -0
  119. datalab/data/icons/group.svg +56 -0
  120. datalab/data/icons/h5/h5array.svg +59 -0
  121. datalab/data/icons/h5/h5attrs.svg +75 -0
  122. datalab/data/icons/h5/h5browser.svg +133 -0
  123. datalab/data/icons/h5/h5file.svg +69 -0
  124. datalab/data/icons/h5/h5group.svg +49 -0
  125. datalab/data/icons/h5/h5scalar.svg +1 -0
  126. datalab/data/icons/help_pdf.svg +46 -0
  127. datalab/data/icons/history.svg +7 -0
  128. datalab/data/icons/image.svg +135 -0
  129. datalab/data/icons/io/fileopen_directory.svg +60 -0
  130. datalab/data/icons/io/fileopen_h5.svg +84 -0
  131. datalab/data/icons/io/fileopen_ima.svg +187 -0
  132. datalab/data/icons/io/fileopen_py.svg +123 -0
  133. datalab/data/icons/io/fileopen_sig.svg +138 -0
  134. datalab/data/icons/io/filesave_h5.svg +97 -0
  135. datalab/data/icons/io/filesave_ima.svg +200 -0
  136. datalab/data/icons/io/filesave_py.svg +136 -0
  137. datalab/data/icons/io/filesave_sig.svg +151 -0
  138. datalab/data/icons/io/import_text.svg +144 -0
  139. datalab/data/icons/io/save_to_directory.svg +134 -0
  140. datalab/data/icons/io.svg +84 -0
  141. datalab/data/icons/libre-camera-flash-off.svg +1 -0
  142. datalab/data/icons/libre-camera-flash-on.svg +1 -0
  143. datalab/data/icons/libre-gui-about.svg +1 -0
  144. datalab/data/icons/libre-gui-action-delete.svg +1 -0
  145. datalab/data/icons/libre-gui-add.svg +1 -0
  146. datalab/data/icons/libre-gui-arrow-down.svg +1 -0
  147. datalab/data/icons/libre-gui-arrow-left.svg +1 -0
  148. datalab/data/icons/libre-gui-arrow-right.svg +1 -0
  149. datalab/data/icons/libre-gui-arrow-up.svg +1 -0
  150. datalab/data/icons/libre-gui-close.svg +40 -0
  151. datalab/data/icons/libre-gui-cogs.svg +1 -0
  152. datalab/data/icons/libre-gui-globe.svg +1 -0
  153. datalab/data/icons/libre-gui-help.svg +1 -0
  154. datalab/data/icons/libre-gui-link.svg +1 -0
  155. datalab/data/icons/libre-gui-menu.svg +1 -0
  156. datalab/data/icons/libre-gui-pencil.svg +1 -0
  157. datalab/data/icons/libre-gui-plugin.svg +1 -0
  158. datalab/data/icons/libre-gui-questions.svg +1 -0
  159. datalab/data/icons/libre-gui-settings.svg +1 -0
  160. datalab/data/icons/libre-gui-unlink.svg +1 -0
  161. datalab/data/icons/libre-tech-ram.svg +1 -0
  162. datalab/data/icons/libre-toolbox.svg +1 -0
  163. datalab/data/icons/logs.svg +1 -0
  164. datalab/data/icons/markers.svg +74 -0
  165. datalab/data/icons/menu.svg +13 -0
  166. datalab/data/icons/new_ima.svg +148 -0
  167. datalab/data/icons/new_sig.svg +123 -0
  168. datalab/data/icons/operations/abs.svg +116 -0
  169. datalab/data/icons/operations/arithmetic.svg +123 -0
  170. datalab/data/icons/operations/average.svg +124 -0
  171. datalab/data/icons/operations/complex_from_magnitude_phase.svg +116 -0
  172. datalab/data/icons/operations/complex_from_real_imag.svg +124 -0
  173. datalab/data/icons/operations/constant.svg +116 -0
  174. datalab/data/icons/operations/constant_add.svg +109 -0
  175. datalab/data/icons/operations/constant_divide.svg +109 -0
  176. datalab/data/icons/operations/constant_multiply.svg +109 -0
  177. datalab/data/icons/operations/constant_subtract.svg +109 -0
  178. datalab/data/icons/operations/convert_dtype.svg +117 -0
  179. datalab/data/icons/operations/convolution.svg +46 -0
  180. datalab/data/icons/operations/deconvolution.svg +57 -0
  181. datalab/data/icons/operations/derivative.svg +127 -0
  182. datalab/data/icons/operations/difference.svg +52 -0
  183. datalab/data/icons/operations/division.svg +139 -0
  184. datalab/data/icons/operations/exp.svg +116 -0
  185. datalab/data/icons/operations/flip_horizontally.svg +69 -0
  186. datalab/data/icons/operations/flip_vertically.svg +74 -0
  187. datalab/data/icons/operations/im.svg +124 -0
  188. datalab/data/icons/operations/integral.svg +50 -0
  189. datalab/data/icons/operations/inverse.svg +143 -0
  190. datalab/data/icons/operations/log10.svg +109 -0
  191. datalab/data/icons/operations/phase.svg +116 -0
  192. datalab/data/icons/operations/power.svg +118 -0
  193. datalab/data/icons/operations/product.svg +124 -0
  194. datalab/data/icons/operations/profile.svg +379 -0
  195. datalab/data/icons/operations/profile_average.svg +399 -0
  196. datalab/data/icons/operations/profile_radial.svg +261 -0
  197. datalab/data/icons/operations/profile_segment.svg +262 -0
  198. datalab/data/icons/operations/quadratic_difference.svg +84 -0
  199. datalab/data/icons/operations/re.svg +124 -0
  200. datalab/data/icons/operations/rotate_left.svg +72 -0
  201. datalab/data/icons/operations/rotate_right.svg +72 -0
  202. datalab/data/icons/operations/signals_to_image.svg +314 -0
  203. datalab/data/icons/operations/sqrt.svg +110 -0
  204. datalab/data/icons/operations/std.svg +124 -0
  205. datalab/data/icons/operations/sum.svg +102 -0
  206. datalab/data/icons/play_demo.svg +9 -0
  207. datalab/data/icons/processing/axis_transform.svg +62 -0
  208. datalab/data/icons/processing/bandpass.svg +79 -0
  209. datalab/data/icons/processing/bandstop.svg +71 -0
  210. datalab/data/icons/processing/binning.svg +126 -0
  211. datalab/data/icons/processing/clip.svg +119 -0
  212. datalab/data/icons/processing/detrending.svg +173 -0
  213. datalab/data/icons/processing/distribute_on_grid.svg +769 -0
  214. datalab/data/icons/processing/edge_detection.svg +46 -0
  215. datalab/data/icons/processing/erase.svg +1 -0
  216. datalab/data/icons/processing/exposure.svg +143 -0
  217. datalab/data/icons/processing/fourier.svg +104 -0
  218. datalab/data/icons/processing/highpass.svg +59 -0
  219. datalab/data/icons/processing/interpolation.svg +71 -0
  220. datalab/data/icons/processing/level_adjustment.svg +70 -0
  221. datalab/data/icons/processing/lowpass.svg +60 -0
  222. datalab/data/icons/processing/morphology.svg +49 -0
  223. datalab/data/icons/processing/noise_addition.svg +114 -0
  224. datalab/data/icons/processing/noise_reduction.svg +38 -0
  225. datalab/data/icons/processing/normalize.svg +84 -0
  226. datalab/data/icons/processing/offset_correction.svg +131 -0
  227. datalab/data/icons/processing/resampling1d.svg +101 -0
  228. datalab/data/icons/processing/resampling2d.svg +240 -0
  229. datalab/data/icons/processing/reset_positions.svg +185 -0
  230. datalab/data/icons/processing/resize.svg +9 -0
  231. datalab/data/icons/processing/reverse_signal_x.svg +171 -0
  232. datalab/data/icons/processing/stability.svg +11 -0
  233. datalab/data/icons/processing/swap_x_y.svg +65 -0
  234. datalab/data/icons/processing/thresholding.svg +63 -0
  235. datalab/data/icons/processing/windowing.svg +45 -0
  236. datalab/data/icons/properties.svg +26 -0
  237. datalab/data/icons/reset.svg +9 -0
  238. datalab/data/icons/restore.svg +40 -0
  239. datalab/data/icons/roi/roi.svg +76 -0
  240. datalab/data/icons/roi/roi_coordinate.svg +78 -0
  241. datalab/data/icons/roi/roi_copy.svg +112 -0
  242. datalab/data/icons/roi/roi_delete.svg +81 -0
  243. datalab/data/icons/roi/roi_export.svg +87 -0
  244. datalab/data/icons/roi/roi_graphical.svg +78 -0
  245. datalab/data/icons/roi/roi_grid.svg +67 -0
  246. datalab/data/icons/roi/roi_ima.svg +188 -0
  247. datalab/data/icons/roi/roi_import.svg +87 -0
  248. datalab/data/icons/roi/roi_new.svg +81 -0
  249. datalab/data/icons/roi/roi_new_circle.svg +95 -0
  250. datalab/data/icons/roi/roi_new_polygon.svg +110 -0
  251. datalab/data/icons/roi/roi_new_rectangle.svg +70 -0
  252. datalab/data/icons/roi/roi_paste.svg +98 -0
  253. datalab/data/icons/roi/roi_sig.svg +124 -0
  254. datalab/data/icons/shapes.svg +134 -0
  255. datalab/data/icons/signal.svg +103 -0
  256. datalab/data/icons/table.svg +85 -0
  257. datalab/data/icons/table_unavailable.svg +102 -0
  258. datalab/data/icons/to_signal.svg +124 -0
  259. datalab/data/icons/tour/next.svg +44 -0
  260. datalab/data/icons/tour/previous.svg +44 -0
  261. datalab/data/icons/tour/rewind.svg +51 -0
  262. datalab/data/icons/tour/stop.svg +47 -0
  263. datalab/data/icons/tour/tour.svg +16 -0
  264. datalab/data/icons/uncheck_all.svg +78 -0
  265. datalab/data/icons/view/curve_antialiasing.svg +50 -0
  266. datalab/data/icons/view/new_window.svg +98 -0
  267. datalab/data/icons/view/refresh-auto.svg +57 -0
  268. datalab/data/icons/view/refresh-manual.svg +51 -0
  269. datalab/data/icons/view/reset_curve_styles.svg +96 -0
  270. datalab/data/icons/view/show_first.svg +55 -0
  271. datalab/data/icons/view/show_titles.svg +46 -0
  272. datalab/data/icons/visualization.svg +51 -0
  273. datalab/data/logo/DataLab-Banner-150.png +0 -0
  274. datalab/data/logo/DataLab-Banner-200.png +0 -0
  275. datalab/data/logo/DataLab-Banner2-100.png +0 -0
  276. datalab/data/logo/DataLab-Splash.png +0 -0
  277. datalab/data/logo/DataLab-watermark.png +0 -0
  278. datalab/data/logo/DataLab.svg +83 -0
  279. datalab/data/tests/reordering_test.h5 +0 -0
  280. datalab/data/tutorials/fabry_perot/fabry-perot1.jpg +0 -0
  281. datalab/data/tutorials/fabry_perot/fabry-perot2.jpg +0 -0
  282. datalab/data/tutorials/laser_beam/TEM00_z_13.jpg +0 -0
  283. datalab/data/tutorials/laser_beam/TEM00_z_18.jpg +0 -0
  284. datalab/data/tutorials/laser_beam/TEM00_z_23.jpg +0 -0
  285. datalab/data/tutorials/laser_beam/TEM00_z_30.jpg +0 -0
  286. datalab/data/tutorials/laser_beam/TEM00_z_35.jpg +0 -0
  287. datalab/data/tutorials/laser_beam/TEM00_z_40.jpg +0 -0
  288. datalab/data/tutorials/laser_beam/TEM00_z_45.jpg +0 -0
  289. datalab/data/tutorials/laser_beam/TEM00_z_50.jpg +0 -0
  290. datalab/data/tutorials/laser_beam/TEM00_z_55.jpg +0 -0
  291. datalab/data/tutorials/laser_beam/TEM00_z_60.jpg +0 -0
  292. datalab/data/tutorials/laser_beam/TEM00_z_65.jpg +0 -0
  293. datalab/data/tutorials/laser_beam/TEM00_z_70.jpg +0 -0
  294. datalab/data/tutorials/laser_beam/TEM00_z_75.jpg +0 -0
  295. datalab/data/tutorials/laser_beam/TEM00_z_80.jpg +0 -0
  296. datalab/env.py +542 -0
  297. datalab/gui/__init__.py +89 -0
  298. datalab/gui/actionhandler.py +1701 -0
  299. datalab/gui/docks.py +473 -0
  300. datalab/gui/h5io.py +150 -0
  301. datalab/gui/macroeditor.py +310 -0
  302. datalab/gui/main.py +2081 -0
  303. datalab/gui/newobject.py +217 -0
  304. datalab/gui/objectview.py +766 -0
  305. datalab/gui/panel/__init__.py +48 -0
  306. datalab/gui/panel/base.py +3254 -0
  307. datalab/gui/panel/image.py +157 -0
  308. datalab/gui/panel/macro.py +607 -0
  309. datalab/gui/panel/signal.py +164 -0
  310. datalab/gui/plothandler.py +800 -0
  311. datalab/gui/processor/__init__.py +84 -0
  312. datalab/gui/processor/base.py +2456 -0
  313. datalab/gui/processor/catcher.py +75 -0
  314. datalab/gui/processor/image.py +1214 -0
  315. datalab/gui/processor/signal.py +755 -0
  316. datalab/gui/profiledialog.py +333 -0
  317. datalab/gui/roieditor.py +633 -0
  318. datalab/gui/roigrideditor.py +208 -0
  319. datalab/gui/settings.py +612 -0
  320. datalab/gui/tour.py +908 -0
  321. datalab/h5/__init__.py +12 -0
  322. datalab/h5/common.py +314 -0
  323. datalab/h5/generic.py +580 -0
  324. datalab/h5/native.py +39 -0
  325. datalab/h5/utils.py +95 -0
  326. datalab/objectmodel.py +640 -0
  327. datalab/plugins/_readme_.txt +9 -0
  328. datalab/plugins/datalab_imageformats.py +175 -0
  329. datalab/plugins/datalab_testdata.py +190 -0
  330. datalab/plugins.py +355 -0
  331. datalab/tests/__init__.py +199 -0
  332. datalab/tests/backbone/__init__.py +1 -0
  333. datalab/tests/backbone/config_unit_test.py +170 -0
  334. datalab/tests/backbone/config_versioning_unit_test.py +34 -0
  335. datalab/tests/backbone/dictlistserial_app_test.py +38 -0
  336. datalab/tests/backbone/errorcatcher_unit_test.py +69 -0
  337. datalab/tests/backbone/errormsgbox_unit_test.py +50 -0
  338. datalab/tests/backbone/execenv_unit.py +262 -0
  339. datalab/tests/backbone/loadtest_gdi.py +147 -0
  340. datalab/tests/backbone/long_callback.py +96 -0
  341. datalab/tests/backbone/main_app_test.py +137 -0
  342. datalab/tests/backbone/memory_leak.py +43 -0
  343. datalab/tests/backbone/procisolation1_unit.py +128 -0
  344. datalab/tests/backbone/procisolation2_unit.py +171 -0
  345. datalab/tests/backbone/procisolation_unit_test.py +22 -0
  346. datalab/tests/backbone/profiling_app.py +27 -0
  347. datalab/tests/backbone/strings_unit_test.py +65 -0
  348. datalab/tests/backbone/title_formatting_unit_test.py +82 -0
  349. datalab/tests/conftest.py +131 -0
  350. datalab/tests/features/__init__.py +1 -0
  351. datalab/tests/features/applauncher/__init__.py +1 -0
  352. datalab/tests/features/applauncher/launcher1_app_test.py +28 -0
  353. datalab/tests/features/applauncher/launcher2_app_test.py +30 -0
  354. datalab/tests/features/common/__init__.py +1 -0
  355. datalab/tests/features/common/add_metadata_app_test.py +134 -0
  356. datalab/tests/features/common/add_metadata_unit_test.py +267 -0
  357. datalab/tests/features/common/annotations_management_unit_test.py +152 -0
  358. datalab/tests/features/common/auto_analysis_recompute_unit_test.py +240 -0
  359. datalab/tests/features/common/createobject_unit_test.py +50 -0
  360. datalab/tests/features/common/geometry_results_app_test.py +135 -0
  361. datalab/tests/features/common/interactive_processing_test.py +1109 -0
  362. datalab/tests/features/common/io_app_test.py +75 -0
  363. datalab/tests/features/common/large_results_app_test.py +187 -0
  364. datalab/tests/features/common/metadata_all_patterns_test.py +103 -0
  365. datalab/tests/features/common/metadata_app_test.py +139 -0
  366. datalab/tests/features/common/metadata_io_unit_test.py +60 -0
  367. datalab/tests/features/common/misc_app_test.py +236 -0
  368. datalab/tests/features/common/multiple_geometry_results_unit_test.py +122 -0
  369. datalab/tests/features/common/multiple_table_results_unit_test.py +64 -0
  370. datalab/tests/features/common/operation_modes_app_test.py +392 -0
  371. datalab/tests/features/common/plot_results_app_test.py +278 -0
  372. datalab/tests/features/common/reorder_app_test.py +75 -0
  373. datalab/tests/features/common/result_deletion_unit_test.py +96 -0
  374. datalab/tests/features/common/result_merged_label_unit_test.py +154 -0
  375. datalab/tests/features/common/result_shape_settings_unit_test.py +223 -0
  376. datalab/tests/features/common/roi_plotitem_unit_test.py +64 -0
  377. datalab/tests/features/common/roieditor_unit_test.py +102 -0
  378. datalab/tests/features/common/save_to_dir_app_test.py +163 -0
  379. datalab/tests/features/common/save_to_dir_unit_test.py +474 -0
  380. datalab/tests/features/common/stat_app_test.py +40 -0
  381. datalab/tests/features/common/stats_tools_unit_test.py +77 -0
  382. datalab/tests/features/common/table_results_app_test.py +52 -0
  383. datalab/tests/features/common/textimport_unit_test.py +131 -0
  384. datalab/tests/features/common/uuid_preservation_test.py +281 -0
  385. datalab/tests/features/common/worker_unit_test.py +402 -0
  386. datalab/tests/features/control/__init__.py +1 -0
  387. datalab/tests/features/control/connect_dialog.py +28 -0
  388. datalab/tests/features/control/embedded1_unit_test.py +304 -0
  389. datalab/tests/features/control/embedded2_unit_test.py +52 -0
  390. datalab/tests/features/control/remoteclient_app_test.py +219 -0
  391. datalab/tests/features/control/remoteclient_unit.py +75 -0
  392. datalab/tests/features/control/simpleclient_unit_test.py +321 -0
  393. datalab/tests/features/hdf5/__init__.py +1 -0
  394. datalab/tests/features/hdf5/h5browser1_unit_test.py +31 -0
  395. datalab/tests/features/hdf5/h5browser2_unit.py +55 -0
  396. datalab/tests/features/hdf5/h5browser_app_test.py +77 -0
  397. datalab/tests/features/hdf5/h5import_app_test.py +25 -0
  398. datalab/tests/features/hdf5/h5importer_app_test.py +34 -0
  399. datalab/tests/features/image/__init__.py +1 -0
  400. datalab/tests/features/image/annotations_app_test.py +28 -0
  401. datalab/tests/features/image/annotations_unit_test.py +80 -0
  402. datalab/tests/features/image/average_app_test.py +46 -0
  403. datalab/tests/features/image/background_dialog_test.py +70 -0
  404. datalab/tests/features/image/blobs_app_test.py +50 -0
  405. datalab/tests/features/image/contour_app_test.py +42 -0
  406. datalab/tests/features/image/contour_fabryperot_app_test.py +51 -0
  407. datalab/tests/features/image/denoise_app_test.py +31 -0
  408. datalab/tests/features/image/distribute_on_grid_app_test.py +95 -0
  409. datalab/tests/features/image/edges_app_test.py +31 -0
  410. datalab/tests/features/image/erase_app_test.py +21 -0
  411. datalab/tests/features/image/fft2d_app_test.py +27 -0
  412. datalab/tests/features/image/flatfield_app_test.py +40 -0
  413. datalab/tests/features/image/geometry_transform_unit_test.py +396 -0
  414. datalab/tests/features/image/imagetools_app_test.py +51 -0
  415. datalab/tests/features/image/imagetools_unit_test.py +27 -0
  416. datalab/tests/features/image/load_app_test.py +73 -0
  417. datalab/tests/features/image/morph_app_test.py +32 -0
  418. datalab/tests/features/image/offsetcorrection_app_test.py +30 -0
  419. datalab/tests/features/image/peak2d_app_test.py +53 -0
  420. datalab/tests/features/image/profile_app_test.py +73 -0
  421. datalab/tests/features/image/profile_dialog_test.py +56 -0
  422. datalab/tests/features/image/roi_app_test.py +98 -0
  423. datalab/tests/features/image/roi_circ_app_test.py +62 -0
  424. datalab/tests/features/image/roi_manipulation_app_test.py +268 -0
  425. datalab/tests/features/image/roigrid_unit_test.py +60 -0
  426. datalab/tests/features/image/side_by_side_app_test.py +52 -0
  427. datalab/tests/features/macro/__init__.py +1 -0
  428. datalab/tests/features/macro/macro_app_test.py +28 -0
  429. datalab/tests/features/macro/macroeditor_unit_test.py +102 -0
  430. datalab/tests/features/signal/__init__.py +1 -0
  431. datalab/tests/features/signal/baseline_dialog_test.py +53 -0
  432. datalab/tests/features/signal/deltax_dialog_unit_test.py +34 -0
  433. datalab/tests/features/signal/fft1d_app_test.py +26 -0
  434. datalab/tests/features/signal/filter_app_test.py +44 -0
  435. datalab/tests/features/signal/fitdialog_unit_test.py +50 -0
  436. datalab/tests/features/signal/interpolation_app_test.py +110 -0
  437. datalab/tests/features/signal/loadbigsignal_app_test.py +80 -0
  438. datalab/tests/features/signal/multiple_rois_unit_test.py +132 -0
  439. datalab/tests/features/signal/pulse_features_app_test.py +118 -0
  440. datalab/tests/features/signal/pulse_features_roi_app_test.py +55 -0
  441. datalab/tests/features/signal/roi_app_test.py +78 -0
  442. datalab/tests/features/signal/roi_manipulation_app_test.py +261 -0
  443. datalab/tests/features/signal/select_xy_cursor_unit_test.py +46 -0
  444. datalab/tests/features/signal/signalpeakdetection_dialog_test.py +33 -0
  445. datalab/tests/features/signal/signals_to_image_app_test.py +98 -0
  446. datalab/tests/features/signal/xarray_compat_app_test.py +128 -0
  447. datalab/tests/features/tour_unit_test.py +22 -0
  448. datalab/tests/features/utilities/__init__.py +1 -0
  449. datalab/tests/features/utilities/installconf_unit_test.py +21 -0
  450. datalab/tests/features/utilities/logview_app_test.py +21 -0
  451. datalab/tests/features/utilities/logview_error.py +24 -0
  452. datalab/tests/features/utilities/logview_unit_test.py +21 -0
  453. datalab/tests/features/utilities/memstatus_app_test.py +42 -0
  454. datalab/tests/features/utilities/settings_unit_test.py +88 -0
  455. datalab/tests/scenarios/__init__.py +1 -0
  456. datalab/tests/scenarios/beautiful_app.py +121 -0
  457. datalab/tests/scenarios/common.py +463 -0
  458. datalab/tests/scenarios/demo.py +212 -0
  459. datalab/tests/scenarios/example_app_test.py +47 -0
  460. datalab/tests/scenarios/scenario_h5_app_test.py +75 -0
  461. datalab/tests/scenarios/scenario_ima1_app_test.py +34 -0
  462. datalab/tests/scenarios/scenario_ima2_app_test.py +34 -0
  463. datalab/tests/scenarios/scenario_mac_app_test.py +58 -0
  464. datalab/tests/scenarios/scenario_sig1_app_test.py +36 -0
  465. datalab/tests/scenarios/scenario_sig2_app_test.py +35 -0
  466. datalab/utils/__init__.py +1 -0
  467. datalab/utils/conf.py +304 -0
  468. datalab/utils/dephash.py +105 -0
  469. datalab/utils/qthelpers.py +633 -0
  470. datalab/utils/strings.py +34 -0
  471. datalab/utils/tests.py +0 -0
  472. datalab/widgets/__init__.py +1 -0
  473. datalab/widgets/connection.py +138 -0
  474. datalab/widgets/filedialog.py +91 -0
  475. datalab/widgets/fileviewer.py +84 -0
  476. datalab/widgets/fitdialog.py +788 -0
  477. datalab/widgets/h5browser.py +1048 -0
  478. datalab/widgets/imagebackground.py +111 -0
  479. datalab/widgets/instconfviewer.py +175 -0
  480. datalab/widgets/logviewer.py +80 -0
  481. datalab/widgets/signalbaseline.py +90 -0
  482. datalab/widgets/signalcursor.py +208 -0
  483. datalab/widgets/signaldeltax.py +151 -0
  484. datalab/widgets/signalpeak.py +199 -0
  485. datalab/widgets/status.py +249 -0
  486. datalab/widgets/textimport.py +786 -0
  487. datalab/widgets/warningerror.py +223 -0
  488. datalab/widgets/wizard.py +286 -0
  489. datalab_platform-1.0.0.dist-info/METADATA +121 -0
  490. datalab_platform-1.0.0.dist-info/RECORD +494 -0
  491. datalab_platform-0.0.1.dev0.dist-info/METADATA +0 -67
  492. datalab_platform-0.0.1.dev0.dist-info/RECORD +0 -7
  493. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/WHEEL +0 -0
  494. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/entry_points.txt +0 -0
  495. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/licenses/LICENSE +0 -0
  496. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,304 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Application embedded test 1
5
+
6
+ DataLab main window is destroyed when closing application.
7
+ It is rebuilt from scratch when reopening application.
8
+ """
9
+
10
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
11
+ # guitest: show
12
+
13
+ import abc
14
+
15
+ from guidata.qthelpers import (
16
+ get_std_icon,
17
+ qt_app_context,
18
+ win32_fix_title_bar_background,
19
+ )
20
+ from guidata.widgets.codeeditor import CodeEditor
21
+ from qtpy import QtWidgets as QW
22
+ from sigima.objects import NewImageParam
23
+ from sigima.tests import data as test_data
24
+
25
+ from datalab.config import _
26
+ from datalab.gui.main import DLMainWindow
27
+ from datalab.tests.features.macro.macroeditor_unit_test import get_macro_example_path
28
+
29
+
30
+ class HostWidget(QW.QWidget):
31
+ """Host widget: menu with action buttons, log viewer"""
32
+
33
+ def __init__(self, parent=None):
34
+ super().__init__(parent)
35
+ self.button_layout = QW.QVBoxLayout()
36
+ self.logwidget = CodeEditor(self)
37
+ self.logwidget.setMinimumWidth(500)
38
+ grid_layout = QW.QGridLayout()
39
+ grid_layout.addLayout(self.button_layout, 0, 0)
40
+ grid_layout.addWidget(self.logwidget, 0, 1)
41
+ self.setLayout(grid_layout)
42
+
43
+ def log(self, message):
44
+ """Log message"""
45
+ self.logwidget.appendPlainText(message)
46
+
47
+ def add_spacing(self, spacing: int) -> None:
48
+ """Add spacing to button box"""
49
+ self.button_layout.addSpacing(spacing)
50
+
51
+ def add_label(self, text: str) -> None:
52
+ """Add label to button box"""
53
+ self.button_layout.addWidget(QW.QLabel(text))
54
+
55
+ def add_widget(self, obj: QW.QWidget, spacing_before: int = 0) -> None:
56
+ """Add widget (QWidget) to button box"""
57
+ if spacing_before > 0:
58
+ self.add_spacing(spacing_before)
59
+ self.button_layout.addWidget(obj)
60
+
61
+ def add_button(self, title, slot, spacing_before=0, icon=None):
62
+ """Add button"""
63
+ btn = QW.QPushButton(title)
64
+ if icon is not None:
65
+ btn.setIcon(get_std_icon(icon))
66
+ btn.clicked.connect(lambda _checked=False: slot())
67
+ self.add_widget(btn, spacing_before=spacing_before)
68
+ return btn
69
+
70
+ def add_stretch(self):
71
+ """Add stretch to button box"""
72
+ self.button_layout.addStretch()
73
+
74
+
75
+ class AbstractClientWindowMeta(type(QW.QMainWindow), abc.ABCMeta):
76
+ """Mixed metaclass to avoid conflicts"""
77
+
78
+
79
+ class AbstractClientWindow(QW.QMainWindow, metaclass=AbstractClientWindowMeta):
80
+ """Abstract client window, to embed DataLab or connect to it"""
81
+
82
+ PURPOSE = None
83
+ INIT_BUTTON_LABEL = None
84
+ SIG_TITLES = ("Oscilloscope", "Digitizer", "Radiometer", "Voltmeter", "Sensor")
85
+ IMA_TITLES = (
86
+ "Camera",
87
+ "Streak Camera",
88
+ "Image Scanner",
89
+ "Laser Beam Profiler",
90
+ "Gated Imaging Camera",
91
+ )
92
+
93
+ def __init__(self):
94
+ super().__init__()
95
+ win32_fix_title_bar_background(self)
96
+ self.setWindowTitle(_("Host application"))
97
+ self.setWindowIcon(get_std_icon("ComputerIcon"))
98
+ self.datalab: DLMainWindow = None
99
+ self.host = HostWidget(self)
100
+ self.setCentralWidget(self.host)
101
+ self.setup_window()
102
+ self.host.add_stretch()
103
+ self.index_sigtitle = -1
104
+ self.index_imatitle = -1
105
+
106
+ @property
107
+ def sigtitle(self):
108
+ """Return current signal title index"""
109
+ self.index_sigtitle = idx = (self.index_sigtitle + 1) % len(self.SIG_TITLES)
110
+ return self.SIG_TITLES[idx]
111
+
112
+ @property
113
+ def imatitle(self):
114
+ """Return current image title index"""
115
+ self.index_imatitle = idx = (self.index_imatitle + 1) % len(self.IMA_TITLES)
116
+ return self.IMA_TITLES[idx]
117
+
118
+ def setup_window(self):
119
+ """Setup window"""
120
+ self.host.add_label(self.PURPOSE)
121
+ add_btn = self.host.add_button
122
+ add_btn(self.INIT_BUTTON_LABEL, self.init_cdl, 10, "DialogApplyButton")
123
+ add_btn(_("Raise window"), self.raise_cdl, 0, "FileDialogToParent")
124
+ self.add_additional_buttons()
125
+ add_btn(_("Add signal objects"), self.add_signals, 10, "CommandLink")
126
+ add_btn(_("Add image objects"), self.add_images, 0, "CommandLink")
127
+ add_btn(_("Remove all objects"), self.remove_all, 5, "MessageBoxWarning")
128
+ add_btn(_("Run macro"), self.run_macro, 10, "CommandLink")
129
+ add_btn(_("Stop macro"), self.stop_macro, 0, "CommandLink")
130
+ add_btn(
131
+ _("Import macro from file (example)"), self.import_macro, 0, "CommandLink"
132
+ )
133
+ add_btn(_("Close DataLab"), self.close_datalab, 10, "DialogCloseButton")
134
+
135
+ def add_additional_buttons(self):
136
+ """Add additional buttons"""
137
+
138
+ @abc.abstractmethod
139
+ def init_cdl(self):
140
+ """Open DataLab test"""
141
+
142
+ def raise_cdl(self):
143
+ """Raise DataLab window"""
144
+ if self.datalab is not None:
145
+ self.datalab.raise_window()
146
+ self.host.log("=> Raised DataLab window")
147
+
148
+ @abc.abstractmethod
149
+ def close_datalab(self):
150
+ """Close DataLab window"""
151
+
152
+ def add_object(self, obj):
153
+ """Add object to DataLab"""
154
+ if self.datalab is not None:
155
+ self.datalab.add_object(obj)
156
+
157
+ def add_signals(self):
158
+ """Add signals to DataLab"""
159
+ if self.datalab is not None:
160
+ for func in (
161
+ test_data.create_paracetamol_signal,
162
+ test_data.create_noisy_signal,
163
+ ):
164
+ obj = func(title=self.sigtitle)
165
+ self.add_object(obj)
166
+ self.host.log(f"Added signal: {obj.title}")
167
+
168
+ def add_images(self):
169
+ """Add images to DataLab"""
170
+ if self.datalab is not None:
171
+ p = NewImageParam.create(height=2000, width=2000, title=self.imatitle)
172
+ for func in (
173
+ test_data.create_sincos_image,
174
+ test_data.create_noisy_gaussian_image,
175
+ test_data.create_multigaussian_image,
176
+ ):
177
+ obj = func(p)
178
+ self.add_object(obj)
179
+ self.host.log(f"Added image: {obj.title}")
180
+
181
+ @abc.abstractmethod
182
+ def remove_all(self):
183
+ """Remove all objects from DataLab"""
184
+
185
+ def __has_macro(self):
186
+ """Check if there is a macro in DataLab"""
187
+ return len(self.datalab.get_object_titles("macro")) > 0
188
+
189
+ def run_macro(self):
190
+ """Run macro in DataLab"""
191
+ if self.datalab is not None:
192
+ if self.__has_macro():
193
+ self.datalab.run_macro()
194
+ self.host.log("=> Running macro")
195
+ else:
196
+ self.host.log("No macro to run")
197
+
198
+ def stop_macro(self):
199
+ """Stop macro in DataLab"""
200
+ if self.datalab is not None:
201
+ if self.__has_macro():
202
+ self.datalab.stop_macro()
203
+ self.host.log("=> Stopping macro")
204
+ else:
205
+ self.host.log("No macro to stop")
206
+
207
+ def import_macro(self):
208
+ """Import macro in DataLab"""
209
+ if self.datalab is not None:
210
+ fname = get_macro_example_path()
211
+ self.datalab.import_macro_from_file(fname)
212
+ self.host.log(f"=> Imported macro: {fname}")
213
+
214
+
215
+ class AbstractHostWindow(AbstractClientWindow): # pylint: disable=abstract-method
216
+ """Abstract host window, embedding DataLab"""
217
+
218
+ PURPOSE = _("This the host application, which embeds DataLab.")
219
+ INIT_BUTTON_LABEL = _("Open DataLab")
220
+
221
+ def remove_all(self):
222
+ """Remove all objects from DataLab"""
223
+ if self.datalab is not None:
224
+ for panel in self.datalab.panels:
225
+ panel.remove_all_objects()
226
+ self.host.log(f"Removed objects from {panel.PANEL_STR}")
227
+
228
+ def add_additional_buttons(self):
229
+ """Add additional buttons"""
230
+ add_btn = self.host.add_button
231
+ add_btn(_("Import signal from DataLab"), self.import_signal, 10, "ArrowLeft")
232
+ add_btn(_("Import image from DataLab"), self.import_image, 0, "ArrowLeft")
233
+
234
+ def import_object(self, panel, title):
235
+ """Import object from DataLab"""
236
+ self.host.log(f"get_objects_with_dialog ({title}):")
237
+ objs = panel.get_objects_with_dialog(title, parent=self.host)
238
+ if objs is not None:
239
+ for obj in objs:
240
+ self.host.log(f" -> {obj.title}:")
241
+ self.host.log(str(obj))
242
+ else:
243
+ self.host.log(" -> canceled")
244
+
245
+ def import_signal(self):
246
+ """Import signal from DataLab"""
247
+ if self.datalab is not None:
248
+ self.import_object(self.datalab.signalpanel, self.sender().text())
249
+
250
+ def import_image(self):
251
+ """Import image from DataLab"""
252
+ if self.datalab is not None:
253
+ self.import_object(self.datalab.imagepanel, self.sender().text())
254
+
255
+
256
+ class HostWindow(AbstractHostWindow):
257
+ """Test main view"""
258
+
259
+ def init_cdl(self):
260
+ """Open DataLab test"""
261
+ if self.datalab is None:
262
+ self.datalab = DLMainWindow(console=False)
263
+ self.datalab.SIG_CLOSING.connect(self.datalab_was_closed)
264
+ self.datalab.show()
265
+ self.host.log("✨Initialized DataLab window")
266
+ else:
267
+ try:
268
+ self.datalab.show()
269
+ self.datalab.raise_()
270
+ self.host.log("=> Shown DataLab window")
271
+ except RuntimeError:
272
+ self.datalab = None
273
+ self.init_cdl()
274
+
275
+ def datalab_was_closed(self):
276
+ """DataLab was closed"""
277
+ self.datalab = None
278
+ self.host.log("✨DataLab window was closed by user")
279
+
280
+ def close_datalab(self):
281
+ """Close DataLab window"""
282
+ if self.datalab is not None:
283
+ self.host.log("=> Closed DataLab")
284
+ self.datalab.SIG_CLOSING.disconnect(self.datalab_was_closed)
285
+ self.datalab.close()
286
+ self.datalab.deleteLater()
287
+ self.datalab = None
288
+
289
+
290
+ def run_host_window(klass):
291
+ """Running host window to test DataLab embedding feature"""
292
+ with qt_app_context(exec_loop=True):
293
+ window: HostWindow = klass()
294
+ window.resize(800, 800)
295
+ window.show()
296
+
297
+
298
+ def test_embedded_feature():
299
+ """Testing embedded feature"""
300
+ run_host_window(HostWindow)
301
+
302
+
303
+ if __name__ == "__main__":
304
+ test_embedded_feature()
@@ -0,0 +1,52 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Application embedded test 2
5
+
6
+ DataLab main window is simply hidden when closing application.
7
+ It is shown and raised above other windows when reopening application.
8
+ """
9
+
10
+ # guitest: show
11
+
12
+ from datalab.gui.main import DLMainWindow
13
+ from datalab.tests.features.control import embedded1_unit_test
14
+
15
+
16
+ class HostWindow(embedded1_unit_test.AbstractHostWindow):
17
+ """Test main view"""
18
+
19
+ def init_cdl(self) -> None:
20
+ """Open DataLab test"""
21
+ if self.datalab is None:
22
+ self.datalab = DLMainWindow(console=False, hide_on_close=True)
23
+ self.host.log("✨ Initialized DataLab window")
24
+ self.datalab.show()
25
+ else:
26
+ self.datalab.show()
27
+ self.datalab.raise_window()
28
+ self.host.log("=> Shown DataLab window")
29
+
30
+ def close_datalab(self) -> None:
31
+ """Close DataLab window"""
32
+ if self.datalab is not None:
33
+ self.host.log("=> Closed DataLab")
34
+ self.datalab.close()
35
+
36
+ def closeEvent(self, event) -> None: # pylint: disable=invalid-name
37
+ """Close event
38
+
39
+ Reimplemented from QWidget.closeEvent"""
40
+ if self.datalab is None or self.datalab.close_properly():
41
+ event.accept()
42
+ else:
43
+ event.ignore()
44
+
45
+
46
+ def test_embedded_feature():
47
+ """Testing embedded feature"""
48
+ embedded1_unit_test.run_host_window(HostWindow)
49
+
50
+
51
+ if __name__ == "__main__":
52
+ test_embedded_feature()
@@ -0,0 +1,219 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Remote GUI-based client test
5
+ """
6
+
7
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
8
+ # pylint: disable=duplicate-code
9
+
10
+ # guitest: show
11
+
12
+ from __future__ import annotations
13
+
14
+ import functools
15
+ from contextlib import contextmanager
16
+
17
+ from guidata.qthelpers import qt_app_context, qt_wait
18
+ from qtpy import QtWidgets as QW
19
+
20
+ from datalab.config import _
21
+ from datalab.control.proxy import RemoteProxy
22
+ from datalab.env import execenv
23
+ from datalab.tests import run_datalab_in_background
24
+ from datalab.tests.features.control import embedded1_unit_test
25
+ from datalab.tests.features.control.remoteclient_unit import multiple_commands
26
+ from datalab.utils.qthelpers import bring_to_front
27
+ from datalab.widgets.connection import ConnectionDialog
28
+
29
+ APP_NAME = _("Remote client test")
30
+
31
+
32
+ def try_send_command():
33
+ """Try and send command to DataLab application remotely"""
34
+
35
+ def try_send_command_decorator(func):
36
+ """Try... except... decorator"""
37
+
38
+ @functools.wraps(func)
39
+ def method_wrapper(*args, **kwargs):
40
+ """Decorator wrapper function"""
41
+ self: HostWindow = args[0] # extracting 'self' from method arguments
42
+ output = None
43
+ try:
44
+ output = func(*args, **kwargs)
45
+ except ConnectionRefusedError as exc:
46
+ self.datalab = None
47
+ message = "🔥 Connection refused 🔥 (server is not ready?)"
48
+ self.host.log(message)
49
+ if execenv.unattended:
50
+ raise ConnectionRefusedError(
51
+ "Connection refused (server is not ready?)"
52
+ ) from exc
53
+ QW.QMessageBox.critical(self, APP_NAME, message)
54
+ return output
55
+
56
+ return method_wrapper
57
+
58
+ return try_send_command_decorator
59
+
60
+
61
+ class HostWindow(embedded1_unit_test.AbstractClientWindow):
62
+ """Test main view"""
63
+
64
+ PURPOSE = _("This the client application, which connects to DataLab.")
65
+ INIT_BUTTON_LABEL = _("Connect to DataLab")
66
+
67
+ def init_cdl(self):
68
+ """Open DataLab test"""
69
+ if self.datalab is None:
70
+ if execenv.unattended:
71
+ self.datalab = RemoteProxy()
72
+ ok = True
73
+ else:
74
+ self.datalab = RemoteProxy(autoconnect=False)
75
+ connect_dlg = ConnectionDialog(self.datalab.connect, self)
76
+ ok = connect_dlg.exec()
77
+ if ok:
78
+ self.host.log("✨ Initialized DataLab connection ✨")
79
+ self.host.log(f" Communication port: {self.datalab.port}")
80
+ self.host.log(" List of exposed methods:")
81
+ for name in self.datalab.get_method_list():
82
+ self.host.log(f" {name}")
83
+ else:
84
+ self.datalab = None
85
+ error_msg = connect_dlg.get_error_message()
86
+ self.host.log(f"🔥 Connection refused 🔥 ({error_msg})")
87
+ if execenv.unattended:
88
+ raise ConnectionRefusedError(
89
+ "Connection refused (server is not ready?)"
90
+ )
91
+ else:
92
+ self.host.log("=> Already connected to DataLab")
93
+
94
+ @try_send_command()
95
+ def close_datalab(self):
96
+ """Close DataLab window"""
97
+ if self.datalab is not None:
98
+ self.datalab.close_application()
99
+ self.host.log("🎬 Closed DataLab!")
100
+ self.datalab = None
101
+
102
+ def add_additional_buttons(self):
103
+ """Add additional buttons"""
104
+ add_btn = self.host.add_button
105
+ add_btn(_("Execute multiple commands"), self.exec_multiple_cmd, 10)
106
+ add_btn(_("Get object titles"), self.get_object_titles, 10)
107
+ add_btn(_("Get object uuids"), self.get_object_uuids, 10)
108
+ add_btn(_("Get object"), self.get_object)
109
+
110
+ @try_send_command()
111
+ def exec_multiple_cmd(self):
112
+ """Execute multiple commands in DataLab"""
113
+ if self.datalab is not None:
114
+ self.host.log("Starting command sequence...")
115
+ multiple_commands(self.datalab)
116
+ self.host.log("...end")
117
+
118
+ @try_send_command()
119
+ def get_object_titles(self):
120
+ """Get object (signal/image) titles for current panel"""
121
+ if self.datalab is not None:
122
+ self.host.log("Object titles:")
123
+ titles = self.datalab.get_object_titles()
124
+ if titles:
125
+ for name in titles:
126
+ self.host.log(f" {name}")
127
+ else:
128
+ self.host.log(" Empty.")
129
+
130
+ @try_send_command()
131
+ def get_object_uuids(self):
132
+ """Get object (signal/image) uuids for current panel"""
133
+ if self.datalab is not None:
134
+ self.host.log("Object uuids:")
135
+ uuids = self.datalab.get_object_uuids()
136
+ if uuids:
137
+ for uuid in uuids:
138
+ self.host.log(f" {uuid}")
139
+ else:
140
+ self.host.log(" Empty.")
141
+
142
+ @try_send_command()
143
+ def get_object(self):
144
+ """Get object (signal/image) at index for current panel"""
145
+ if self.datalab is not None:
146
+ titles = self.datalab.get_object_titles()
147
+ if titles:
148
+ obj = self.datalab.get_object()
149
+ if obj is not None:
150
+ self.host.log(f"Object '{obj.title}'")
151
+ self.host.log(str(obj))
152
+ else:
153
+ self.host.log("🏴‍☠️ Object is None! (no selection)")
154
+ else:
155
+ self.host.log("🏴‍☠️ Object list is empty!")
156
+
157
+ @try_send_command()
158
+ def add_object(self, obj):
159
+ """Add object to DataLab"""
160
+ super().add_object(obj)
161
+
162
+ @try_send_command()
163
+ def remove_all(self):
164
+ """Remove all objects from DataLab"""
165
+ if self.datalab is not None:
166
+ self.datalab.reset_all()
167
+ self.host.log("Removed all objects")
168
+
169
+
170
+ @contextmanager
171
+ def qt_wait_print(dt: float, message: str, parent=None):
172
+ """Wait and print message"""
173
+ qt_wait(dt, show_message=True, parent=parent)
174
+ execenv.print(f"{message}...", end="")
175
+ yield
176
+ execenv.print("OK")
177
+
178
+
179
+ def test_remote_client():
180
+ """Remote client application test"""
181
+ run_datalab_in_background()
182
+
183
+ with qt_app_context(exec_loop=True):
184
+ window = HostWindow()
185
+ window.resize(800, 800)
186
+ window.show()
187
+ dt = 1
188
+ if execenv.unattended:
189
+ qt_wait(8, show_message=True, parent=window)
190
+ window.init_cdl()
191
+ with qt_wait_print(dt, "Executing multiple commands"):
192
+ window.exec_multiple_cmd()
193
+ bring_to_front(window)
194
+ with qt_wait_print(dt, "Raising DataLab window"):
195
+ window.raise_cdl()
196
+ with qt_wait_print(dt, "Import macro"):
197
+ window.import_macro()
198
+ with qt_wait_print(dt, "Getting object titles"):
199
+ window.get_object_titles()
200
+ with qt_wait_print(dt, "Getting object uuids"):
201
+ window.get_object_uuids()
202
+ with qt_wait_print(dt, "Getting object"):
203
+ window.get_object()
204
+ with qt_wait_print(dt, "Adding signals"):
205
+ window.add_signals()
206
+ with qt_wait_print(dt, "Adding images"):
207
+ window.add_images()
208
+ with qt_wait_print(dt, "Run macro"):
209
+ window.run_macro()
210
+ with qt_wait_print(dt * 2, "Stop macro"):
211
+ window.stop_macro()
212
+ with qt_wait_print(dt, "Removing all objects"):
213
+ window.remove_all()
214
+ with qt_wait_print(dt, "Closing DataLab"):
215
+ window.close_datalab()
216
+
217
+
218
+ if __name__ == "__main__":
219
+ test_remote_client()
@@ -0,0 +1,75 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Remote client test
5
+ """
6
+
7
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
8
+ # pylint: disable=duplicate-code
9
+ # guitest: skip
10
+
11
+ import os
12
+ import os.path as osp
13
+ import time
14
+
15
+ import numpy as np
16
+ from guidata.qthelpers import qt_app_context
17
+ from plotpy.builder import make
18
+ from sigima.params import XYCalibrateParam
19
+ from sigima.tests.data import create_2d_gaussian, create_paracetamol_signal
20
+
21
+ from datalab import app
22
+ from datalab.control.proxy import RemoteProxy
23
+ from datalab.env import execenv
24
+ from datalab.tests import helpers
25
+
26
+
27
+ def multiple_commands(remote: RemoteProxy):
28
+ """Execute multiple XML-RPC commands"""
29
+ with helpers.WorkdirRestoringTempDir() as tmpdir:
30
+ x, y = create_paracetamol_signal().get_data()
31
+ remote.add_signal("tutu", x, y)
32
+
33
+ z = create_2d_gaussian(2000, np.uint16)
34
+ remote.add_image("toto", z)
35
+ rect = make.annotated_rectangle(100, 100, 200, 200, title="Test")
36
+ area = rect.get_rect()
37
+ remote.add_annotations_from_items([rect])
38
+ uuid = remote.get_sel_object_uuids()[0]
39
+ items = remote.get_object_shapes()
40
+ assert len(items) == 1 and items[0].get_rect() == area
41
+ remote.add_label_with_title(f"Image uuid: {uuid}")
42
+ remote.select_groups([1])
43
+ remote.select_objects([uuid])
44
+ remote.delete_metadata()
45
+
46
+ fname = osp.join(tmpdir, osp.basename("remote_test.h5"))
47
+ remote.save_to_h5_file(fname)
48
+ remote.reset_all()
49
+ remote.open_h5_files([fname], True, False)
50
+ remote.import_h5_file(fname, True)
51
+ remote.set_current_panel("signal")
52
+ assert remote.get_current_panel() == "signal"
53
+ remote.calc("log10")
54
+
55
+ param = XYCalibrateParam.create(a=1.2, b=0.1)
56
+ remote.calc("calibration", param)
57
+
58
+ time.sleep(2) # Avoid permission error when trying to clean-up temporary files
59
+
60
+
61
+ def test_remoteclient_unit():
62
+ """Remote client test"""
63
+ env = os.environ.copy()
64
+ env[execenv.DO_NOT_QUIT_ENV] = "1"
65
+ execenv.print("Launching DataLab in a separate process")
66
+ helpers.exec_script(app.__file__, wait=False, env=env)
67
+ remote = RemoteProxy()
68
+ execenv.print("Executing multiple commands...", end="")
69
+ with qt_app_context(): # needed for building plot items
70
+ multiple_commands(remote)
71
+ execenv.print("OK")
72
+
73
+
74
+ if __name__ == "__main__":
75
+ test_remoteclient_unit()