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,118 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Pulse features application test.
5
+ """
6
+
7
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
8
+ # guitest: show
9
+
10
+ from sigima.objects import (
11
+ SignalObj,
12
+ TableKind,
13
+ TableResult,
14
+ create_signal_from_param,
15
+ create_signal_roi,
16
+ )
17
+ from sigima.params import PulseFeaturesParam
18
+ from sigima.tests.helpers import check_scalar_result
19
+ from sigima.tests.signal.pulse.pulse_unit_test import (
20
+ create_test_square_params,
21
+ create_test_step_params,
22
+ )
23
+
24
+ from datalab.adapters_metadata import TableAdapter
25
+ from datalab.gui.panel.signal import SignalPanel
26
+ from datalab.tests import datalab_test_app_context
27
+ from datalab.utils import qthelpers as qth
28
+
29
+
30
+ def __check_table(obj: SignalObj) -> TableResult:
31
+ """Check that the object has a pulse features table."""
32
+ tables = list(TableAdapter.iterate_from_obj(obj))
33
+ assert len(tables) == 1
34
+ table = tables[0].result
35
+ assert table.kind == TableKind.PULSE_FEATURES
36
+ return table
37
+
38
+
39
+ def __add_signal_and_check_pulse_features(
40
+ panel: SignalPanel, obj: SignalObj, assertions: dict[str, float]
41
+ ) -> None:
42
+ """Add signal to the application and check that pulse features are extracted."""
43
+ panel.add_object(obj)
44
+ param = PulseFeaturesParam()
45
+ param.update_from_obj(obj)
46
+ panel.processor.run_feature("extract_pulse_features", param)
47
+ table = __check_table(obj)
48
+ for name, expected_value in assertions.items():
49
+ if isinstance(expected_value, str):
50
+ assert table[name][0] == expected_value
51
+ else:
52
+ check_scalar_result(name, table[name][0], expected_value, rtol=1e-2)
53
+
54
+
55
+ def test_pulse_features_app():
56
+ """Pulse features application test."""
57
+ with datalab_test_app_context(console=False) as win:
58
+ panel = win.signalpanel
59
+
60
+ # Add first signal and extract features
61
+ s1 = create_signal_from_param(create_test_step_params())
62
+ __add_signal_and_check_pulse_features(
63
+ panel,
64
+ s1,
65
+ {
66
+ "signal_shape": "step",
67
+ "polarity": 1.0,
68
+ "amplitude": 4.9,
69
+ "rise_time": 1.5,
70
+ },
71
+ )
72
+
73
+ # Add second signal and extract features
74
+ s2 = create_signal_from_param(create_test_square_params())
75
+ __add_signal_and_check_pulse_features(
76
+ panel,
77
+ s2,
78
+ {
79
+ "signal_shape": "square",
80
+ "polarity": 1.0,
81
+ "amplitude": 4.94,
82
+ "rise_time": 1.60,
83
+ "fall_time": 3.95,
84
+ "fwhm": 5.49,
85
+ },
86
+ )
87
+
88
+ # Select the two signals and show the results table
89
+ panel.objview.select_objects([s1, s2])
90
+ panel.show_results()
91
+
92
+ # Define a ROI, just to test that it works (⚠️ it makes no sense here):
93
+ # it tests that the "comparison rows" features work correctly with ROIs.
94
+ # TODO: Maybe we should test this part in a more appropriate place, like in
95
+ # a test for the "statistics" feature.
96
+ roi = create_signal_roi([[0.650227, 5.8], [1.1596, 9.09509]])
97
+ s1.roi = roi
98
+ s2.roi = roi.copy()
99
+ panel.processor.run_feature("stats")
100
+
101
+ panel.show_results()
102
+
103
+
104
+ def pulse_features_screenshot():
105
+ """Generate pulse features screenshot."""
106
+ with datalab_test_app_context(size=(1400, 600), console=False) as win:
107
+ panel = win.signalpanel
108
+ s1 = create_signal_from_param(create_test_step_params())
109
+ panel.add_object(s1)
110
+ param = PulseFeaturesParam()
111
+ param.update_from_obj(s1)
112
+ panel.processor.run_feature("extract_pulse_features", param)
113
+ qth.grab_save_window(win.signalview, "s_pulse_features")
114
+
115
+
116
+ if __name__ == "__main__":
117
+ # test_pulse_features_app()
118
+ pulse_features_screenshot()
@@ -0,0 +1,55 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Pulse features with ROIs application test.
5
+ """
6
+
7
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
8
+ # guitest: show
9
+
10
+ from __future__ import annotations
11
+
12
+ from sigima.objects import SignalObj, TableResult
13
+ from sigima.params import PulseFeaturesParam
14
+ from sigima.tests.signal.pulse.pulse_features_roi_unit_test import (
15
+ check_results_equal,
16
+ generate_source_signal,
17
+ )
18
+
19
+ from datalab.gui.panel.signal import SignalPanel
20
+ from datalab.tests import datalab_test_app_context
21
+
22
+
23
+ def __extract_pulse_features(panel: SignalPanel, obj: SignalObj) -> TableResult:
24
+ """Extract pulse features."""
25
+ panel.objview.select_objects([obj])
26
+ param = PulseFeaturesParam()
27
+ param.update_from_obj(obj)
28
+ rdata = panel.processor.run_feature("extract_pulse_features", param)
29
+ assert len(rdata.results) == 1
30
+ return rdata.results[0]
31
+
32
+
33
+ def test_pulse_features_roi_app():
34
+ """Pulse features with ROIs application test."""
35
+ with datalab_test_app_context(console=False) as win:
36
+ panel = win.signalpanel
37
+
38
+ # Test signal with multiple ROIs defined around peaks of the spectrum
39
+ sig = generate_source_signal()
40
+ panel.add_object(sig)
41
+ pf_sig = __extract_pulse_features(panel, sig)
42
+
43
+ # Extract ROIs in separate signals and test each one
44
+ panel.processor.run_feature("extract_roi", params=sig.roi.to_params(sig))
45
+ pf_extracted_sigs = []
46
+ for nb_sig in (2, 3, 4):
47
+ extracted_sig = panel.objmodel.get_object_from_number(nb_sig)
48
+ pf_extracted_sig = __extract_pulse_features(panel, extracted_sig)
49
+ pf_extracted_sigs.append(pf_extracted_sig)
50
+
51
+ check_results_equal(pf_sig, pf_extracted_sigs)
52
+
53
+
54
+ if __name__ == "__main__":
55
+ test_pulse_features_roi_app()
@@ -0,0 +1,78 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """Signal ROI application test"""
4
+
5
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
6
+ # guitest: show
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import TYPE_CHECKING
11
+
12
+ import pytest
13
+ import sigima.params as sigima_param
14
+ from sigima.objects import SignalROI, create_signal_roi
15
+ from sigima.tests.data import create_paracetamol_signal
16
+
17
+ from datalab.config import Conf
18
+ from datalab.env import execenv
19
+ from datalab.tests import datalab_test_app_context, helpers
20
+
21
+ if TYPE_CHECKING:
22
+ from datalab.gui.panel.signal import SignalPanel
23
+
24
+ SIZE = 200
25
+
26
+ # Signal ROIs:
27
+ SROI1 = [26, 41]
28
+ SROI2 = [125, 146]
29
+
30
+
31
+ def __run_signal_computations(panel: SignalPanel):
32
+ """Test all signal features related to ROI"""
33
+ panel.processor.run_feature("fwhm", sigima_param.FWHMParam())
34
+ panel.processor.run_feature("fw1e2")
35
+ panel.processor.run_feature("histogram", sigima_param.HistogramParam())
36
+ roi = SignalROI()
37
+ panel.processor.compute_roi_extraction(roi)
38
+
39
+
40
+ def test_signal_roi_app(screenshots: bool = False) -> None:
41
+ """Run Signal ROI application test scenario
42
+
43
+ Args:
44
+ screenshots: If True, take screenshots during the test.
45
+ """
46
+ with datalab_test_app_context(console=False) as win:
47
+ execenv.print("Signal ROI application test:")
48
+ panel = win.signalpanel
49
+ sig1 = create_paracetamol_signal(SIZE)
50
+ panel.add_object(sig1)
51
+ __run_signal_computations(panel)
52
+ sig2 = create_paracetamol_signal(SIZE)
53
+ sig2.roi = create_signal_roi([SROI1, SROI2], indices=True)
54
+ for singleobj in (False, True):
55
+ with Conf.proc.extract_roi_singleobj.temp(singleobj):
56
+ sig2_i = sig2.copy()
57
+ panel.add_object(sig2_i)
58
+ helpers.print_obj_data_dimensions(sig2_i, indent=1)
59
+ panel.processor.edit_roi_graphically()
60
+ if screenshots:
61
+ win.statusBar().hide()
62
+ win.take_screenshot("s_roi_signal")
63
+ __run_signal_computations(panel)
64
+
65
+
66
+ @pytest.mark.skip(reason="This test is only for manual testing")
67
+ def test_signal_roi_basic_app():
68
+ """Run Signal ROI basic application test scenario"""
69
+ with datalab_test_app_context(console=False) as win:
70
+ panel = win.signalpanel
71
+ sig1 = create_paracetamol_signal(SIZE)
72
+ panel.add_object(sig1)
73
+ panel.processor.edit_roi_graphically()
74
+
75
+
76
+ if __name__ == "__main__":
77
+ test_signal_roi_basic_app()
78
+ test_signal_roi_app(screenshots=False)
@@ -0,0 +1,261 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """Signal ROI manipulation application test (copy/paste, import/export)"""
4
+
5
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
6
+ # guitest: show
7
+
8
+ from __future__ import annotations
9
+
10
+ import os
11
+ import tempfile
12
+ from typing import TYPE_CHECKING
13
+
14
+ from sigima.io import read_roi
15
+ from sigima.objects import create_signal_roi
16
+ from sigima.tests.data import create_paracetamol_signal
17
+
18
+ from datalab.env import execenv
19
+ from datalab.objectmodel import get_uuid
20
+ from datalab.tests import datalab_test_app_context
21
+
22
+ if TYPE_CHECKING:
23
+ from datalab.gui.panel.signal import SignalPanel
24
+
25
+ SIZE = 200
26
+
27
+ # Signal ROIs:
28
+ SROI1 = [26, 41]
29
+ SROI2 = [125, 146]
30
+ SROI3 = [60, 80]
31
+
32
+
33
+ def test_signal_roi_copy_paste():
34
+ """Test signal ROI copy and paste functionality"""
35
+ with datalab_test_app_context(console=False) as win:
36
+ execenv.print("Signal ROI Copy/Paste test:")
37
+ panel: SignalPanel = win.signalpanel
38
+
39
+ # Create first signal with ROI
40
+ sig1 = create_paracetamol_signal(SIZE)
41
+ sig1.title = "Signal with ROI"
42
+ roi1 = create_signal_roi([SROI1, SROI2], indices=True)
43
+ sig1.roi = roi1
44
+ panel.add_object(sig1)
45
+
46
+ # Create second signal without ROI
47
+ sig2 = create_paracetamol_signal(SIZE)
48
+ sig2.title = "Signal without ROI"
49
+ panel.add_object(sig2)
50
+
51
+ # Create third signal without ROI
52
+ sig3 = create_paracetamol_signal(SIZE)
53
+ sig3.title = "Signal without ROI 2"
54
+ panel.add_object(sig3)
55
+
56
+ execenv.print(" Initial state:")
57
+ execenv.print(f" Signal 1 ROI: {sig1.roi is not None}")
58
+ execenv.print(f" Signal 2 ROI: {sig2.roi is not None}")
59
+ execenv.print(f" Signal 3 ROI: {sig3.roi is not None}")
60
+
61
+ # Select first signal and copy its ROI
62
+ panel.objview.set_current_item_id(get_uuid(sig1))
63
+ panel.copy_roi()
64
+ execenv.print(" Copied ROI from Signal 1")
65
+
66
+ # Select second signal and paste ROI
67
+ panel.objview.set_current_item_id(get_uuid(sig2))
68
+ panel.paste_roi()
69
+ execenv.print(" Pasted ROI to Signal 2")
70
+
71
+ # Verify that sig2 now has the same ROI as sig1
72
+ assert sig2.roi is not None, "Signal 2 should have ROI after paste"
73
+ assert len(sig2.roi) == len(sig1.roi), "ROI should have same number of regions"
74
+ execenv.print(f" Signal 2 now has {len(sig2.roi)} ROI regions")
75
+
76
+ # Select third signal and paste ROI (should create new ROI)
77
+ panel.objview.set_current_item_id(get_uuid(sig3))
78
+ panel.paste_roi()
79
+ execenv.print(" Pasted ROI to Signal 3")
80
+
81
+ assert sig3.roi is not None, "Signal 3 should have ROI after paste"
82
+ assert len(sig3.roi) == len(sig1.roi), "ROI should have same number of regions"
83
+ execenv.print(f" Signal 3 now has {len(sig3.roi)} ROI regions")
84
+
85
+ # Test pasting to signal that already has ROI (should combine)
86
+ panel.objview.set_current_item_id(get_uuid(sig2))
87
+ panel.copy_roi()
88
+ execenv.print(" Copied ROI from Signal 2")
89
+
90
+ # Add a different ROI to sig1
91
+ roi_new = create_signal_roi([SROI3], indices=True)
92
+ sig1.roi = sig1.roi.combine_with(roi_new)
93
+ original_roi_count = len(sig1.roi)
94
+ execenv.print(f" Signal 1 now has {original_roi_count} ROI regions")
95
+
96
+ # Paste the ROI from sig2 into sig1 (should combine)
97
+ panel.objview.set_current_item_id(get_uuid(sig1))
98
+ panel.paste_roi()
99
+ execenv.print(" Pasted ROI to Signal 1 (should combine)")
100
+
101
+ # Get fresh reference to sig1 from panel
102
+ sig1_updated = panel.objmodel[get_uuid(sig1)]
103
+ assert sig1_updated.roi is not None, "Signal 1 should still have ROI"
104
+ # After combining, sig1 should have more regions than before
105
+ assert len(sig1_updated.roi) >= original_roi_count, (
106
+ f"Expected at least {original_roi_count} ROI regions, "
107
+ f"got {len(sig1_updated.roi)}"
108
+ )
109
+ execenv.print(
110
+ f" Signal 1 now has {len(sig1_updated.roi)} ROI regions (combined)"
111
+ )
112
+
113
+ execenv.print(" ✓ Signal ROI copy/paste test passed")
114
+
115
+
116
+ def test_signal_roi_copy_paste_multiple_selection():
117
+ """Test signal ROI paste to multiple selected signals"""
118
+ with datalab_test_app_context(console=False) as win:
119
+ execenv.print("Signal ROI Copy/Paste with multiple selection test:")
120
+ panel: SignalPanel = win.signalpanel
121
+
122
+ # Create source signal with ROI
123
+ sig_src = create_paracetamol_signal(SIZE)
124
+ sig_src.title = "Source with ROI"
125
+ roi = create_signal_roi([SROI1, SROI2], indices=True)
126
+ sig_src.roi = roi
127
+ panel.add_object(sig_src)
128
+
129
+ # Create multiple target signals without ROI
130
+ target_signals = []
131
+ for i in range(3):
132
+ sig = create_paracetamol_signal(SIZE)
133
+ sig.title = f"Target signal {i + 1}"
134
+ panel.add_object(sig)
135
+ target_signals.append(sig)
136
+
137
+ execenv.print(f" Created {len(target_signals)} target signals")
138
+
139
+ # Copy ROI from source
140
+ panel.objview.set_current_item_id(get_uuid(sig_src))
141
+ panel.copy_roi()
142
+ execenv.print(" Copied ROI from source signal")
143
+
144
+ # Select all target signals
145
+ target_uuids = [get_uuid(sig) for sig in target_signals]
146
+ panel.objview.set_current_item_id(target_uuids[0])
147
+ for uuid in target_uuids[1:]:
148
+ panel.objview.set_current_item_id(uuid, extend=True)
149
+
150
+ execenv.print(f" Selected {len(target_uuids)} target signals")
151
+
152
+ # Paste ROI to all selected signals
153
+ panel.paste_roi()
154
+ execenv.print(" Pasted ROI to all selected signals")
155
+
156
+ # Verify all target signals have ROI
157
+ for i, sig in enumerate(target_signals):
158
+ assert sig.roi is not None, f"Target signal {i + 1} should have ROI"
159
+ assert len(sig.roi) == len(sig_src.roi), (
160
+ f"Target signal {i + 1} should have {len(sig_src.roi)} ROI regions"
161
+ )
162
+ execenv.print(f" Target signal {i + 1}: {len(sig.roi)} ROI regions ✓")
163
+
164
+ execenv.print(" ✓ Multiple selection paste test passed")
165
+
166
+
167
+ def test_signal_roi_import_export():
168
+ """Test signal ROI import and export to/from file functionality"""
169
+ with datalab_test_app_context(console=False) as win:
170
+ execenv.print("Signal ROI Import/Export test:")
171
+ panel: SignalPanel = win.signalpanel
172
+
173
+ # Create first signal with ROI
174
+ sig1 = create_paracetamol_signal(SIZE)
175
+ sig1.title = "Signal with ROI"
176
+ roi1 = create_signal_roi([SROI1, SROI2, SROI3], indices=True)
177
+ sig1.roi = roi1
178
+ panel.add_object(sig1)
179
+
180
+ original_roi_count = len(sig1.roi)
181
+ execenv.print(f" Signal 1 has {original_roi_count} ROI regions")
182
+
183
+ # Export ROI to file
184
+ roi_file = tempfile.mktemp(suffix=".dlabroi")
185
+ try:
186
+ execenv.print(" Exporting ROI to temporary file")
187
+
188
+ # Select first signal and export its ROI
189
+ panel.objview.set_current_item_id(get_uuid(sig1))
190
+ panel.export_roi_to_file(roi_file)
191
+ execenv.print(" ✓ ROI exported")
192
+
193
+ # Verify file was created
194
+ assert os.path.exists(roi_file), "ROI file should have been created"
195
+
196
+ # Read the exported ROI directly to verify content
197
+ exported_roi = read_roi(roi_file)
198
+ assert len(exported_roi) == original_roi_count, (
199
+ f"Exported ROI should have {original_roi_count} regions"
200
+ )
201
+ execenv.print(f" ✓ Exported ROI has {len(exported_roi)} regions")
202
+
203
+ # Create second signal without ROI
204
+ sig2 = create_paracetamol_signal(SIZE)
205
+ sig2.title = "Signal without ROI"
206
+ panel.add_object(sig2)
207
+ assert sig2.roi is None, "Signal 2 should not have ROI initially"
208
+
209
+ # Import ROI from file to second signal
210
+ panel.objview.set_current_item_id(get_uuid(sig2))
211
+ panel.import_roi_from_file(roi_file)
212
+ execenv.print(" Imported ROI to Signal 2")
213
+
214
+ # Get fresh reference to sig2 from panel
215
+ sig2_updated = panel.objmodel[get_uuid(sig2)]
216
+ assert sig2_updated.roi is not None, "Signal 2 should have ROI after import"
217
+ assert len(sig2_updated.roi) == original_roi_count, (
218
+ f"Imported ROI should have {original_roi_count} regions"
219
+ )
220
+ execenv.print(f" ✓ Signal 2 now has {len(sig2_updated.roi)} ROI regions")
221
+
222
+ # Test importing ROI to signal that already has ROI (should combine)
223
+ sig3 = create_paracetamol_signal(SIZE)
224
+ sig3.title = "Signal with existing ROI"
225
+ roi3 = create_signal_roi([[90, 110]], indices=True)
226
+ sig3.roi = roi3
227
+ panel.add_object(sig3)
228
+ initial_roi_count = len(sig3.roi)
229
+ execenv.print(f" Signal 3 has {initial_roi_count} ROI region initially")
230
+
231
+ # Import ROI (should combine with existing)
232
+ panel.objview.set_current_item_id(get_uuid(sig3))
233
+ panel.import_roi_from_file(roi_file)
234
+ execenv.print(" Imported ROI to Signal 3 (should combine)")
235
+
236
+ # Get fresh reference to sig3 from panel
237
+ sig3_updated = panel.objmodel[get_uuid(sig3)]
238
+ assert sig3_updated.roi is not None, "Signal 3 should still have ROI"
239
+ # After combining, should have more regions
240
+ assert len(sig3_updated.roi) >= initial_roi_count, (
241
+ f"Expected at least {initial_roi_count} ROI regions, "
242
+ f"got {len(sig3_updated.roi)}"
243
+ )
244
+ execenv.print(
245
+ f" ✓ Signal 3 now has {len(sig3_updated.roi)} ROI regions (combined)"
246
+ )
247
+ finally:
248
+ # Clean up temporary file
249
+ if os.path.exists(roi_file):
250
+ try:
251
+ os.unlink(roi_file)
252
+ except (PermissionError, OSError):
253
+ pass # Ignore cleanup errors on Windows
254
+
255
+ execenv.print(" ✓ Signal ROI import/export test passed")
256
+
257
+
258
+ if __name__ == "__main__":
259
+ test_signal_roi_copy_paste()
260
+ test_signal_roi_copy_paste_multiple_selection()
261
+ test_signal_roi_import_export()
@@ -0,0 +1,46 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Signal horizontal or vertical cursor selection unit test.
5
+ """
6
+
7
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
8
+ # guitest: show
9
+
10
+ from typing import Literal
11
+
12
+ import numpy as np
13
+ import pytest
14
+ from guidata.qthelpers import exec_dialog, qt_app_context
15
+ from sigima.tests.data import create_paracetamol_signal
16
+ from sigima.tools.signal.features import find_x_values_at_y
17
+
18
+ from datalab.env import execenv
19
+ from datalab.widgets.signalcursor import SignalCursorDialog
20
+
21
+
22
+ @pytest.mark.parametrize("cursor_orientation", ["horizontal", "vertical"])
23
+ def test_signal_cursor_selection(
24
+ cursor_orientation: Literal["horizontal", "vertical"],
25
+ ) -> None:
26
+ """Parametrized signal cursor selection unit test."""
27
+ sig = create_paracetamol_signal()
28
+ with qt_app_context():
29
+ dlg = SignalCursorDialog(signal=sig, cursor_orientation=cursor_orientation)
30
+ dlg.resize(640, 480)
31
+ dlg.setObjectName(dlg.objectName() + "_00") # to avoid timestamp suffix
32
+ exec_dialog(dlg)
33
+ x, y = dlg.get_cursor_position()
34
+ if cursor_orientation == "horizontal":
35
+ execenv.print(f"X value: {x}")
36
+ x_sig = find_x_values_at_y(sig.x, sig.y, y)[0]
37
+ assert x == x_sig, f"Expected {x_sig}, got {x}"
38
+ else:
39
+ execenv.print(f"Y value: {y}")
40
+ y_sig = sig.y[np.searchsorted(sig.x, x)]
41
+ assert y == y_sig, f"Expected {y_sig}, got {y}"
42
+
43
+
44
+ if __name__ == "__main__":
45
+ test_signal_cursor_selection(cursor_orientation="horizontal")
46
+ test_signal_cursor_selection(cursor_orientation="vertical")
@@ -0,0 +1,33 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Signal peak detection dialog test.
5
+ """
6
+
7
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
8
+ # guitest: show
9
+
10
+ from guidata.qthelpers import exec_dialog, qt_app_context
11
+ from sigima.tests.data import get_test_signal
12
+
13
+ from datalab.env import execenv
14
+ from datalab.widgets.signalpeak import SignalPeakDetectionDialog
15
+
16
+
17
+ def test_peak1d_dialog():
18
+ """Signal peak dialog test"""
19
+ with qt_app_context():
20
+ s = get_test_signal("paracetamol.txt")
21
+ dlg = SignalPeakDetectionDialog(s)
22
+ dlg.resize(640, 300)
23
+ plot = dlg.get_plot()
24
+ plot.set_axis_limits(plot.xBottom, 16, 30)
25
+ dlg.setObjectName(dlg.objectName() + "_00") # to avoid timestamp suffix
26
+ exec_dialog(dlg)
27
+ execenv.print("peaks:")
28
+ execenv.pprint(dlg.get_peaks())
29
+ execenv.pprint(dlg.get_min_dist())
30
+
31
+
32
+ if __name__ == "__main__":
33
+ test_peak1d_dialog()
@@ -0,0 +1,98 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """Signals to image conversion application test"""
4
+
5
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
6
+ # guitest: show
7
+
8
+ from __future__ import annotations
9
+
10
+ import sigima.params
11
+ from sigima.enums import NormalizationMethod, SignalsToImageOrientation
12
+ from sigima.objects import SignalTypes
13
+ from sigima.tests.data import create_periodic_signal
14
+
15
+ from datalab.env import execenv
16
+ from datalab.tests import datalab_test_app_context
17
+
18
+ SIZE = 100
19
+ N_SIGNALS = 10
20
+
21
+
22
+ def test_signals_to_image_app(screenshots: bool = False) -> None:
23
+ """Run signals to image conversion application test scenario
24
+
25
+ Args:
26
+ screenshots: If True, take screenshots during the test.
27
+ """
28
+ with datalab_test_app_context(console=False) as win:
29
+ execenv.print("Signals to image conversion application test:")
30
+
31
+ # Create multiple test signals
32
+ for i in range(N_SIGNALS):
33
+ sig = create_periodic_signal(
34
+ SignalTypes.SINE, freq=50.0 + i * 10.0, size=SIZE, a=(i + 1) * 0.1
35
+ )
36
+ sig.title = f"Signal {i + 1}"
37
+ win.signalpanel.add_object(sig)
38
+
39
+ # Select all signals
40
+ win.signalpanel.objview.select_objects(list(range(1, N_SIGNALS + 1)))
41
+
42
+ # Test without normalization, as rows
43
+ p = sigima.params.SignalsToImageParam()
44
+ p.orientation = SignalsToImageOrientation.ROWS
45
+ p.normalize = False
46
+ win.signalpanel.processor.run_feature("signals_to_image", p)
47
+
48
+ if screenshots:
49
+ win.statusBar().hide()
50
+ win.take_screenshot("s_signals_to_image_rows")
51
+
52
+ # Select all signals again
53
+ win.set_current_panel("signal")
54
+ win.signalpanel.objview.select_objects(list(range(1, N_SIGNALS + 1)))
55
+
56
+ # Test without normalization, as columns
57
+ p.orientation = SignalsToImageOrientation.COLUMNS
58
+ win.signalpanel.processor.run_feature("signals_to_image", p)
59
+
60
+ if screenshots:
61
+ win.take_screenshot("s_signals_to_image_columns")
62
+
63
+ # Select all signals again
64
+ win.set_current_panel("signal")
65
+ win.signalpanel.objview.select_objects(list(range(1, N_SIGNALS + 1)))
66
+
67
+ # Test with normalization, as rows
68
+ p.orientation = SignalsToImageOrientation.ROWS
69
+ p.normalize = True
70
+ p.normalize_method = NormalizationMethod.MAXIMUM
71
+ win.signalpanel.processor.run_feature("signals_to_image", p)
72
+
73
+ if screenshots:
74
+ win.take_screenshot("s_signals_to_image_normalized")
75
+
76
+ # Verify that images were created
77
+ assert len(win.imagepanel) == 3, f"Expected 3 images, got {len(win.imagepanel)}"
78
+
79
+ # Switch to image panel to verify dimensions
80
+ win.set_current_panel("image")
81
+
82
+ # Verify image dimensions - get objects directly from object model
83
+ images = win.imagepanel.objmodel.get_all_objects()
84
+ assert len(images) == 3, f"Expected 3 images in object model, got {len(images)}"
85
+ assert images[0].data.shape == (
86
+ N_SIGNALS,
87
+ SIZE,
88
+ ), f"Expected shape ({N_SIGNALS}, {SIZE}), got {images[0].data.shape}"
89
+ assert images[1].data.shape == (
90
+ SIZE,
91
+ N_SIGNALS,
92
+ ), f"Expected shape ({SIZE}, {N_SIGNALS}), got {images[1].data.shape}"
93
+
94
+ execenv.print(" ✓ Signals to image conversion test passed")
95
+
96
+
97
+ if __name__ == "__main__":
98
+ test_signals_to_image_app(screenshots=False)