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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (496) hide show
  1. datalab/__init__.py +35 -2
  2. datalab/adapters_metadata/__init__.py +31 -0
  3. datalab/adapters_metadata/base_adapter.py +316 -0
  4. datalab/adapters_metadata/common.py +422 -0
  5. datalab/adapters_metadata/geometry_adapter.py +98 -0
  6. datalab/adapters_metadata/table_adapter.py +84 -0
  7. datalab/adapters_plotpy/__init__.py +54 -0
  8. datalab/adapters_plotpy/annotations.py +124 -0
  9. datalab/adapters_plotpy/base.py +110 -0
  10. datalab/adapters_plotpy/converters.py +86 -0
  11. datalab/adapters_plotpy/factories.py +80 -0
  12. datalab/adapters_plotpy/objects/__init__.py +0 -0
  13. datalab/adapters_plotpy/objects/base.py +197 -0
  14. datalab/adapters_plotpy/objects/image.py +157 -0
  15. datalab/adapters_plotpy/objects/scalar.py +565 -0
  16. datalab/adapters_plotpy/objects/signal.py +264 -0
  17. datalab/adapters_plotpy/roi/__init__.py +0 -0
  18. datalab/adapters_plotpy/roi/base.py +146 -0
  19. datalab/adapters_plotpy/roi/factory.py +93 -0
  20. datalab/adapters_plotpy/roi/image.py +207 -0
  21. datalab/adapters_plotpy/roi/signal.py +72 -0
  22. datalab/app.py +98 -0
  23. datalab/config.py +817 -0
  24. datalab/control/__init__.py +0 -0
  25. datalab/control/baseproxy.py +776 -0
  26. datalab/control/proxy.py +343 -0
  27. datalab/control/remote.py +1005 -0
  28. datalab/data/doc/DataLab_en.pdf +0 -0
  29. datalab/data/doc/DataLab_fr.pdf +0 -0
  30. datalab/data/icons/analysis/delete_results.svg +109 -0
  31. datalab/data/icons/analysis/fw1e2.svg +156 -0
  32. datalab/data/icons/analysis/fwhm.svg +156 -0
  33. datalab/data/icons/analysis/histogram.svg +49 -0
  34. datalab/data/icons/analysis/peak_detect.svg +160 -0
  35. datalab/data/icons/analysis/plot_results.svg +151 -0
  36. datalab/data/icons/analysis/show_results.svg +83 -0
  37. datalab/data/icons/analysis/stats.svg +49 -0
  38. datalab/data/icons/analysis.svg +120 -0
  39. datalab/data/icons/apply.svg +3 -0
  40. datalab/data/icons/check_all.svg +15 -0
  41. datalab/data/icons/collapse.svg +44 -0
  42. datalab/data/icons/collapse_selection.svg +63 -0
  43. datalab/data/icons/console.svg +101 -0
  44. datalab/data/icons/create/1d-normal.svg +8 -0
  45. datalab/data/icons/create/1d-poisson.svg +9 -0
  46. datalab/data/icons/create/1d-uniform.svg +8 -0
  47. datalab/data/icons/create/1d-zero.svg +57 -0
  48. datalab/data/icons/create/2d-gaussian.svg +56 -0
  49. datalab/data/icons/create/2d-normal.svg +38 -0
  50. datalab/data/icons/create/2d-poisson.svg +38 -0
  51. datalab/data/icons/create/2d-ramp.svg +90 -0
  52. datalab/data/icons/create/2d-sinc.svg +62 -0
  53. datalab/data/icons/create/2d-uniform.svg +38 -0
  54. datalab/data/icons/create/2d-zero.svg +13 -0
  55. datalab/data/icons/create/checkerboard.svg +39 -0
  56. datalab/data/icons/create/cosine.svg +12 -0
  57. datalab/data/icons/create/exponential.svg +55 -0
  58. datalab/data/icons/create/gaussian.svg +12 -0
  59. datalab/data/icons/create/grating.svg +29 -0
  60. datalab/data/icons/create/linear_chirp.svg +7 -0
  61. datalab/data/icons/create/logistic.svg +7 -0
  62. datalab/data/icons/create/lorentzian.svg +12 -0
  63. datalab/data/icons/create/planck.svg +12 -0
  64. datalab/data/icons/create/polynomial.svg +7 -0
  65. datalab/data/icons/create/pulse.svg +12 -0
  66. datalab/data/icons/create/ring.svg +18 -0
  67. datalab/data/icons/create/sawtooth.svg +7 -0
  68. datalab/data/icons/create/siemens.svg +35 -0
  69. datalab/data/icons/create/sinc.svg +12 -0
  70. datalab/data/icons/create/sine.svg +7 -0
  71. datalab/data/icons/create/square.svg +7 -0
  72. datalab/data/icons/create/square_pulse.svg +7 -0
  73. datalab/data/icons/create/step.svg +7 -0
  74. datalab/data/icons/create/step_pulse.svg +12 -0
  75. datalab/data/icons/create/triangle.svg +7 -0
  76. datalab/data/icons/create/voigt.svg +12 -0
  77. datalab/data/icons/edit/annotations.svg +72 -0
  78. datalab/data/icons/edit/annotations_copy.svg +114 -0
  79. datalab/data/icons/edit/annotations_delete.svg +83 -0
  80. datalab/data/icons/edit/annotations_edit.svg +98 -0
  81. datalab/data/icons/edit/annotations_export.svg +85 -0
  82. datalab/data/icons/edit/annotations_import.svg +85 -0
  83. datalab/data/icons/edit/annotations_paste.svg +100 -0
  84. datalab/data/icons/edit/copy_titles.svg +109 -0
  85. datalab/data/icons/edit/delete.svg +84 -0
  86. datalab/data/icons/edit/delete_all.svg +214 -0
  87. datalab/data/icons/edit/duplicate.svg +64 -0
  88. datalab/data/icons/edit/goto_source.svg +60 -0
  89. datalab/data/icons/edit/metadata.svg +60 -0
  90. datalab/data/icons/edit/metadata_add.svg +80 -0
  91. datalab/data/icons/edit/metadata_copy.svg +96 -0
  92. datalab/data/icons/edit/metadata_delete.svg +62 -0
  93. datalab/data/icons/edit/metadata_export.svg +68 -0
  94. datalab/data/icons/edit/metadata_import.svg +68 -0
  95. datalab/data/icons/edit/metadata_paste.svg +79 -0
  96. datalab/data/icons/edit/move_down.svg +55 -0
  97. datalab/data/icons/edit/move_up.svg +54 -0
  98. datalab/data/icons/edit/new_group.svg +76 -0
  99. datalab/data/icons/edit/recompute.svg +60 -0
  100. datalab/data/icons/edit/rename.svg +49 -0
  101. datalab/data/icons/edit.svg +16 -0
  102. datalab/data/icons/expand.svg +44 -0
  103. datalab/data/icons/expand_selection.svg +63 -0
  104. datalab/data/icons/fit/cdf_fit.svg +56 -0
  105. datalab/data/icons/fit/exponential_fit.svg +55 -0
  106. datalab/data/icons/fit/gaussian_fit.svg +62 -0
  107. datalab/data/icons/fit/interactive_fit.svg +101 -0
  108. datalab/data/icons/fit/linear_fit.svg +57 -0
  109. datalab/data/icons/fit/lorentzian_fit.svg +209 -0
  110. datalab/data/icons/fit/multigaussian_fit.svg +85 -0
  111. datalab/data/icons/fit/multilorentzian_fit.svg +85 -0
  112. datalab/data/icons/fit/piecewiseexponential_fit.svg +209 -0
  113. datalab/data/icons/fit/planckian_fit.svg +62 -0
  114. datalab/data/icons/fit/polynomial_fit.svg +59 -0
  115. datalab/data/icons/fit/sigmoid_fit.svg +56 -0
  116. datalab/data/icons/fit/sinusoidal_fit.svg +72 -0
  117. datalab/data/icons/fit/twohalfgaussian_fit.svg +63 -0
  118. datalab/data/icons/fit/voigt_fit.svg +57 -0
  119. datalab/data/icons/group.svg +56 -0
  120. datalab/data/icons/h5/h5array.svg +59 -0
  121. datalab/data/icons/h5/h5attrs.svg +75 -0
  122. datalab/data/icons/h5/h5browser.svg +133 -0
  123. datalab/data/icons/h5/h5file.svg +69 -0
  124. datalab/data/icons/h5/h5group.svg +49 -0
  125. datalab/data/icons/h5/h5scalar.svg +1 -0
  126. datalab/data/icons/help_pdf.svg +46 -0
  127. datalab/data/icons/history.svg +7 -0
  128. datalab/data/icons/image.svg +135 -0
  129. datalab/data/icons/io/fileopen_directory.svg +60 -0
  130. datalab/data/icons/io/fileopen_h5.svg +84 -0
  131. datalab/data/icons/io/fileopen_ima.svg +187 -0
  132. datalab/data/icons/io/fileopen_py.svg +123 -0
  133. datalab/data/icons/io/fileopen_sig.svg +138 -0
  134. datalab/data/icons/io/filesave_h5.svg +97 -0
  135. datalab/data/icons/io/filesave_ima.svg +200 -0
  136. datalab/data/icons/io/filesave_py.svg +136 -0
  137. datalab/data/icons/io/filesave_sig.svg +151 -0
  138. datalab/data/icons/io/import_text.svg +144 -0
  139. datalab/data/icons/io/save_to_directory.svg +134 -0
  140. datalab/data/icons/io.svg +84 -0
  141. datalab/data/icons/libre-camera-flash-off.svg +1 -0
  142. datalab/data/icons/libre-camera-flash-on.svg +1 -0
  143. datalab/data/icons/libre-gui-about.svg +1 -0
  144. datalab/data/icons/libre-gui-action-delete.svg +1 -0
  145. datalab/data/icons/libre-gui-add.svg +1 -0
  146. datalab/data/icons/libre-gui-arrow-down.svg +1 -0
  147. datalab/data/icons/libre-gui-arrow-left.svg +1 -0
  148. datalab/data/icons/libre-gui-arrow-right.svg +1 -0
  149. datalab/data/icons/libre-gui-arrow-up.svg +1 -0
  150. datalab/data/icons/libre-gui-close.svg +40 -0
  151. datalab/data/icons/libre-gui-cogs.svg +1 -0
  152. datalab/data/icons/libre-gui-globe.svg +1 -0
  153. datalab/data/icons/libre-gui-help.svg +1 -0
  154. datalab/data/icons/libre-gui-link.svg +1 -0
  155. datalab/data/icons/libre-gui-menu.svg +1 -0
  156. datalab/data/icons/libre-gui-pencil.svg +1 -0
  157. datalab/data/icons/libre-gui-plugin.svg +1 -0
  158. datalab/data/icons/libre-gui-questions.svg +1 -0
  159. datalab/data/icons/libre-gui-settings.svg +1 -0
  160. datalab/data/icons/libre-gui-unlink.svg +1 -0
  161. datalab/data/icons/libre-tech-ram.svg +1 -0
  162. datalab/data/icons/libre-toolbox.svg +1 -0
  163. datalab/data/icons/logs.svg +1 -0
  164. datalab/data/icons/markers.svg +74 -0
  165. datalab/data/icons/menu.svg +13 -0
  166. datalab/data/icons/new_ima.svg +148 -0
  167. datalab/data/icons/new_sig.svg +123 -0
  168. datalab/data/icons/operations/abs.svg +116 -0
  169. datalab/data/icons/operations/arithmetic.svg +123 -0
  170. datalab/data/icons/operations/average.svg +124 -0
  171. datalab/data/icons/operations/complex_from_magnitude_phase.svg +116 -0
  172. datalab/data/icons/operations/complex_from_real_imag.svg +124 -0
  173. datalab/data/icons/operations/constant.svg +116 -0
  174. datalab/data/icons/operations/constant_add.svg +109 -0
  175. datalab/data/icons/operations/constant_divide.svg +109 -0
  176. datalab/data/icons/operations/constant_multiply.svg +109 -0
  177. datalab/data/icons/operations/constant_subtract.svg +109 -0
  178. datalab/data/icons/operations/convert_dtype.svg +117 -0
  179. datalab/data/icons/operations/convolution.svg +46 -0
  180. datalab/data/icons/operations/deconvolution.svg +57 -0
  181. datalab/data/icons/operations/derivative.svg +127 -0
  182. datalab/data/icons/operations/difference.svg +52 -0
  183. datalab/data/icons/operations/division.svg +139 -0
  184. datalab/data/icons/operations/exp.svg +116 -0
  185. datalab/data/icons/operations/flip_horizontally.svg +69 -0
  186. datalab/data/icons/operations/flip_vertically.svg +74 -0
  187. datalab/data/icons/operations/im.svg +124 -0
  188. datalab/data/icons/operations/integral.svg +50 -0
  189. datalab/data/icons/operations/inverse.svg +143 -0
  190. datalab/data/icons/operations/log10.svg +109 -0
  191. datalab/data/icons/operations/phase.svg +116 -0
  192. datalab/data/icons/operations/power.svg +118 -0
  193. datalab/data/icons/operations/product.svg +124 -0
  194. datalab/data/icons/operations/profile.svg +379 -0
  195. datalab/data/icons/operations/profile_average.svg +399 -0
  196. datalab/data/icons/operations/profile_radial.svg +261 -0
  197. datalab/data/icons/operations/profile_segment.svg +262 -0
  198. datalab/data/icons/operations/quadratic_difference.svg +84 -0
  199. datalab/data/icons/operations/re.svg +124 -0
  200. datalab/data/icons/operations/rotate_left.svg +72 -0
  201. datalab/data/icons/operations/rotate_right.svg +72 -0
  202. datalab/data/icons/operations/signals_to_image.svg +314 -0
  203. datalab/data/icons/operations/sqrt.svg +110 -0
  204. datalab/data/icons/operations/std.svg +124 -0
  205. datalab/data/icons/operations/sum.svg +102 -0
  206. datalab/data/icons/play_demo.svg +9 -0
  207. datalab/data/icons/processing/axis_transform.svg +62 -0
  208. datalab/data/icons/processing/bandpass.svg +79 -0
  209. datalab/data/icons/processing/bandstop.svg +71 -0
  210. datalab/data/icons/processing/binning.svg +126 -0
  211. datalab/data/icons/processing/clip.svg +119 -0
  212. datalab/data/icons/processing/detrending.svg +173 -0
  213. datalab/data/icons/processing/distribute_on_grid.svg +769 -0
  214. datalab/data/icons/processing/edge_detection.svg +46 -0
  215. datalab/data/icons/processing/erase.svg +1 -0
  216. datalab/data/icons/processing/exposure.svg +143 -0
  217. datalab/data/icons/processing/fourier.svg +104 -0
  218. datalab/data/icons/processing/highpass.svg +59 -0
  219. datalab/data/icons/processing/interpolation.svg +71 -0
  220. datalab/data/icons/processing/level_adjustment.svg +70 -0
  221. datalab/data/icons/processing/lowpass.svg +60 -0
  222. datalab/data/icons/processing/morphology.svg +49 -0
  223. datalab/data/icons/processing/noise_addition.svg +114 -0
  224. datalab/data/icons/processing/noise_reduction.svg +38 -0
  225. datalab/data/icons/processing/normalize.svg +84 -0
  226. datalab/data/icons/processing/offset_correction.svg +131 -0
  227. datalab/data/icons/processing/resampling1d.svg +101 -0
  228. datalab/data/icons/processing/resampling2d.svg +240 -0
  229. datalab/data/icons/processing/reset_positions.svg +185 -0
  230. datalab/data/icons/processing/resize.svg +9 -0
  231. datalab/data/icons/processing/reverse_signal_x.svg +171 -0
  232. datalab/data/icons/processing/stability.svg +11 -0
  233. datalab/data/icons/processing/swap_x_y.svg +65 -0
  234. datalab/data/icons/processing/thresholding.svg +63 -0
  235. datalab/data/icons/processing/windowing.svg +45 -0
  236. datalab/data/icons/properties.svg +26 -0
  237. datalab/data/icons/reset.svg +9 -0
  238. datalab/data/icons/restore.svg +40 -0
  239. datalab/data/icons/roi/roi.svg +76 -0
  240. datalab/data/icons/roi/roi_coordinate.svg +78 -0
  241. datalab/data/icons/roi/roi_copy.svg +112 -0
  242. datalab/data/icons/roi/roi_delete.svg +81 -0
  243. datalab/data/icons/roi/roi_export.svg +87 -0
  244. datalab/data/icons/roi/roi_graphical.svg +78 -0
  245. datalab/data/icons/roi/roi_grid.svg +67 -0
  246. datalab/data/icons/roi/roi_ima.svg +188 -0
  247. datalab/data/icons/roi/roi_import.svg +87 -0
  248. datalab/data/icons/roi/roi_new.svg +81 -0
  249. datalab/data/icons/roi/roi_new_circle.svg +95 -0
  250. datalab/data/icons/roi/roi_new_polygon.svg +110 -0
  251. datalab/data/icons/roi/roi_new_rectangle.svg +70 -0
  252. datalab/data/icons/roi/roi_paste.svg +98 -0
  253. datalab/data/icons/roi/roi_sig.svg +124 -0
  254. datalab/data/icons/shapes.svg +134 -0
  255. datalab/data/icons/signal.svg +103 -0
  256. datalab/data/icons/table.svg +85 -0
  257. datalab/data/icons/table_unavailable.svg +102 -0
  258. datalab/data/icons/to_signal.svg +124 -0
  259. datalab/data/icons/tour/next.svg +44 -0
  260. datalab/data/icons/tour/previous.svg +44 -0
  261. datalab/data/icons/tour/rewind.svg +51 -0
  262. datalab/data/icons/tour/stop.svg +47 -0
  263. datalab/data/icons/tour/tour.svg +16 -0
  264. datalab/data/icons/uncheck_all.svg +78 -0
  265. datalab/data/icons/view/curve_antialiasing.svg +50 -0
  266. datalab/data/icons/view/new_window.svg +98 -0
  267. datalab/data/icons/view/refresh-auto.svg +57 -0
  268. datalab/data/icons/view/refresh-manual.svg +51 -0
  269. datalab/data/icons/view/reset_curve_styles.svg +96 -0
  270. datalab/data/icons/view/show_first.svg +55 -0
  271. datalab/data/icons/view/show_titles.svg +46 -0
  272. datalab/data/icons/visualization.svg +51 -0
  273. datalab/data/logo/DataLab-Banner-150.png +0 -0
  274. datalab/data/logo/DataLab-Banner-200.png +0 -0
  275. datalab/data/logo/DataLab-Banner2-100.png +0 -0
  276. datalab/data/logo/DataLab-Splash.png +0 -0
  277. datalab/data/logo/DataLab-watermark.png +0 -0
  278. datalab/data/logo/DataLab.svg +83 -0
  279. datalab/data/tests/reordering_test.h5 +0 -0
  280. datalab/data/tutorials/fabry_perot/fabry-perot1.jpg +0 -0
  281. datalab/data/tutorials/fabry_perot/fabry-perot2.jpg +0 -0
  282. datalab/data/tutorials/laser_beam/TEM00_z_13.jpg +0 -0
  283. datalab/data/tutorials/laser_beam/TEM00_z_18.jpg +0 -0
  284. datalab/data/tutorials/laser_beam/TEM00_z_23.jpg +0 -0
  285. datalab/data/tutorials/laser_beam/TEM00_z_30.jpg +0 -0
  286. datalab/data/tutorials/laser_beam/TEM00_z_35.jpg +0 -0
  287. datalab/data/tutorials/laser_beam/TEM00_z_40.jpg +0 -0
  288. datalab/data/tutorials/laser_beam/TEM00_z_45.jpg +0 -0
  289. datalab/data/tutorials/laser_beam/TEM00_z_50.jpg +0 -0
  290. datalab/data/tutorials/laser_beam/TEM00_z_55.jpg +0 -0
  291. datalab/data/tutorials/laser_beam/TEM00_z_60.jpg +0 -0
  292. datalab/data/tutorials/laser_beam/TEM00_z_65.jpg +0 -0
  293. datalab/data/tutorials/laser_beam/TEM00_z_70.jpg +0 -0
  294. datalab/data/tutorials/laser_beam/TEM00_z_75.jpg +0 -0
  295. datalab/data/tutorials/laser_beam/TEM00_z_80.jpg +0 -0
  296. datalab/env.py +542 -0
  297. datalab/gui/__init__.py +89 -0
  298. datalab/gui/actionhandler.py +1701 -0
  299. datalab/gui/docks.py +473 -0
  300. datalab/gui/h5io.py +150 -0
  301. datalab/gui/macroeditor.py +310 -0
  302. datalab/gui/main.py +2081 -0
  303. datalab/gui/newobject.py +217 -0
  304. datalab/gui/objectview.py +766 -0
  305. datalab/gui/panel/__init__.py +48 -0
  306. datalab/gui/panel/base.py +3254 -0
  307. datalab/gui/panel/image.py +157 -0
  308. datalab/gui/panel/macro.py +607 -0
  309. datalab/gui/panel/signal.py +164 -0
  310. datalab/gui/plothandler.py +800 -0
  311. datalab/gui/processor/__init__.py +84 -0
  312. datalab/gui/processor/base.py +2456 -0
  313. datalab/gui/processor/catcher.py +75 -0
  314. datalab/gui/processor/image.py +1214 -0
  315. datalab/gui/processor/signal.py +755 -0
  316. datalab/gui/profiledialog.py +333 -0
  317. datalab/gui/roieditor.py +633 -0
  318. datalab/gui/roigrideditor.py +208 -0
  319. datalab/gui/settings.py +612 -0
  320. datalab/gui/tour.py +908 -0
  321. datalab/h5/__init__.py +12 -0
  322. datalab/h5/common.py +314 -0
  323. datalab/h5/generic.py +580 -0
  324. datalab/h5/native.py +39 -0
  325. datalab/h5/utils.py +95 -0
  326. datalab/objectmodel.py +640 -0
  327. datalab/plugins/_readme_.txt +9 -0
  328. datalab/plugins/datalab_imageformats.py +175 -0
  329. datalab/plugins/datalab_testdata.py +190 -0
  330. datalab/plugins.py +355 -0
  331. datalab/tests/__init__.py +199 -0
  332. datalab/tests/backbone/__init__.py +1 -0
  333. datalab/tests/backbone/config_unit_test.py +170 -0
  334. datalab/tests/backbone/config_versioning_unit_test.py +34 -0
  335. datalab/tests/backbone/dictlistserial_app_test.py +38 -0
  336. datalab/tests/backbone/errorcatcher_unit_test.py +69 -0
  337. datalab/tests/backbone/errormsgbox_unit_test.py +50 -0
  338. datalab/tests/backbone/execenv_unit.py +262 -0
  339. datalab/tests/backbone/loadtest_gdi.py +147 -0
  340. datalab/tests/backbone/long_callback.py +96 -0
  341. datalab/tests/backbone/main_app_test.py +137 -0
  342. datalab/tests/backbone/memory_leak.py +43 -0
  343. datalab/tests/backbone/procisolation1_unit.py +128 -0
  344. datalab/tests/backbone/procisolation2_unit.py +171 -0
  345. datalab/tests/backbone/procisolation_unit_test.py +22 -0
  346. datalab/tests/backbone/profiling_app.py +27 -0
  347. datalab/tests/backbone/strings_unit_test.py +65 -0
  348. datalab/tests/backbone/title_formatting_unit_test.py +82 -0
  349. datalab/tests/conftest.py +131 -0
  350. datalab/tests/features/__init__.py +1 -0
  351. datalab/tests/features/applauncher/__init__.py +1 -0
  352. datalab/tests/features/applauncher/launcher1_app_test.py +28 -0
  353. datalab/tests/features/applauncher/launcher2_app_test.py +30 -0
  354. datalab/tests/features/common/__init__.py +1 -0
  355. datalab/tests/features/common/add_metadata_app_test.py +134 -0
  356. datalab/tests/features/common/add_metadata_unit_test.py +267 -0
  357. datalab/tests/features/common/annotations_management_unit_test.py +152 -0
  358. datalab/tests/features/common/auto_analysis_recompute_unit_test.py +240 -0
  359. datalab/tests/features/common/createobject_unit_test.py +50 -0
  360. datalab/tests/features/common/geometry_results_app_test.py +135 -0
  361. datalab/tests/features/common/interactive_processing_test.py +1109 -0
  362. datalab/tests/features/common/io_app_test.py +75 -0
  363. datalab/tests/features/common/large_results_app_test.py +187 -0
  364. datalab/tests/features/common/metadata_all_patterns_test.py +103 -0
  365. datalab/tests/features/common/metadata_app_test.py +139 -0
  366. datalab/tests/features/common/metadata_io_unit_test.py +60 -0
  367. datalab/tests/features/common/misc_app_test.py +236 -0
  368. datalab/tests/features/common/multiple_geometry_results_unit_test.py +122 -0
  369. datalab/tests/features/common/multiple_table_results_unit_test.py +64 -0
  370. datalab/tests/features/common/operation_modes_app_test.py +392 -0
  371. datalab/tests/features/common/plot_results_app_test.py +278 -0
  372. datalab/tests/features/common/reorder_app_test.py +75 -0
  373. datalab/tests/features/common/result_deletion_unit_test.py +96 -0
  374. datalab/tests/features/common/result_merged_label_unit_test.py +154 -0
  375. datalab/tests/features/common/result_shape_settings_unit_test.py +223 -0
  376. datalab/tests/features/common/roi_plotitem_unit_test.py +64 -0
  377. datalab/tests/features/common/roieditor_unit_test.py +102 -0
  378. datalab/tests/features/common/save_to_dir_app_test.py +163 -0
  379. datalab/tests/features/common/save_to_dir_unit_test.py +474 -0
  380. datalab/tests/features/common/stat_app_test.py +40 -0
  381. datalab/tests/features/common/stats_tools_unit_test.py +77 -0
  382. datalab/tests/features/common/table_results_app_test.py +52 -0
  383. datalab/tests/features/common/textimport_unit_test.py +131 -0
  384. datalab/tests/features/common/uuid_preservation_test.py +281 -0
  385. datalab/tests/features/common/worker_unit_test.py +402 -0
  386. datalab/tests/features/control/__init__.py +1 -0
  387. datalab/tests/features/control/connect_dialog.py +28 -0
  388. datalab/tests/features/control/embedded1_unit_test.py +304 -0
  389. datalab/tests/features/control/embedded2_unit_test.py +52 -0
  390. datalab/tests/features/control/remoteclient_app_test.py +219 -0
  391. datalab/tests/features/control/remoteclient_unit.py +75 -0
  392. datalab/tests/features/control/simpleclient_unit_test.py +321 -0
  393. datalab/tests/features/hdf5/__init__.py +1 -0
  394. datalab/tests/features/hdf5/h5browser1_unit_test.py +31 -0
  395. datalab/tests/features/hdf5/h5browser2_unit.py +55 -0
  396. datalab/tests/features/hdf5/h5browser_app_test.py +77 -0
  397. datalab/tests/features/hdf5/h5import_app_test.py +25 -0
  398. datalab/tests/features/hdf5/h5importer_app_test.py +34 -0
  399. datalab/tests/features/image/__init__.py +1 -0
  400. datalab/tests/features/image/annotations_app_test.py +28 -0
  401. datalab/tests/features/image/annotations_unit_test.py +80 -0
  402. datalab/tests/features/image/average_app_test.py +46 -0
  403. datalab/tests/features/image/background_dialog_test.py +70 -0
  404. datalab/tests/features/image/blobs_app_test.py +50 -0
  405. datalab/tests/features/image/contour_app_test.py +42 -0
  406. datalab/tests/features/image/contour_fabryperot_app_test.py +51 -0
  407. datalab/tests/features/image/denoise_app_test.py +31 -0
  408. datalab/tests/features/image/distribute_on_grid_app_test.py +95 -0
  409. datalab/tests/features/image/edges_app_test.py +31 -0
  410. datalab/tests/features/image/erase_app_test.py +21 -0
  411. datalab/tests/features/image/fft2d_app_test.py +27 -0
  412. datalab/tests/features/image/flatfield_app_test.py +40 -0
  413. datalab/tests/features/image/geometry_transform_unit_test.py +396 -0
  414. datalab/tests/features/image/imagetools_app_test.py +51 -0
  415. datalab/tests/features/image/imagetools_unit_test.py +27 -0
  416. datalab/tests/features/image/load_app_test.py +73 -0
  417. datalab/tests/features/image/morph_app_test.py +32 -0
  418. datalab/tests/features/image/offsetcorrection_app_test.py +30 -0
  419. datalab/tests/features/image/peak2d_app_test.py +53 -0
  420. datalab/tests/features/image/profile_app_test.py +73 -0
  421. datalab/tests/features/image/profile_dialog_test.py +56 -0
  422. datalab/tests/features/image/roi_app_test.py +98 -0
  423. datalab/tests/features/image/roi_circ_app_test.py +62 -0
  424. datalab/tests/features/image/roi_manipulation_app_test.py +268 -0
  425. datalab/tests/features/image/roigrid_unit_test.py +60 -0
  426. datalab/tests/features/image/side_by_side_app_test.py +52 -0
  427. datalab/tests/features/macro/__init__.py +1 -0
  428. datalab/tests/features/macro/macro_app_test.py +28 -0
  429. datalab/tests/features/macro/macroeditor_unit_test.py +102 -0
  430. datalab/tests/features/signal/__init__.py +1 -0
  431. datalab/tests/features/signal/baseline_dialog_test.py +53 -0
  432. datalab/tests/features/signal/deltax_dialog_unit_test.py +34 -0
  433. datalab/tests/features/signal/fft1d_app_test.py +26 -0
  434. datalab/tests/features/signal/filter_app_test.py +44 -0
  435. datalab/tests/features/signal/fitdialog_unit_test.py +50 -0
  436. datalab/tests/features/signal/interpolation_app_test.py +110 -0
  437. datalab/tests/features/signal/loadbigsignal_app_test.py +80 -0
  438. datalab/tests/features/signal/multiple_rois_unit_test.py +132 -0
  439. datalab/tests/features/signal/pulse_features_app_test.py +118 -0
  440. datalab/tests/features/signal/pulse_features_roi_app_test.py +55 -0
  441. datalab/tests/features/signal/roi_app_test.py +78 -0
  442. datalab/tests/features/signal/roi_manipulation_app_test.py +261 -0
  443. datalab/tests/features/signal/select_xy_cursor_unit_test.py +46 -0
  444. datalab/tests/features/signal/signalpeakdetection_dialog_test.py +33 -0
  445. datalab/tests/features/signal/signals_to_image_app_test.py +98 -0
  446. datalab/tests/features/signal/xarray_compat_app_test.py +128 -0
  447. datalab/tests/features/tour_unit_test.py +22 -0
  448. datalab/tests/features/utilities/__init__.py +1 -0
  449. datalab/tests/features/utilities/installconf_unit_test.py +21 -0
  450. datalab/tests/features/utilities/logview_app_test.py +21 -0
  451. datalab/tests/features/utilities/logview_error.py +24 -0
  452. datalab/tests/features/utilities/logview_unit_test.py +21 -0
  453. datalab/tests/features/utilities/memstatus_app_test.py +42 -0
  454. datalab/tests/features/utilities/settings_unit_test.py +88 -0
  455. datalab/tests/scenarios/__init__.py +1 -0
  456. datalab/tests/scenarios/beautiful_app.py +121 -0
  457. datalab/tests/scenarios/common.py +463 -0
  458. datalab/tests/scenarios/demo.py +212 -0
  459. datalab/tests/scenarios/example_app_test.py +47 -0
  460. datalab/tests/scenarios/scenario_h5_app_test.py +75 -0
  461. datalab/tests/scenarios/scenario_ima1_app_test.py +34 -0
  462. datalab/tests/scenarios/scenario_ima2_app_test.py +34 -0
  463. datalab/tests/scenarios/scenario_mac_app_test.py +58 -0
  464. datalab/tests/scenarios/scenario_sig1_app_test.py +36 -0
  465. datalab/tests/scenarios/scenario_sig2_app_test.py +35 -0
  466. datalab/utils/__init__.py +1 -0
  467. datalab/utils/conf.py +304 -0
  468. datalab/utils/dephash.py +105 -0
  469. datalab/utils/qthelpers.py +633 -0
  470. datalab/utils/strings.py +34 -0
  471. datalab/utils/tests.py +0 -0
  472. datalab/widgets/__init__.py +1 -0
  473. datalab/widgets/connection.py +138 -0
  474. datalab/widgets/filedialog.py +91 -0
  475. datalab/widgets/fileviewer.py +84 -0
  476. datalab/widgets/fitdialog.py +788 -0
  477. datalab/widgets/h5browser.py +1048 -0
  478. datalab/widgets/imagebackground.py +111 -0
  479. datalab/widgets/instconfviewer.py +175 -0
  480. datalab/widgets/logviewer.py +80 -0
  481. datalab/widgets/signalbaseline.py +90 -0
  482. datalab/widgets/signalcursor.py +208 -0
  483. datalab/widgets/signaldeltax.py +151 -0
  484. datalab/widgets/signalpeak.py +199 -0
  485. datalab/widgets/status.py +249 -0
  486. datalab/widgets/textimport.py +786 -0
  487. datalab/widgets/warningerror.py +223 -0
  488. datalab/widgets/wizard.py +286 -0
  489. datalab_platform-1.0.0.dist-info/METADATA +121 -0
  490. datalab_platform-1.0.0.dist-info/RECORD +494 -0
  491. datalab_platform-0.0.1.dev0.dist-info/METADATA +0 -67
  492. datalab_platform-0.0.1.dev0.dist-info/RECORD +0 -7
  493. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/WHEEL +0 -0
  494. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/entry_points.txt +0 -0
  495. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/licenses/LICENSE +0 -0
  496. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,134 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Add metadata application test for screenshots:
