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,75 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ I/O application test:
5
+
6
+ - Testing signals I/O
7
+ - Testing images I/O
8
+ """
9
+
10
+ # guitest: show
11
+
12
+ from __future__ import annotations
13
+
14
+ import os.path as osp
15
+
16
+ from sigima.io.base import IOAction
17
+ from sigima.io.image import ImageIORegistry
18
+ from sigima.io.signal import SignalIORegistry
19
+
20
+ from datalab.env import execenv
21
+ from datalab.gui.panel.base import BaseDataPanel
22
+ from datalab.tests import datalab_test_app_context, helpers
23
+
24
+
25
+ def __testfunc(
26
+ title: str,
27
+ panel: BaseDataPanel,
28
+ registry: SignalIORegistry | ImageIORegistry,
29
+ pattern: str,
30
+ in_folder: str,
31
+ ) -> None:
32
+ """Test I/O features"""
33
+ execenv.print(f" {title}:")
34
+ with helpers.WorkdirRestoringTempDir() as tmpdir:
35
+ # os.startfile(tmpdir)
36
+ fnames = helpers.get_test_fnames(pattern, in_folder)
37
+ execenv.print(" Opening:")
38
+ # TODO: [P3] This test does not support formats that return multiple objects
39
+ # (e.g. SIF files with multiple images). As a consequence, it will not test
40
+ # thoroughly the I/O functionalities for these formats (it will keep only the
41
+ # first object in the list of returned objects)
42
+ objs = []
43
+ for fname in fnames:
44
+ execenv.print(f" {fname}: ", end="")
45
+ try:
46
+ registry.get_format(fname, IOAction.LOAD)
47
+ except NotImplementedError:
48
+ execenv.print("Skipped (not supported)")
49
+ continue
50
+ objs.append(panel.load_from_files([fname])[0])
51
+ execenv.print("OK")
52
+ execenv.print(" Saving:")
53
+ for fname, obj in zip(fnames, objs):
54
+ panel.objview.set_current_object(obj)
55
+ path = osp.join(tmpdir, osp.basename(fname))
56
+ execenv.print(f" {path}: ", end="")
57
+ try:
58
+ registry.get_format(fname, IOAction.SAVE)
59
+ except NotImplementedError:
60
+ execenv.print("Skipped (not supported)")
61
+ continue
62
+ panel.save_to_files([path])
63
+ execenv.print("OK")
64
+
65
+
66
+ def test_io_app() -> None:
67
+ """Run image tools test scenario"""
68
+ with datalab_test_app_context() as win:
69
+ execenv.print("I/O application test:")
70
+ __testfunc("Signals", win.signalpanel, SignalIORegistry, "*.*", "curve_formats")
71
+ __testfunc("Images", win.imagepanel, ImageIORegistry, "*.*", "image_formats")
72
+
73
+
74
+ if __name__ == "__main__":
75
+ test_io_app()
@@ -0,0 +1,187 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Large Results Application Test Module
5
+
6
+ This module contains tests for verifying that DataLab handles large result datasets
7
+ efficiently and correctly.
8
+ """
9
+
10
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
11
+ # guitest: show,skip
12
+
13
+ import time
14
+
15
+ import numpy as np
16
+ import sigima.enums
17
+ import sigima.objects
18
+ import sigima.params as sigima_param
19
+ from sigima.tests.data import get_test_image
20
+
21
+ from datalab.adapters_metadata.geometry_adapter import GeometryAdapter
22
+ from datalab.config import Conf
23
+ from datalab.tests import datalab_test_app_context
24
+
25
+
26
+ def create_polygon_vertices(
27
+ x0: float, y0: float, nb_points: int, radius_mean: float, radius_variation: float
28
+ ) -> list[tuple[float, float]]:
29
+ """Generate points for a polygon around (x0, y0)
30
+
31
+ Args:
32
+ x0: x coordinate of the polygon center
33
+ y0: y coordinate of the polygon center
34
+ nb_points: number of points to generate
35
+ radius_mean: mean radius of the polygon
36
+ radius_variation: variation in radius
37
+
38
+ Returns:
39
+ List of (x, y) points representing the polygon vertices
40
+ """
41
+ points = []
42
+ # Calculate number of NaNs to append (random numbers between 0 and nb_points-10):
43
+ num_nans = np.random.randint(0, nb_points - 10)
44
+ for j in range(nb_points - num_nans):
45
+ angle = j * (2 * np.pi / (nb_points - num_nans))
46
+ radius = radius_mean + radius_variation * np.random.rand()
47
+ x = x0 + radius * np.cos(angle)
48
+ y = y0 + radius * np.sin(angle)
49
+ points.append((x, y))
50
+ for _ in range(num_nans):
51
+ points.append((np.nan, np.nan))
52
+ return points
53
+
54
+
55
+ def create_random_polygons(
56
+ size: int, nb_polygons: int, nb_points_per_polygon: int
57
+ ) -> np.ndarray:
58
+ """Create random polygons
59
+
60
+ Args:
61
+ size: size of the area in which to create polygons
62
+ nb_polygons: number of polygons to create
63
+ nb_points_per_polygon: number of points per polygon
64
+
65
+ Returns:
66
+ Array of shape (nb_polygons, nb_points_per_polygon, 2)
67
+ """
68
+ polygons = []
69
+ for _ in range(nb_polygons):
70
+ x0 = size * np.random.rand()
71
+ y0 = size * np.random.rand()
72
+ points = create_polygon_vertices(
73
+ x0, y0, nb_points_per_polygon, radius_mean=20, radius_variation=30
74
+ )
75
+ # Append the flattened points:
76
+ polygons.append(points)
77
+ return np.array(polygons)
78
+
79
+
80
+ def test_large_results_scenario(measure_execution_time: bool = False) -> None:
81
+ """Test scenario to verify result truncation limits work correctly
82
+
83
+ Args:
84
+ measure_execution_time: if True, measure and print the execution time, then
85
+ quit immediately
86
+
87
+ This scenario tests:
88
+ - Contour detection on flower.npy (generates many contours)
89
+ - Shape drawing truncation at max_shapes_to_draw limit
90
+ - Label display truncation at max_cells_in_label limit
91
+ - Performance with large polygons (many points per polygon)
92
+
93
+ Performance benchmark (15 polygons × 5000 points):
94
+ - Pure PlotPy: ~473ms (baseline for drawing shapes only)
95
+ - DataLab: ~254ms (includes shape drawing + HTML label generation)
96
+ - Note: DataLab is faster due to optimized HTML truncation before formatting
97
+ """
98
+ nb_polygons = 15
99
+ nb_points_per_polygon = 5000
100
+
101
+ with datalab_test_app_context(
102
+ console=False, exec_loop=not measure_execution_time
103
+ ) as win:
104
+ # Create an image panel
105
+ panel = win.imagepanel
106
+
107
+ # Load the flower test image
108
+ ima = get_test_image("flower.npy")
109
+ ima.title = "Test image 'flower.npy' - Contour Detection Limit Test"
110
+ panel.add_object(ima)
111
+
112
+ # Apply Roberts filter for edge detection
113
+ panel.processor.run_feature("roberts")
114
+
115
+ # Run contour detection which should produce a large set of results
116
+ param = sigima_param.ContourShapeParam()
117
+ param.shape = sigima.enums.ContourShape.POLYGON
118
+ with Conf.proc.show_result_dialog.temp(False):
119
+ panel.processor.run_feature("contour_shape", param)
120
+
121
+ # Create geometry results manually using many polygons (we generate results
122
+ # in a manner that should be similar to what contour detection would typically
123
+ # produce but in a way that we can control precisely here)
124
+ vertices = create_random_polygons(
125
+ size=ima.data.shape[0],
126
+ nb_polygons=nb_polygons,
127
+ nb_points_per_polygon=nb_points_per_polygon,
128
+ )
129
+ geom_result = sigima.objects.GeometryResult(
130
+ title="Polygon",
131
+ kind=sigima.objects.KindShape.POLYGON,
132
+ coords=vertices.reshape(-1, nb_points_per_polygon * 2),
133
+ func_name="contour_detection_test",
134
+ )
135
+ geom_adapter = GeometryAdapter(geom_result)
136
+
137
+ ima2 = ima.copy()
138
+ geom_adapter.add_to(ima2)
139
+ panel.add_object(ima2)
140
+
141
+ if measure_execution_time:
142
+ # Now measure the execution time of switching selection between
143
+ # the 3 images:
144
+ # Image #1: flower.npy, as loaded
145
+ # Image #2: Image #1 after Roberts filter + contour detection
146
+ # Image #3: Image #1 with manually added large polygon result
147
+ print("\nMeasuring image switch timings...")
148
+ image_switch_times = {}
149
+ for _j in range(2): # Doing multiple iterations to stabilize timings
150
+ panel.objview.select_objects([1])
151
+ for i in range(2, 4):
152
+ start_time = time.perf_counter()
153
+ panel.objview.select_objects([i])
154
+ elapsed_time = (time.perf_counter() - start_time) * 1000 # in ms
155
+ image_switch_times.setdefault(i, []).append(elapsed_time)
156
+ print(f" - Switch to image #{i}: {elapsed_time:.1f} ms")
157
+ print("\nImage switch timings (ms):")
158
+ for i in range(2, 4):
159
+ times = image_switch_times[i]
160
+ avg_time = sum(times) / len(times)
161
+ print(
162
+ f" - Switching to image #{i}: avg {avg_time:.1f} ms "
163
+ f"over {len(times)} runs"
164
+ )
165
+
166
+ # Measure execution time of manual refresh of the image view:
167
+ print("\nMeasuring image view refresh timings...")
168
+ image_refresh_times = {}
169
+ for i in range(3, 4):
170
+ panel.objview.select_objects([i])
171
+ for _j in range(5): # Doing multiple iterations to stabilize timings
172
+ start_time = time.perf_counter()
173
+ panel.manual_refresh()
174
+ elapsed_time = (time.perf_counter() - start_time) * 1000 # in ms
175
+ image_refresh_times.setdefault(i, []).append(elapsed_time)
176
+ print(f" - Manual refresh: {elapsed_time:.1f} ms")
177
+ print("\nImage view refresh timings (ms):")
178
+ for i in range(3, 4):
179
+ times = image_refresh_times[i]
180
+ avg_time = sum(times) / len(times)
181
+ print(
182
+ f" - Manual refresh: avg {avg_time:.1f} ms over {len(times)} runs"
183
+ )
184
+
185
+
186
+ if __name__ == "__main__":
187
+ test_large_results_scenario(measure_execution_time=False)
@@ -0,0 +1,103 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Processing metadata storage tests
5
+
6
+ Tests that ALL processing patterns (1-to-1, 2-to-1, n-to-1) correctly
7
+ store metadata in object metadata options, regardless of whether they
8
+ support interactive re-processing.
9
+
10
+ This is an integration test that verifies the metadata storage infrastructure
11
+ works correctly across all computation patterns.
12
+
13
+ Note: interactive_processing_test.py tests the interactive re-processing UI feature.
14
+ """
15
+
16
+ # guitest: show
17
+
18
+ import guidata.dataset as gds
19
+ from guidata.qthelpers import qt_app_context
20
+ from sigima.proc.signal.filtering import GaussianParam
21
+
22
+ from datalab.gui.processor.base import PROCESSING_PARAMETERS_OPTION
23
+ from datalab.objectmodel import get_uuid
24
+ from datalab.tests import datalab_test_app_context
25
+
26
+
27
+ def test_metadata_all_patterns():
28
+ """Test that metadata is stored for all processing patterns."""
29
+ with qt_app_context():
30
+ with datalab_test_app_context() as win:
31
+ # Get panels
32
+ sig_panel = win.signalpanel
33
+ img_panel = win.imagepanel
34
+
35
+ # === Test 1: 1-to-1 pattern (with parameters) ===
36
+ sig_panel.new_object()
37
+ sig1 = sig_panel.objmodel.get_all_objects()[-1]
38
+
39
+ param = GaussianParam.create(sigma=2.0)
40
+ sig_panel.processor.compute_1_to_1(
41
+ sig_panel.processor.get_feature("gaussian_filter").function,
42
+ param=param,
43
+ title="Gaussian filter",
44
+ )
45
+ filtered_sig = sig_panel.objmodel.get_all_objects()[-1]
46
+
47
+ # Check metadata contains all keys including pattern type
48
+ assert PROCESSING_PARAMETERS_OPTION in filtered_sig.get_metadata_options()
49
+ option_dict = filtered_sig.get_metadata_option(PROCESSING_PARAMETERS_OPTION)
50
+ assert option_dict["func_name"] == "gaussian_filter"
51
+ assert option_dict["pattern"] == "1-to-1"
52
+ assert option_dict["source_uuid"] == get_uuid(sig1)
53
+ assert option_dict["param_json"] == gds.dataset_to_json(param)
54
+
55
+ # === Test 2: 2-to-1 pattern (single operand) ===
56
+ sig_panel.new_object()
57
+ sig2 = sig_panel.objmodel.get_all_objects()[-1]
58
+ sig_panel.objview.select_objects([sig1]) # Select only sig1
59
+ sig_panel.processor.compute_2_to_1(
60
+ obj2=sig2,
61
+ obj2_name="signal to subtract",
62
+ func=sig_panel.processor.get_feature("difference").function,
63
+ title="Difference",
64
+ )
65
+ subtracted_sig = sig_panel.objmodel.get_all_objects()[-1]
66
+
67
+ # Check lightweight metadata (no params, but has pattern and sources)
68
+ assert PROCESSING_PARAMETERS_OPTION in subtracted_sig.get_metadata_options()
69
+ option_dict = subtracted_sig.get_metadata_option(
70
+ PROCESSING_PARAMETERS_OPTION
71
+ )
72
+ assert option_dict["pattern"] == "2-to-1"
73
+ assert option_dict["source_uuids"] == [get_uuid(sig1), get_uuid(sig2)]
74
+ assert len(option_dict["source_uuids"]) == 2
75
+ # Should NOT have full parameters stored
76
+ assert "param" not in option_dict
77
+
78
+ # === Test 3: n-to-1 pattern (single operand mode) ===
79
+ img_panel.new_object()
80
+ img1 = img_panel.objmodel.get_all_objects()[-1]
81
+ img_panel.new_object()
82
+ img2 = img_panel.objmodel.get_all_objects()[-1]
83
+ img_panel.objview.select_objects([img1, img2])
84
+ img_panel.processor.compute_n_to_1(
85
+ func=img_panel.processor.get_feature("addition").function,
86
+ title="Addition",
87
+ )
88
+ sum_img = img_panel.objmodel.get_all_objects()[-1]
89
+
90
+ # Check lightweight metadata
91
+ assert PROCESSING_PARAMETERS_OPTION in sum_img.get_metadata_options()
92
+ option_dict = sum_img.get_metadata_option(PROCESSING_PARAMETERS_OPTION)
93
+ assert option_dict["pattern"] == "n-to-1"
94
+ assert "source_uuids" in option_dict
95
+ assert len(option_dict["source_uuids"]) == 2
96
+ # Should NOT have full parameters stored
97
+ assert "param" not in option_dict
98
+
99
+ print("✓ All processing patterns store appropriate metadata")
100
+
101
+
102
+ if __name__ == "__main__":
103
+ test_metadata_all_patterns()
@@ -0,0 +1,139 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Metadata application test:
5
+
6
+ - Create signal/image, with ROI
7
+ - Compute things (adds metadata)
8
+ - Test metadata delete, copy, paste
9
+ """
10
+
11
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
12
+ # guitest: show
13
+
14
+ import sigima.objects
15
+ import sigima.params
16
+ import sigima.proc.image as sipi
17
+ import sigima.proc.signal as sips
18
+ from sigima.tests.data import create_paracetamol_signal
19
+
20
+ from datalab.adapters_metadata.geometry_adapter import GeometryAdapter
21
+ from datalab.env import execenv
22
+ from datalab.gui.panel.base import BaseDataPanel, PasteMetadataParam
23
+ from datalab.gui.panel.image import ImagePanel
24
+ from datalab.gui.panel.signal import SignalPanel
25
+ from datalab.tests import datalab_test_app_context
26
+ from datalab.tests.features.image.roi_app_test import create_test_image_with_roi
27
+
28
+
29
+ def __run_signal_computations(panel: SignalPanel):
30
+ """Test all signal features related to ROI"""
31
+ execenv.print(" Signal features")
32
+ panel.processor.run_feature(sips.fwhm, sigima.params.FWHMParam())
33
+ panel.processor.run_feature(sips.fw1e2)
34
+
35
+
36
+ def __run_image_computations(panel: ImagePanel):
37
+ """Test all image features related to ROI"""
38
+ execenv.print(" Image features")
39
+ panel.processor.run_feature(sipi.centroid)
40
+ panel.processor.run_feature(sipi.enclosing_circle)
41
+ panel.processor.run_feature(
42
+ sipi.peak_detection, sigima.params.Peak2DDetectionParam()
43
+ )
44
+
45
+
46
+ def __test_metadata_features(panel: BaseDataPanel):
47
+ """Test all metadata features"""
48
+ # Duplicate the first object
49
+ panel.duplicate_object()
50
+
51
+ # Delete metadata of the first object
52
+ for keep_roi in (True, False): # Test both cases (coverage test)
53
+ panel.delete_metadata(keep_roi=keep_roi)
54
+
55
+ # Select and copy metadata of the second object
56
+ panel.objview.select_objects([2])
57
+ source_obj = panel.objview.get_sel_objects()[0]
58
+ source_metadata = source_obj.metadata.copy()
59
+
60
+ # Verify source object has geometry results
61
+ geometry_keys = [
62
+ k for k, v in source_metadata.items() if GeometryAdapter.match(k, v)
63
+ ]
64
+ execenv.print(f" Source object has {len(geometry_keys)} geometry metadata keys")
65
+ assert len(geometry_keys) > 0, "Source object should have geometry results"
66
+
67
+ # Copy metadata
68
+ panel.copy_metadata()
69
+
70
+ # Select and paste metadata to the first object
71
+ panel.objview.select_objects([1])
72
+ target_obj = panel.objview.get_sel_objects()[0]
73
+
74
+ # Verify target has no geometry metadata before paste
75
+ target_geo_keys_before = [
76
+ k for k, v in target_obj.metadata.items() if GeometryAdapter.match(k, v)
77
+ ]
78
+ execenv.print(
79
+ f" Target object has {len(target_geo_keys_before)} geometry keys before paste"
80
+ )
81
+
82
+ # Paste metadata (with default parameters - keep everything)
83
+ param = PasteMetadataParam("Test paste")
84
+ param.keep_geometry = True
85
+ param.keep_tables = True
86
+ param.keep_other = True
87
+ param.keep_roi = True
88
+ panel.paste_metadata(param)
89
+
90
+ # Verify the paste worked
91
+ target_metadata_after = target_obj.metadata.copy()
92
+ target_geo_keys_after = [
93
+ k for k, v in target_metadata_after.items() if GeometryAdapter.match(k, v)
94
+ ]
95
+ execenv.print(
96
+ f" Target object has {len(target_geo_keys_after)} geometry keys after paste"
97
+ )
98
+
99
+ # Check that geometry metadata was actually pasted
100
+ assert len(target_geo_keys_after) > 0, (
101
+ "Target object should have geometry results after paste"
102
+ )
103
+
104
+ # Verify that all geometry metadata uses the new unified format (_dict)
105
+ for key in target_geo_keys_after:
106
+ # Verify the geometry data is valid
107
+ geometry_data = target_metadata_after[key]
108
+ assert isinstance(geometry_data, dict), f"Geometry data should be dict: {key}"
109
+ assert "title" in geometry_data, f"Missing title in geometry data: {key}"
110
+ assert "coords" in geometry_data, f"Missing coords in geometry data: {key}"
111
+ execenv.print(f" ✓ Valid geometry entry: {key}")
112
+
113
+ execenv.print(" ✓ Metadata copy/paste verification passed")
114
+
115
+
116
+ def test_metadata_app():
117
+ """Run metadata application test scenario"""
118
+ size = 200
119
+ with datalab_test_app_context() as win:
120
+ execenv.print("Metadata application test:")
121
+ # === Signal metadata features test ===
122
+ panel = win.signalpanel
123
+ sig = create_paracetamol_signal(size)
124
+ sig.roi = sigima.objects.create_signal_roi([[26, 41], [125, 146]], indices=True)
125
+ panel.add_object(sig)
126
+ __run_signal_computations(panel)
127
+ __test_metadata_features(panel)
128
+ # === Image metadata features test ===
129
+ panel = win.imagepanel
130
+ param = sigima.objects.NewImageParam.create(height=size, width=size)
131
+ ima = create_test_image_with_roi(param)
132
+ panel.add_object(ima)
133
+ __run_image_computations(panel)
134
+ __test_metadata_features(panel)
135
+ execenv.print("==> OK")
136
+
137
+
138
+ if __name__ == "__main__":
139
+ test_metadata_app()
@@ -0,0 +1,60 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Metadata import/export unit test:
5
+
6
+ - Create an image with annotations, geometry result and table results
7
+ - Add the image to DataLab
8
+ - Export image metadata to file (JSON)
9
+ - Delete image metadata
10
+ - Import image metadata from previous file
11
+ - Check if image metadata is the same as the original image
12
+ """
13
+
14
+ # guitest: show
15
+
16
+ import os.path as osp
17
+
18
+ from sigima.tests import data as test_data
19
+
20
+ from datalab.adapters_metadata import GeometryAdapter, TableAdapter
21
+ from datalab.env import execenv
22
+ from datalab.tests import datalab_test_app_context, helpers
23
+
24
+
25
+ def test_metadata_io_unit():
26
+ """Run image tools test scenario"""
27
+ with execenv.context(unattended=True):
28
+ with helpers.WorkdirRestoringTempDir() as tmpdir:
29
+ fname = osp.join(tmpdir, "test.dlabmeta")
30
+ with datalab_test_app_context() as win:
31
+ panel = win.imagepanel
32
+
33
+ # Create a test image with annotations
34
+ ima = test_data.create_annotated_image()
35
+
36
+ # Add geometry results to test their serialization
37
+ for geometry in test_data.generate_geometry_results():
38
+ GeometryAdapter(geometry).add_to(ima)
39
+
40
+ # Add table results to test their serialization
41
+ for table in test_data.generate_table_results():
42
+ TableAdapter(table).add_to(ima)
43
+
44
+ panel.add_object(ima)
45
+ orig_metadata = ima.metadata.copy()
46
+ panel.export_metadata_from_file(fname)
47
+ panel.delete_metadata()
48
+
49
+ # The +1 is for the "number" metadata option which has no default:
50
+ assert len(ima.metadata) == len(ima.get_metadata_options_defaults()) + 1
51
+
52
+ panel.import_metadata_from_file(fname)
53
+ execenv.print("Check metadata export <--> import features:")
54
+ helpers.compare_metadata(
55
+ orig_metadata, ima.metadata, raise_on_diff=True
56
+ )
57
+
58
+
59
+ if __name__ == "__main__":
60
+ test_metadata_io_unit()