datalab-platform 0.0.1.dev0__py3-none-any.whl → 1.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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.1.dist-info/METADATA +121 -0
  490. datalab_platform-1.0.1.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.1.dist-info}/WHEEL +0 -0
  494. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.1.dist-info}/entry_points.txt +0 -0
  495. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.1.dist-info}/licenses/LICENSE +0 -0
  496. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,321 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Simple Remote client test
5
+ -------------------------
6
+
7
+ This test covers the simple remote client functionalities as provided by the
8
+ `sigima.client` module.
9
+
10
+ In Sigima, the `sigima.tests.common.client_unit_test` module provides a set of unit
11
+ tests for the client functionalities.
12
+
13
+ The purpose of these tests is to ensure that the client can correctly interact with
14
+ the real server, handling various scenarios and edge cases.
15
+
16
+ The tests include:
17
+
18
+ - A function comparing the list of methods implemented by the real server
19
+ (DataLab's `RemoteServer` class) to those implemented by the stub server
20
+ (Sigima's `DataLabStubServer` class).
21
+ - A function comparing the list of methods implemented by the full client (DataLab's
22
+ `RemoteProxy` class) to those implemented by the simple client (Sigima's
23
+ `SimpleRemoteProxy` class).
24
+ - A function that simply runs the `sigima.tests.common.client_unit_test` suite after
25
+ having launched a real server instance (DataLab application, using the
26
+ `datalab.tests.run_datalab_in_background` function), ensuring that this test passes
27
+ with the stub server as well as with the real server.
28
+ """
29
+
30
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
31
+ # guitest: skip
32
+
33
+ import inspect
34
+ import warnings
35
+
36
+ from guidata.env import execenv
37
+ from packaging.version import Version
38
+ from sigima.client.remote import SimpleRemoteProxy, __required_server_version__
39
+ from sigima.client.stub import DataLabStubServer
40
+ from sigima.tests.common.client_unit_test import RemoteClientTester
41
+
42
+ import datalab
43
+ from datalab.control.baseproxy import AbstractDLControl
44
+ from datalab.control.proxy import RemoteProxy
45
+ from datalab.tests import run_datalab_in_background
46
+
47
+
48
+ def test_compare_server_methods() -> None:
49
+ """Compare methods implemented by RemoteServer vs DataLabStubServer.
50
+
51
+ This function compares the list of methods implemented by the real server
52
+ (DataLab's RemoteServer class) to those implemented by the stub server
53
+ (Sigima's DataLabStubServer class).
54
+ """
55
+ execenv.print("\n=== Comparing Server Methods ===")
56
+
57
+ # Get methods from RemoteServer (the real DataLab server)
58
+ # RemoteServer implements AbstractDLControl methods
59
+ remote_server_methods = set(AbstractDLControl.get_public_methods())
60
+
61
+ # Get methods from DataLabStubServer (the stub server)
62
+ stub_server_methods = {
63
+ name
64
+ for name, method in inspect.getmembers(DataLabStubServer, inspect.isfunction)
65
+ if not name.startswith("_")
66
+ }
67
+
68
+ execenv.print(f"RemoteServer methods: {len(remote_server_methods)}")
69
+ execenv.print(f"DataLabStubServer methods: {len(stub_server_methods)}")
70
+
71
+ # Methods in RemoteServer but not in DataLabStubServer
72
+ missing_in_stub = remote_server_methods - stub_server_methods
73
+ if missing_in_stub:
74
+ execenv.print("\n⚠️ Methods in RemoteServer but missing in DataLabStubServer:")
75
+ for method in sorted(missing_in_stub):
76
+ execenv.print(f" - {method}")
77
+
78
+ # Methods in DataLabStubServer but not in RemoteServer
79
+ extra_in_stub = stub_server_methods - remote_server_methods
80
+ if extra_in_stub:
81
+ execenv.print("\n🔍 Methods in DataLabStubServer but not in RemoteServer:")
82
+ for method in sorted(extra_in_stub):
83
+ execenv.print(f" - {method}")
84
+
85
+ # Common methods
86
+ common_methods = remote_server_methods & stub_server_methods
87
+ execenv.print(f"\n✅ Common methods: {len(common_methods)}")
88
+
89
+ # Assert that stub server implements all required methods
90
+ assert not missing_in_stub, (
91
+ f"DataLabStubServer is missing {len(missing_in_stub)} methods "
92
+ f"implemented by RemoteServer: {sorted(missing_in_stub)}"
93
+ )
94
+
95
+ execenv.print("✨ Server method comparison completed successfully!")
96
+
97
+
98
+ def test_compare_client_methods() -> None:
99
+ """Compare methods implemented by RemoteProxy vs SimpleRemoteProxy.
100
+
101
+ This function compares the list of methods implemented by the full client
102
+ (DataLab's RemoteProxy class) to those implemented by the simple client
103
+ (Sigima's SimpleRemoteProxy class).
104
+ """
105
+ execenv.print("\n=== Comparing Client Methods ===")
106
+
107
+ # Get public methods from RemoteProxy (the full client)
108
+ remote_proxy_methods = {
109
+ name
110
+ for name, method in inspect.getmembers(RemoteProxy, inspect.ismethod)
111
+ if not name.startswith("_") and callable(method)
112
+ }
113
+
114
+ # Get public methods from SimpleRemoteProxy (the simple client)
115
+ simple_proxy_methods = {
116
+ name
117
+ for name, method in inspect.getmembers(SimpleRemoteProxy, inspect.ismethod)
118
+ if not name.startswith("_") and callable(method)
119
+ }
120
+
121
+ execenv.print(f"RemoteProxy methods: {len(remote_proxy_methods)}")
122
+ execenv.print(f"SimpleRemoteProxy methods: {len(simple_proxy_methods)}")
123
+
124
+ # Methods in SimpleRemoteProxy but not in RemoteProxy
125
+ extra_in_simple = simple_proxy_methods - remote_proxy_methods
126
+ if extra_in_simple:
127
+ execenv.print(
128
+ "\n🔍 Methods in SimpleRemoteProxy but not in RemoteProxy "
129
+ "(expected, as SimpleRemoteProxy is a subset):"
130
+ )
131
+ for method in sorted(extra_in_simple):
132
+ execenv.print(f" - {method}")
133
+
134
+ # Methods in RemoteProxy but not in SimpleRemoteProxy
135
+ missing_in_simple = remote_proxy_methods - simple_proxy_methods
136
+ if missing_in_simple:
137
+ execenv.print(
138
+ "\n📝 Methods in RemoteProxy but not in SimpleRemoteProxy "
139
+ "(expected, as SimpleRemoteProxy is simpler):"
140
+ )
141
+ for method in sorted(missing_in_simple):
142
+ execenv.print(f" - {method}")
143
+
144
+ # Common methods
145
+ common_methods = remote_proxy_methods & simple_proxy_methods
146
+ execenv.print(f"\n✅ Common methods: {len(common_methods)}")
147
+
148
+ execenv.print("✨ Client method comparison completed successfully!")
149
+
150
+
151
+ def test_with_real_server() -> None:
152
+ """Run sigima.tests.common.client_unit_test suite with real DataLab server.
153
+
154
+ This function runs the comprehensive client unit test suite after launching
155
+ a real DataLab instance in the background, ensuring that the tests pass
156
+ with the real server.
157
+ """
158
+ execenv.print("\n=== Testing with Real DataLab Server ===")
159
+
160
+ # Launch DataLab application in the background
161
+ execenv.print("Launching DataLab in background...")
162
+ run_datalab_in_background(wait_until_ready=True)
163
+
164
+ # Import and run the comprehensive test from sigima
165
+ execenv.print("Running comprehensive client tests with real server...")
166
+ tester = RemoteClientTester()
167
+
168
+ # Initialize connection to real DataLab server using the existing port
169
+ if not tester.init_cdl():
170
+ raise ConnectionRefusedError(
171
+ "Failed to connect to DataLab server. "
172
+ "Make sure DataLab is running and accessible."
173
+ )
174
+
175
+ try:
176
+ # Run all tests
177
+ tester.run_comprehensive_test()
178
+ execenv.print("✨ All tests passed with real DataLab server!")
179
+ finally:
180
+ # Clean up
181
+ tester.close_datalab()
182
+
183
+
184
+ def test_version_compatibility() -> None:
185
+ """Test that DataLab version is compatible with Sigima client.
186
+
187
+ This test ensures that the current version of DataLab meets the minimum
188
+ requirements of the Sigima client as defined in __required_server_version__.
189
+ """
190
+ execenv.print("\n=== Testing Version Compatibility ===")
191
+
192
+ # Get DataLab version
193
+ datalab_version = datalab.__version__
194
+ execenv.print(f"DataLab version: {datalab_version}")
195
+ execenv.print(f"Required version: {__required_server_version__}")
196
+
197
+ # Test version comparison using Version class with edge cases
198
+ execenv.print("\nTesting Version comparison:")
199
+ test_cases = [
200
+ ("1.0.0", "1.0.0", True, "Same version"),
201
+ ("1.0.1", "1.0.0", True, "Newer patch version"),
202
+ ("1.1.0", "1.0.0", True, "Newer minor version"),
203
+ ("2.0.0", "1.0.0", True, "Newer major version"),
204
+ ("0.9.9", "1.0.0", False, "Older version"),
205
+ ("1.0.0a1", "1.0.0", False, "Alpha is pre-release (< 1.0.0)"),
206
+ ("1.0.0b2", "1.0.0", False, "Beta is pre-release (< 1.0.0)"),
207
+ ("1.0.0rc1", "1.0.0", False, "RC is pre-release (< 1.0.0)"),
208
+ ("1.0.0", "1.0.0a1", True, "Release is newer than alpha"),
209
+ ("1.0.1", "1.0.0a1", True, "Newer patch > alpha"),
210
+ ("1.0.0a10", "1.0.0a2", True, "Later alpha version"),
211
+ ]
212
+
213
+ for ver1, ver2, expected, description in test_cases:
214
+ result = Version(ver1) >= Version(ver2)
215
+ status = "✓" if result == expected else "✗"
216
+ execenv.print(
217
+ f" {status} Version('{ver1}') >= Version('{ver2}') = {result} "
218
+ f"[expected: {expected}] - {description}"
219
+ )
220
+ assert result == expected, (
221
+ f"Version comparison failed for {ver1} vs {ver2}: "
222
+ f"expected {expected}, got {result}"
223
+ )
224
+
225
+ # Check if current DataLab version is compatible
226
+ execenv.print(f"\nChecking DataLab {datalab_version} compatibility...")
227
+ is_compatible = Version(datalab_version) >= Version(__required_server_version__)
228
+
229
+ if is_compatible:
230
+ execenv.print(
231
+ f"✅ DataLab version {datalab_version} is compatible "
232
+ f"(>= {__required_server_version__})"
233
+ )
234
+ else:
235
+ execenv.print(
236
+ f"⚠️ DataLab version {datalab_version} is NOT compatible "
237
+ f"(< {__required_server_version__})"
238
+ )
239
+
240
+ # Note: During development (alpha/beta/rc versions), we allow the test to pass
241
+ # even if the version comparison indicates incompatibility. In production,
242
+ # both DataLab and Sigima should be at release versions.
243
+ vdatalab = Version(datalab_version)
244
+
245
+ # Allow pre-release versions if they're the same base version
246
+ if vdatalab.is_prerelease and not is_compatible:
247
+ # Check if the base version (without pre-release) would be compatible
248
+ base_ver = f"{vdatalab.major}.{vdatalab.minor}.{vdatalab.micro}"
249
+ if Version(base_ver) >= Version(__required_server_version__):
250
+ execenv.print(
251
+ f"ℹ️ Pre-release version {datalab_version} allowed for testing "
252
+ f"(base version {base_ver} >= {__required_server_version__})"
253
+ )
254
+ is_compatible = True
255
+
256
+ # This assertion ensures DataLab's version meets Sigima's requirements
257
+ assert is_compatible, (
258
+ f"DataLab version {datalab_version} is not compatible with "
259
+ f"Sigima client requirements (>= {__required_server_version__}). "
260
+ f"Please upgrade DataLab or downgrade the required version in Sigima."
261
+ )
262
+
263
+ # Test that warning is issued when connecting to incompatible version
264
+ execenv.print("\nTesting version compatibility warning with stub server...")
265
+ with warnings.catch_warnings(record=True) as w:
266
+ warnings.simplefilter("always")
267
+
268
+ # Create a stub server that reports an old version
269
+ stub = DataLabStubServer(port=0, verbose=False)
270
+ # Temporarily patch get_version to return an old version
271
+ original_get_version = stub.get_version
272
+
273
+ def mock_old_version():
274
+ return "0.9.0" # Old version that should trigger warning
275
+
276
+ stub.get_version = mock_old_version
277
+
278
+ try:
279
+ port = stub.start()
280
+
281
+ # Try to connect - should trigger warning
282
+ proxy = SimpleRemoteProxy(autoconnect=False)
283
+ proxy.connect(port=str(port))
284
+
285
+ # Check that a warning was issued
286
+ version_warnings = [
287
+ warning
288
+ for warning in w
289
+ if "may not be fully compatible" in str(warning.message)
290
+ ]
291
+
292
+ if version_warnings:
293
+ execenv.print(
294
+ f"✅ Warning correctly issued for incompatible version: "
295
+ f"{version_warnings[0].message}"
296
+ )
297
+ else:
298
+ execenv.print("⚠️ No warning issued for incompatible version")
299
+ # Print all warnings for debugging
300
+ if w:
301
+ execenv.print(f" All warnings captured ({len(w)}):")
302
+ for warning in w:
303
+ execenv.print(f" - {warning.message}")
304
+
305
+ assert len(version_warnings) > 0, (
306
+ "Expected warning for incompatible version but none was issued"
307
+ )
308
+
309
+ finally:
310
+ # Restore original method and stop server
311
+ stub.get_version = original_get_version
312
+ stub.stop()
313
+
314
+ execenv.print("✨ Version compatibility test completed successfully!")
315
+
316
+
317
+ if __name__ == "__main__":
318
+ test_compare_server_methods()
319
+ test_compare_client_methods()
320
+ test_version_compatibility()
321
+ test_with_real_server()
@@ -0,0 +1 @@
1
+ #
@@ -0,0 +1,31 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ HDF5 browser unit tests 1
5
+ -------------------------
6
+
7
+ Try and open all HDF5 test data available.
8
+ """
9
+
10
+ # guitest: show
11
+
12
+ from __future__ import annotations
13
+
14
+ from guidata.qthelpers import exec_dialog, qt_app_context
15
+
16
+ from datalab.tests import helpers
17
+ from datalab.tests.features.hdf5.h5browser_app_test import create_h5browser_dialog
18
+
19
+
20
+ def test_h5browser_all_files(pattern=None):
21
+ """HDF5 browser unit test for all available .h5 test files"""
22
+ with qt_app_context():
23
+ fnames = helpers.get_test_fnames("*.h5" if pattern is None else pattern)
24
+ for index, fname in enumerate(fnames):
25
+ dlg = create_h5browser_dialog([fname], toggle_all=True, select_all=True)
26
+ dlg.setObjectName(dlg.objectName() + f"_{index:02d}")
27
+ exec_dialog(dlg)
28
+
29
+
30
+ if __name__ == "__main__":
31
+ test_h5browser_all_files()
@@ -0,0 +1,55 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ HDF5 browser unit tests 2
5
+ -------------------------
6
+
7
+ Testing for memory leak
8
+ """
9
+
10
+ # guitest: show,skip
11
+
12
+ import os
13
+ import time
14
+
15
+ import numpy as np
16
+ import psutil
17
+ from guidata.qthelpers import qt_app_context
18
+ from sigima.tests.vistools import view_curves
19
+
20
+ from datalab.env import execenv
21
+ from datalab.tests import helpers
22
+ from datalab.widgets.h5browser import H5BrowserDialog
23
+
24
+
25
+ def test_memoryleak(fname, iterations=20):
26
+ """Memory leak test"""
27
+ with qt_app_context():
28
+ proc = psutil.Process(os.getpid())
29
+ fname = helpers.get_test_fnames(fname)[0]
30
+ dlg = H5BrowserDialog(None)
31
+ memlist = []
32
+ for i in range(iterations):
33
+ t0 = time.time()
34
+ dlg.open_file(fname)
35
+ memdata = proc.memory_info().vms / 1024**2
36
+ memlist.append(memdata)
37
+ execenv.print(i + 1, ":", memdata, "MB")
38
+ dlg.browser.tree.select_all(True)
39
+ dlg.browser.tree.toggle_all(True)
40
+ execenv.print(i + 1, ":", proc.memory_info().vms / 1024**2, "MB")
41
+ dlg.show()
42
+ dlg.accept()
43
+ dlg.close()
44
+ execenv.print(i + 1, ":", proc.memory_info().vms / 1024**2, "MB")
45
+ dlg.cleanup()
46
+ execenv.print(i + 1, ":", f"{(time.time() - t0):.1f} s")
47
+ view_curves(
48
+ np.array(memlist),
49
+ title="Memory leak test for HDF5 browser dialog",
50
+ ylabel="Memory (MB)",
51
+ )
52
+
53
+
54
+ if __name__ == "__main__":
55
+ test_memoryleak("scenario*.h5")
@@ -0,0 +1,77 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ HDF5 Browser Application test
5
+ -----------------------------
6
+
7
+
8
+ """
9
+
10
+ # guitest: show
11
+
12
+ from __future__ import annotations
13
+
14
+ from guidata.qthelpers import exec_dialog, qt_app_context
15
+ from qtpy import QtWidgets as QW
16
+
17
+ from datalab.env import execenv
18
+ from datalab.tests import helpers
19
+ from datalab.widgets.h5browser import H5BrowserDialog
20
+
21
+
22
+ def create_h5browser_dialog(
23
+ fnames: list[str], toggle_all: bool = False, select_all: bool = False
24
+ ) -> H5BrowserDialog:
25
+ """Create HDF5 browser dialog with all nodes expanded and selected
26
+
27
+ Args:
28
+ fnames: HDF5 file names
29
+
30
+ Returns:
31
+ H5BrowserDialog instance
32
+ """
33
+ execenv.print(f"Opening: {fnames}")
34
+ dlg = H5BrowserDialog(None)
35
+ dlg.open_files(fnames)
36
+ dlg.browser.tree.toggle_all(toggle_all)
37
+ dlg.browser.tree.select_all(select_all)
38
+ return dlg
39
+
40
+
41
+ def test_h5browser() -> None:
42
+ """Test HDF5 browser"""
43
+ fnames = helpers.get_test_fnames("*.h5")[-2:]
44
+ with qt_app_context():
45
+ dlg = create_h5browser_dialog(fnames)
46
+
47
+ if execenv.unattended:
48
+ # Test all buttons:
49
+ dlg.show()
50
+ for index in range(dlg.button_layout.count()):
51
+ widget = dlg.button_layout.itemAt(index).widget()
52
+ if isinstance(widget, QW.QCheckBox):
53
+ widget.setChecked(True)
54
+ widget.setChecked(False)
55
+ elif isinstance(widget, QW.QPushButton):
56
+ widget.click()
57
+
58
+ # Test various features:
59
+ tree = dlg.browser.tree
60
+ tree.update_menu()
61
+ tree.expandAll()
62
+ tree.collapseAll()
63
+ tree.restore()
64
+
65
+ # Removing file, adding file from browser:
66
+ dlg.browser.close_file(fnames[0])
67
+ dlg.browser.open_file(fnames[0])
68
+
69
+ # Removing file, adding file from file selector:
70
+ dlg.browser.selector.remove_file(fnames[0])
71
+ dlg.browser.selector.add_file(fnames[0])
72
+
73
+ exec_dialog(dlg)
74
+
75
+
76
+ if __name__ == "__main__":
77
+ test_h5browser()
@@ -0,0 +1,25 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ HDF5 import application test
5
+ """
6
+
7
+ # guitest: show
8
+
9
+ from datalab import app
10
+ from datalab.env import execenv
11
+ from datalab.tests import helpers
12
+ from datalab.utils.qthelpers import datalab_app_context
13
+
14
+
15
+ def test_hdf5_import():
16
+ """Testing DataLab app launcher"""
17
+ with datalab_app_context(exec_loop=True):
18
+ win = app.create(console=False)
19
+ fname = helpers.get_test_fnames("*.h5")[-1]
20
+ execenv.print(f"Importing HDF5 file: {fname}")
21
+ win.import_h5_file(fname)
22
+
23
+
24
+ if __name__ == "__main__":
25
+ test_hdf5_import()
@@ -0,0 +1,34 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ HDF5 Importer Application test
5
+ ------------------------------
6
+
7
+ Running application a few times in a row with different entry parameters.
8
+ """
9
+
10
+ # guitest: show
11
+
12
+ from datalab import app
13
+ from datalab.env import execenv
14
+ from datalab.tests import helpers
15
+ from datalab.utils.qthelpers import datalab_app_context
16
+
17
+
18
+ def test_h5importer_app(pattern=None):
19
+ """Testing DataLab app launcher"""
20
+ if pattern is None:
21
+ pattern = "*.h5"
22
+ execenv.print("HDF5 import test scenario:")
23
+ execenv.print("[1] Loading all h5 files at once (only the first 5 files)")
24
+ with datalab_app_context(exec_loop=True):
25
+ app.create(h5files=helpers.get_test_fnames(pattern)[:5])
26
+ execenv.print("[2] Loading h5 files one by one")
27
+ for fname in helpers.get_test_fnames(pattern):
28
+ with datalab_app_context(exec_loop=True):
29
+ execenv.print(f" Opening: {fname}")
30
+ app.create(h5files=[fname])
31
+
32
+
33
+ if __name__ == "__main__":
34
+ test_h5importer_app()
@@ -0,0 +1 @@
1
+ #
@@ -0,0 +1,28 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Annotations application test:
5
+
6
+ - Create an image with annotations and ROI
7
+ - Further tests to be done manually: edit "Annotations" and check that
8
+ modifications are taken into account, without affecting the existing ROI
9
+ """
10
+
11
+ # guitest: show
12
+
13
+ from sigima.objects import create_image_roi
14
+ from sigima.tests import data as test_data
15
+
16
+ from datalab.app import run
17
+
18
+
19
+ def test_annotations_app():
20
+ """Annotations test"""
21
+ obj1 = test_data.create_sincos_image()
22
+ obj2 = test_data.create_annotated_image()
23
+ obj2.roi = create_image_roi("rectangle", [10, 10, 60, 400])
24
+ run(console=False, objects=(obj1, obj2), size=(1200, 550))
25
+
26
+
27
+ if __name__ == "__main__":
28
+ test_annotations_app()
@@ -0,0 +1,80 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Annotations unit test:
5
+
6
+ - Create an image with annotations
7
+ - Open dialog (equivalent to click on button "Annotations")
8
+ - Accept dialog without modifying shapes
9
+ - Check if image annotations are still the same
10
+ """
11
+
12
+ # guitest: show
13
+
14
+ from plotpy.builder import make
15
+ from plotpy.items import AnnotatedShape, PolygonShape
16
+ from plotpy.plot import BasePlot
17
+ from qtpy import QtWidgets as QW
18
+ from sigima.tests import data as test_data
19
+
20
+ from datalab.adapters_plotpy import create_adapter_from_object
21
+ from datalab.env import execenv
22
+ from datalab.tests import datalab_test_app_context
23
+
24
+
25
+ def set_annotation_color(annotation: AnnotatedShape, color: str) -> None:
26
+ """Set annotation color"""
27
+ shape: PolygonShape = annotation.shape
28
+ param = shape.shapeparam
29
+ param.line.color = param.fill.color = color
30
+ param.fill.alpha = 0.3
31
+ param.fill.style = "SolidPattern"
32
+ param.update_item(shape)
33
+ plot: BasePlot = annotation.plot()
34
+ if plot is not None:
35
+ plot.replot()
36
+
37
+
38
+ def test_annotations_unit():
39
+ """Run image tools test scenario"""
40
+ with datalab_test_app_context() as win:
41
+ panel = win.imagepanel
42
+
43
+ # Create image with annotations
44
+ ima1 = test_data.create_multigaussian_image()
45
+ ima1.title = "Annotations from items"
46
+ rect = make.annotated_rectangle(100, 100, 200, 200, title="Test")
47
+ set_annotation_color(rect, "#2222ff")
48
+ circ = make.annotated_circle(300, 300, 400, 400, title="Test")
49
+ set_annotation_color(circ, "#22ff22")
50
+ elli = make.annotated_ellipse(
51
+ 500, 500, 800, 500, 650, 400, 650, 600, title="Test"
52
+ )
53
+ segm = make.annotated_segment(700, 700, 800, 800, title="Test")
54
+ label = make.label("Test", (1000, 1000), (0, 0), "BR")
55
+ adapter = create_adapter_from_object(ima1)
56
+ adapter.add_annotations_from_items([rect, circ, elli, segm, label])
57
+ panel.add_object(ima1)
58
+
59
+ # Create another image with annotations
60
+ ima2 = test_data.create_annotated_image(title="Annotations from JSON")
61
+ panel.add_object(ima2)
62
+
63
+ execenv.print("Check [geometric shapes] <--> [plot items] conversion:")
64
+ execenv.print("(comparing annotations)")
65
+ for ima in (ima1, ima2):
66
+ execenv.print(f" Checking image '{ima.title}': ", end="")
67
+ panel.objview.select_objects([ima])
68
+ # Open separate view
69
+ panel.open_separate_view().done(QW.QDialog.DialogCode.Accepted)
70
+ orig_ann = ima.annotations
71
+ panel.open_separate_view().done(QW.QDialog.DialogCode.Accepted)
72
+ # Check if annotations are still the same
73
+ # open("before.json", mode="wb").write(orig_ann.encode())
74
+ # open("after.json", mode="wb").write(ima.annotations.encode())
75
+ assert orig_ann == ima.annotations
76
+ execenv.print("OK")
77
+
78
+
79
+ if __name__ == "__main__":
80
+ test_annotations_unit()