5
+
6
+ - Create signals and images
7
+ - Open Add metadata dialog
8
+ - Take screenshots for documentation
9
+ """
10
+
11
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
12
+ # guitest: show
13
+
14
+ from __future__ import annotations
15
+
16
+ import warnings
17
+ from typing import TYPE_CHECKING
18
+
19
+ import guidata.dataset as gds
20
+
21
+ from datalab.env import execenv
22
+ from datalab.gui.panel.base import AddMetadataParam
23
+ from datalab.tests import datalab_test_app_context
24
+ from datalab.tests.features.common.add_metadata_unit_test import (
25
+ create_test_images,
26
+ create_test_signals,
27
+ )
28
+
29
+ if TYPE_CHECKING:
30
+ from datalab.gui.main import DLMainWindow
31
+
32
+
33
+ def __add_metadata_to_signals(win: DLMainWindow, screenshot: bool = False) -> None:
34
+ """Add metadata to signals helper function."""
35
+ execenv.print("Add metadata signal application test:")
36
+ panel = win.signalpanel
37
+
38
+ # Add test signals to the panel
39
+ for sig in create_test_signals():
40
+ panel.add_object(sig)
41
+
42
+ # Select all signals
43
+ panel.objview.select_objects([1, 2, 3])
44
+
45
+ # Create and configure the Add metadata dialog
46
+ objs = panel.objview.get_sel_objects(include_groups=True)
47
+ param = AddMetadataParam(objs)
48
+
49
+ # Configure example metadata
50
+ param.metadata_key = "experiment_id"
51
+ param.value_pattern = "EXP_{index:03d}"
52
+ param.conversion = "string"
53
+ param.update_preview()
54
+ execenv.print(f" Preview: {param.preview}")
55
+ assert "experiment_id" in param.preview
56
+ execenv.print(" ✓ Add metadata parameter configured correctly")
57
+
58
+ # Edit the parameter to show the dialog
59
+ execenv.print(" Opening Add metadata dialog...")
60
+ with warnings.catch_warnings():
61
+ warnings.simplefilter("ignore", category=gds.DataItemValidationWarning)
62
+ with execenv.context(screenshot=screenshot):
63
+ param.edit(parent=win, wordwrap=False, object_name="s_add_metadata")
64
+
65
+ # Run DataLab's metadata addition functionality:
66
+ panel.add_metadata(param)
67
+
68
+ execenv.print("==> Signal application test OK")
69
+
70
+
71
+ def __add_metadata_to_images(win: DLMainWindow, screenshot: bool = False) -> None:
72
+ """Add metadata to images helper function."""
73
+ execenv.print("Add metadata image test:")
74
+ panel = win.imagepanel
75
+
76
+ # Add test images to the panel
77
+ for img in create_test_images():
78
+ panel.add_object(img)
79
+
80
+ # Select all images
81
+ panel.objview.select_objects([1, 2, 3])
82
+
83
+ # Create and configure the Add metadata dialog
84
+ objs = panel.objview.get_sel_objects(include_groups=True)
85
+ param = AddMetadataParam(objs)
86
+
87
+ # Configure example metadata
88
+ param.metadata_key = "sample_id"
89
+ param.value_pattern = "SAMPLE_{index:04d}_{title:upper}"
90
+ param.conversion = "string"
91
+ param.update_preview()
92
+ execenv.print(f" Preview: {param.preview}")
93
+ assert "sample_id" in param.preview
94
+ execenv.print(" ✓ Add metadata parameter configured correctly")
95
+
96
+ # Edit the parameter to show the dialog
97
+ execenv.print(" Opening Add metadata dialog...")
98
+ with warnings.catch_warnings():
99
+ warnings.simplefilter("ignore", category=gds.DataItemValidationWarning)
100
+ with execenv.context(screenshot=screenshot):
101
+ param.edit(parent=win, wordwrap=False, object_name="i_add_metadata")
102
+
103
+ # Run DataLab's metadata addition functionality:
104
+ panel.add_metadata(param)
105
+
106
+ execenv.print("==> Image application test OK")
107
+
108
+
109
+ def test_add_metadata_to_signals() -> None:
110
+ """Test Add metadata feature for signals."""
111
+ with datalab_test_app_context() as win:
112
+ __add_metadata_to_signals(win)
113
+
114
+
115
+ def test_add_metadata_to_images() -> None:
116
+ """Test Add metadata feature for images."""
117
+ with datalab_test_app_context() as win:
118
+ __add_metadata_to_images(win)
119
+
120
+
121
+ def add_metadata_screenshots():
122
+ """Generate add metadata screenshots."""
123
+ with execenv.context(unattended=True):
124
+ with datalab_test_app_context() as win:
125
+ execenv.print("Add metadata screenshots test:")
126
+ __add_metadata_to_signals(win, screenshot=True)
127
+ __add_metadata_to_images(win, screenshot=True)
128
+ execenv.print("==> All screenshot tests completed")
129
+
130
+
131
+ if __name__ == "__main__":
132
+ # test_add_metadata_to_signals()
133
+ # test_add_metadata_to_images()
134
+ add_metadata_screenshots()
@@ -0,0 +1,267 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Unit tests for Add Metadata feature.
5
+
6
+ This module tests the `AddMetadataParam` class and the `add_metadata` method
7
+ from `datalab.gui.panel.base`.
8
+ """
9
+
10
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
11
+
12
+ from __future__ import annotations
13
+
14
+ from typing import TYPE_CHECKING
15
+
16
+ import guidata.config as gcfg
17
+ import numpy as np
18
+ import pytest
19
+ from sigima.objects import create_image, create_signal
20
+
21
+ from datalab.env import execenv
22
+ from datalab.gui.panel.base import AddMetadataParam
23
+
24
+ if TYPE_CHECKING:
25
+ from sigima.objects import ImageObj, SignalObj
26
+
27
+
28
+ def create_test_signals() -> list[SignalObj]:
29
+ """Create a list of test signals for testing."""
30
+ # Signal 1: Sine wave
31
+ x = np.linspace(0, 10, 100)
32
+ signal1 = create_signal(
33
+ title="Sine Wave",
34
+ x=x,
35
+ y=np.sin(x),
36
+ metadata={"type": "sine", "frequency": "1 Hz"},
37
+ )
38
+
39
+ # Signal 2: Cosine wave
40
+ signal2 = create_signal(
41
+ title="Cosine Wave",
42
+ x=x,
43
+ y=np.cos(x * 2),
44
+ metadata={"type": "cosine", "frequency": "2 Hz"},
45
+ )
46
+
47
+ # Signal 3: Exponential decay
48
+ signal3 = create_signal(
49
+ title="Exponential Decay",
50
+ x=x,
51
+ y=np.exp(-x / 3),
52
+ metadata={"type": "exponential", "time_constant": "3 s"},
53
+ )
54
+
55
+ return [signal1, signal2, signal3]
56
+
57
+
58
+ def create_test_images() -> list[ImageObj]:
59
+ """Create a list of test images for testing."""
60
+ # Image 1: Random noise
61
+ image1 = create_image(
62
+ title="Random Noise",
63
+ data=np.random.rand(100, 100),
64
+ metadata={"type": "noise", "distribution": "uniform"},
65
+ )
66
+
67
+ # Image 2: Gaussian pattern
68
+ x = np.linspace(-3, 3, 50)
69
+ y = np.linspace(-3, 3, 50)
70
+ X, Y = np.meshgrid(x, y)
71
+ image2 = create_image(
72
+ title="Gaussian Pattern",
73
+ data=np.exp(-(X**2 + Y**2)),
74
+ metadata={"type": "gaussian", "sigma": "1.0"},
75
+ )
76
+
77
+ # Image 3: Checkerboard pattern
78
+ data3 = np.zeros((100, 100))
79
+ data3[::10, ::10] = 1
80
+ data3[5::10, 5::10] = 1
81
+ image3 = create_image(
82
+ title="Checkerboard",
83
+ data=data3,
84
+ metadata={"type": "pattern", "period": "10 px"},
85
+ )
86
+
87
+ return [image1, image2, image3]
88
+
89
+
90
+ class TestAddMetadata:
91
+ """Test class for AddMetadataParam with proper setup/teardown."""
92
+
93
+ @pytest.fixture(autouse=True)
94
+ def setup_validation(self):
95
+ """Disable guidata validation during tests."""
96
+ old_mode = gcfg.get_validation_mode()
97
+ gcfg.set_validation_mode(gcfg.ValidationMode.DISABLED)
98
+ yield
99
+ gcfg.set_validation_mode(old_mode)
100
+
101
+ def test_string_values(self) -> None:
102
+ """Test adding string metadata values."""
103
+ execenv.print(f"{self.test_string_values.__doc__}:")
104
+
105
+ # Create test signals
106
+ signals = create_test_signals()
107
+
108
+ # Create parameter
109
+ p = AddMetadataParam(signals)
110
+ p.metadata_key = "test_string"
111
+ p.value_pattern = "{title}"
112
+ p.conversion = "string"
113
+
114
+ # Build values
115
+ values = p.build_values(signals)
116
+
117
+ expected_values = ["Sine Wave", "Cosine Wave", "Exponential Decay"]
118
+ assert values == expected_values, f"Expected {expected_values}, got {values}"
119
+ execenv.print(f" ✓ String values: {values}")
120
+
121
+ # Check preview
122
+ p.update_preview()
123
+ assert "test_string" in p.preview, "Preview should contain metadata key"
124
+ execenv.print(" ✓ Preview generated successfully")
125
+
126
+ execenv.print(f"{self.test_string_values.__doc__}: OK")
127
+
128
+ def test_numeric_values(self) -> None:
129
+ """Test adding numeric metadata values."""
130
+ execenv.print(f"{self.test_numeric_values.__doc__}:")
131
+
132
+ # Create test signals
133
+ signals = create_test_signals()
134
+
135
+ # Test integer conversion
136
+ p = AddMetadataParam(signals)
137
+ p.metadata_key = "index"
138
+ p.value_pattern = "{index}"
139
+ p.conversion = "int"
140
+
141
+ values = p.build_values(signals)
142
+ expected_values = [1, 2, 3]
143
+ assert values == expected_values, f"Expected {expected_values}, got {values}"
144
+ execenv.print(f" ✓ Integer values: {values}")
145
+
146
+ # Test float conversion
147
+ p.conversion = "float"
148
+ values = p.build_values(signals)
149
+ expected_values = [1.0, 2.0, 3.0]
150
+ assert values == expected_values, f"Expected {expected_values}, got {values}"
151
+ execenv.print(f" ✓ Float values: {values}")
152
+
153
+ execenv.print(f"{self.test_numeric_values.__doc__}: OK")
154
+
155
+ def test_boolean_values(self) -> None:
156
+ """Test adding boolean metadata values."""
157
+ execenv.print(f"{self.test_boolean_values.__doc__}:")
158
+
159
+ # Create test signals
160
+ signals = create_test_signals()
161
+
162
+ # Test boolean conversion with "true" pattern
163
+ p = AddMetadataParam(signals)
164
+ p.metadata_key = "is_valid"
165
+ p.value_pattern = "true"
166
+ p.conversion = "bool"
167
+
168
+ values = p.build_values(signals)
169
+ expected_values = [True, True, True]
170
+ assert values == expected_values, f"Expected {expected_values}, got {values}"
171
+ execenv.print(f" ✓ Boolean (true) values: {values}")
172
+
173
+ # Test boolean conversion with "false" pattern
174
+ p.value_pattern = "false"
175
+ values = p.build_values(signals)
176
+ expected_values = [False, False, False]
177
+ assert values == expected_values, f"Expected {expected_values}, got {values}"
178
+ execenv.print(f" ✓ Boolean (false) values: {values}")
179
+
180
+ execenv.print(f"{self.test_boolean_values.__doc__}: OK")
181
+
182
+ def test_pattern_formatting(self) -> None:
183
+ """Test various pattern formatting options."""
184
+ execenv.print(f"{self.test_pattern_formatting.__doc__}:")
185
+
186
+ # Create test signals
187
+ signals = create_test_signals()
188
+
189
+ # Test index with zero padding
190
+ p = AddMetadataParam(signals)
191
+ p.metadata_key = "file_id"
192
+ p.value_pattern = "file_{index:03d}"
193
+ p.conversion = "string"
194
+
195
+ values = p.build_values(signals)
196
+ expected_values = ["file_001", "file_002", "file_003"]
197
+ assert values == expected_values, f"Expected {expected_values}, got {values}"
198
+ execenv.print(f" ✓ Padded index pattern: {values}")
199
+
200
+ # Test uppercase modifier
201
+ p.value_pattern = "{title:upper}"
202
+ values = p.build_values(signals)
203
+ expected_values = ["SINE WAVE", "COSINE WAVE", "EXPONENTIAL DECAY"]
204
+ assert values == expected_values, f"Expected {expected_values}, got {values}"
205
+ execenv.print(f" ✓ Uppercase pattern: {values}")
206
+
207
+ # Test lowercase modifier
208
+ p.value_pattern = "{title:lower}"
209
+ values = p.build_values(signals)
210
+ expected_values = ["sine wave", "cosine wave", "exponential decay"]
211
+ assert values == expected_values, f"Expected {expected_values}, got {values}"
212
+ execenv.print(f" ✓ Lowercase pattern: {values}")
213
+
214
+ execenv.print(f"{self.test_pattern_formatting.__doc__}: OK")
215
+
216
+ def test_with_images(self) -> None:
217
+ """Test AddMetadataParam with image objects."""
218
+ execenv.print(f"{self.test_with_images.__doc__}:")
219
+
220
+ # Create test images
221
+ images = create_test_images()
222
+
223
+ # Create parameter
224
+ p = AddMetadataParam(images)
225
+ p.metadata_key = "category"
226
+ p.value_pattern = "{title:lower}"
227
+ p.conversion = "string"
228
+
229
+ # Build values
230
+ values = p.build_values(images)
231
+ expected_values = ["random noise", "gaussian pattern", "checkerboard"]
232
+ assert values == expected_values, f"Expected {expected_values}, got {values}"
233
+ execenv.print(f" ✓ Image metadata values: {values}")
234
+
235
+ # Check preview
236
+ p.update_preview()
237
+ assert "category" in p.preview, "Preview should contain metadata key"
238
+ # Check that all values are in the preview
239
+ for expected_val in expected_values:
240
+ assert expected_val in p.preview, f"Preview should contain {expected_val}"
241
+ execenv.print(" ✓ Preview contains all values")
242
+
243
+ execenv.print(f"{self.test_with_images.__doc__}: OK")
244
+
245
+ def test_error_handling(self) -> None:
246
+ """Test error handling for invalid patterns."""
247
+ execenv.print(f"{self.test_error_handling.__doc__}:")
248
+
249
+ # Create test signals
250
+ signals = create_test_signals()
251
+
252
+ # Test with invalid pattern
253
+ p = AddMetadataParam(signals)
254
+ p.metadata_key = "test"
255
+ p.value_pattern = "{invalid_key}" # This key doesn't exist
256
+ p.conversion = "string"
257
+
258
+ # Update preview should handle the error gracefully
259
+ p.update_preview()
260
+ assert "Invalid" in p.preview, "Preview should show invalid pattern error"
261
+ execenv.print(" ✓ Invalid pattern error handled")
262
+
263
+ execenv.print(f"{self.test_error_handling.__doc__}: OK")
264
+
265
+
266
+ if __name__ == "__main__":
267
+ pytest.main([__file__, "-v"])
@@ -0,0 +1,152 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """Unit tests for annotation copy/paste functionality."""
4
+
5
+ import os.path as osp
6
+
7
+ from sigima.tests import data as test_data
8
+
9
+ from datalab.env import execenv
10
+ from datalab.tests import datalab_test_app_context, helpers
11
+
12
+
13
+ def test_annotations_copy_paste():
14
+ """Test copying and pasting annotations between objects."""
15
+ with execenv.context(unattended=True):
16
+ with datalab_test_app_context() as win:
17
+ panel = win.signalpanel
18
+
19
+ # Create two signals
20
+ sig1 = test_data.create_paracetamol_signal()
21
+ sig2 = test_data.create_paracetamol_signal()
22
+
23
+ # Add annotations to first signal
24
+ orig_annotations = [
25
+ {"type": "label", "text": "Peak 1"},
26
+ {"type": "label", "text": "Peak 2"},
27
+ ]
28
+ sig1.set_annotations(orig_annotations)
29
+
30
+ # Add objects to panel - sig1 will be selected after this
31
+ panel.add_object(sig1)
32
+
33
+ # Copy from first signal (which is currently selected)
34
+ panel.copy_annotations()
35
+
36
+ # Add second signal - sig2 will be selected after this
37
+ panel.add_object(sig2)
38
+
39
+ # Paste to second signal (which is now selected)
40
+ panel.paste_annotations()
41
+
42
+ # Verify annotations were copied
43
+ assert sig2.get_annotations() == orig_annotations
44
+
45
+
46
+ def test_annotations_import_export():
47
+ """Test importing and exporting annotations to file."""
48
+ with execenv.context(unattended=True):
49
+ with helpers.WorkdirRestoringTempDir() as tmpdir:
50
+ fname = osp.join(tmpdir, "test.dlabann")
51
+ with datalab_test_app_context() as win:
52
+ panel = win.signalpanel
53
+
54
+ # Create signal with annotations
55
+ sig = test_data.create_paracetamol_signal()
56
+ orig_annotations = [{"type": "label", "text": "Test annotation"}]
57
+ sig.set_annotations(orig_annotations)
58
+
59
+ panel.add_object(sig)
60
+
61
+ # Export annotations
62
+ panel.export_annotations_from_file(fname)
63
+
64
+ # Clear annotations to test import
65
+ sig.clear_annotations()
66
+ assert len(sig.get_annotations()) == 0
67
+
68
+ # Import annotations
69
+ panel.import_annotations_from_file(fname)
70
+
71
+ # Verify annotations were imported
72
+ assert sig.get_annotations() == orig_annotations
73
+
74
+
75
+ def test_annotations_delete():
76
+ """Test deleting annotations from objects."""
77
+ with execenv.context(unattended=True):
78
+ with datalab_test_app_context() as win:
79
+ panel = win.signalpanel
80
+
81
+ # Create signal with annotations
82
+ sig = test_data.create_paracetamol_signal()
83
+ sig.set_annotations(
84
+ [
85
+ {"type": "label", "text": "To be deleted"},
86
+ ]
87
+ )
88
+
89
+ panel.add_object(sig)
90
+
91
+ # Verify annotations exist
92
+ assert len(sig.get_annotations()) == 1
93
+
94
+ # Delete annotations
95
+ panel.delete_annotations()
96
+
97
+ # Verify annotations were deleted
98
+ assert len(sig.get_annotations()) == 0
99
+
100
+
101
+ def test_annotations_action_states():
102
+ """Test that action states are updated after annotation operations.
103
+
104
+ This test verifies the fix for the issue where action enable states
105
+ were not updated after operations like delete_annotations, requiring
106
+ the user to select another object for the actions to update.
107
+
108
+ Note: We can't easily test the UI action states in automated tests,
109
+ but we verify that the underlying state update mechanism is called.
110
+ """
111
+ with execenv.context(unattended=True):
112
+ with datalab_test_app_context() as win:
113
+ panel = win.signalpanel
114
+
115
+ # Create signal with annotations
116
+ sig = test_data.create_paracetamol_signal()
117
+ orig_annotations = [{"type": "label", "text": "Test"}]
118
+ sig.set_annotations(orig_annotations)
119
+
120
+ panel.add_object(sig)
121
+
122
+ # Verify object has annotations
123
+ assert len(sig.get_annotations()) == 1
124
+
125
+ # Delete annotations - this should update action states
126
+ panel.delete_annotations()
127
+
128
+ # Verify annotations were deleted
129
+ assert len(sig.get_annotations()) == 0
130
+
131
+ # Verify clipboard is empty
132
+ assert len(panel.annotations_clipboard) == 0
133
+
134
+ # Re-add annotations and copy - this should update action states
135
+ sig.set_annotations(orig_annotations)
136
+ panel.selection_changed() # Refresh states
137
+ panel.copy_annotations()
138
+
139
+ # Verify clipboard now has annotations
140
+ assert len(panel.annotations_clipboard) == 1
141
+
142
+ # Clear annotations, paste, and verify
143
+ sig.clear_annotations()
144
+ panel.paste_annotations()
145
+ assert len(sig.get_annotations()) == 1
146
+
147
+
148
+ if __name__ == "__main__":
149
+ test_annotations_copy_paste()
150
+ test_annotations_import_export()
151
+ test_annotations_delete()
152
+ test_annotations_action_states()