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,396 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """Unit test for geometry transformation operations."""
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing import Callable
9
+
10
+ import numpy as np
11
+ import sigima.objects as sio
12
+ import sigima.params as sip
13
+ import sigima.proc.image as sipi
14
+ from sigima.tests import data as test_data
15
+
16
+ from datalab.adapters_metadata.geometry_adapter import GeometryAdapter
17
+ from datalab.gui.processor.image import apply_geometry_transform
18
+ from datalab.tests import datalab_test_app_context
19
+
20
+
21
+ def __create_test_image() -> sio.ImageObj:
22
+ """Create a test image with geometry results for testing."""
23
+ param = sio.Gauss2DParam.create(
24
+ height=600,
25
+ width=600,
26
+ x0=2.5,
27
+ y0=7.5,
28
+ title="Test image (with geometry results)",
29
+ dtype=sio.ImageDatatypes.UINT16,
30
+ )
31
+ obj = sio.create_image_from_param(param)
32
+ for geometry in test_data.generate_geometry_results():
33
+ GeometryAdapter(geometry).add_to(obj)
34
+ obj.roi = sio.create_image_roi("rectangle", [10, 10, 50, 400])
35
+ return obj
36
+
37
+
38
+ def __get_geometries(obj: sio.ImageObj) -> list[sio.GeometryResult]:
39
+ """Get geometries from an image object."""
40
+ return [ga.result for ga in GeometryAdapter.iterate_from_obj(obj)]
41
+
42
+
43
+ def __get_expected_geometry_result(
44
+ orig_geom: sio.GeometryResult, operation: str
45
+ ) -> sio.GeometryResult:
46
+ """Get expected geometry result for a given operation.
47
+
48
+ Args:
49
+ orig_geom: Original geometry result
50
+ operation: Operation name (rotate90, rotate270, etc.)
51
+
52
+ Returns:
53
+ Expected geometry result after transformation
54
+ """
55
+ # For image transformations, rotations should be around the image center
56
+ # (300, 300 for our 600x600 test image)
57
+ xc, yc = (300.0, 300.0)
58
+
59
+ if operation == "rotate90":
60
+ exp_geom = sipi.transformer.rotate(orig_geom, -np.pi / 2, (xc, yc))
61
+ elif operation == "rotate270":
62
+ exp_geom = sipi.transformer.rotate(orig_geom, np.pi / 2, (xc, yc))
63
+ elif operation == "fliph":
64
+ exp_geom = sipi.transformer.fliph(orig_geom, xc)
65
+ elif operation == "flipv":
66
+ exp_geom = sipi.transformer.flipv(orig_geom, yc)
67
+ elif operation == "transpose":
68
+ exp_geom = sipi.transformer.transpose(orig_geom)
69
+ elif operation == "resize":
70
+ # Resize changes pixel resolution but keeps physical coordinates unchanged
71
+ exp_geom = orig_geom
72
+ elif operation == "binning":
73
+ # Binning changes pixel resolution but keeps physical coordinates unchanged
74
+ exp_geom = orig_geom
75
+ else:
76
+ raise ValueError(f"Unknown operation: {operation}")
77
+ return exp_geom
78
+
79
+
80
+ def __validate_geometry_transformation(
81
+ tr_geometries: list[sio.GeometryResult],
82
+ or_geometries: list[sio.GeometryResult],
83
+ operation: str,
84
+ test_context: str = "geometry",
85
+ ) -> None:
86
+ """Validate that geometry transformation was applied correctly.
87
+
88
+ Args:
89
+ tr_geometries: List of transformed geometry results
90
+ or_geometries: List of original geometry results
91
+ operation: Operation name (rotate90, rotate270, etc.)
92
+ test_context: Context string for error messages (e.g., "App", "Unit")
93
+ """
94
+ for i, tr_geom in enumerate(tr_geometries):
95
+ original_geom = or_geometries[i]
96
+ expected_geom = __get_expected_geometry_result(original_geom, operation)
97
+
98
+ # Compare the actual transformation result with expected
99
+ np.testing.assert_allclose(
100
+ tr_geom.coords,
101
+ expected_geom.coords,
102
+ rtol=1e-10,
103
+ err_msg=f"{test_context} geometry result {i} "
104
+ f"({tr_geom.title}) coordinates do not match expected for {operation}. "
105
+ f"Got: {tr_geom.coords}, Expected: {expected_geom.coords}",
106
+ )
107
+
108
+ # Verify other properties are preserved
109
+ assert tr_geom.title == expected_geom.title, (
110
+ f"Title should be preserved for geometry {i} in {operation}"
111
+ )
112
+ assert tr_geom.kind == expected_geom.kind, (
113
+ f"Kind should be preserved for geometry {i} in {operation}"
114
+ )
115
+ np.testing.assert_array_equal(
116
+ tr_geom.roi_indices,
117
+ expected_geom.roi_indices,
118
+ err_msg=f"ROI indices should be preserved for geometry {i} in {operation}",
119
+ )
120
+
121
+
122
+ def __validate_basic_transformation(tr_obj: sio.ImageObj, or_obj: sio.ImageObj) -> None:
123
+ """Validate basic transformation requirements.
124
+
125
+ Args:
126
+ tr_obj: The transformed image object
127
+ or_obj: The original image object
128
+ """
129
+ assert tr_obj is not or_obj, "Transformation should create a new object"
130
+ assert len(tr_obj.metadata) == len(or_obj.metadata), (
131
+ "Number of geometry results should be preserved"
132
+ )
133
+
134
+
135
+ def __validate_roi_transformation(
136
+ tr_obj: sio.ImageObj,
137
+ or_obj: sio.ImageObj,
138
+ operation: str,
139
+ ) -> None:
140
+ """Validate that ROI is properly transformed.
141
+
142
+ Args:
143
+ tr_obj: The transformed image object
144
+ or_obj: Original image object
145
+ operation: Operation name for expected transformation
146
+ """
147
+ tr_roi = tr_obj.roi
148
+ assert tr_roi is not None, "ROI should not be removed after transformation"
149
+ assert len(tr_roi.single_rois) == len(or_obj.roi.single_rois), (
150
+ "Number of ROI objects should be preserved"
151
+ )
152
+ # Validate that the ROI coordinates were properly transformed
153
+ for i, roi in enumerate(tr_roi.single_rois):
154
+ # Temporary transform the ROI into a geometry result:
155
+ or_roi = or_obj.roi.get_single_roi(i)
156
+ temp_geom = sio.GeometryResult(
157
+ "temp_geom",
158
+ sio.KindShape.RECTANGLE,
159
+ coords=np.asarray([or_roi.get_physical_coords(or_obj)]),
160
+ )
161
+ expected_geom = __get_expected_geometry_result(temp_geom, operation)
162
+ exp_coords = expected_geom.coords[0]
163
+ np.testing.assert_allclose(
164
+ roi.get_physical_coords(tr_obj),
165
+ exp_coords,
166
+ rtol=1e-10,
167
+ atol=1e-10,
168
+ err_msg=f"ROI {i} coordinates do not match expected for {operation}.",
169
+ )
170
+
171
+
172
+ def __validate_image_data_transformation(
173
+ tr_obj: sio.ImageObj, or_obj: sio.ImageObj, operation: str
174
+ ) -> None:
175
+ """Validate that image data was properly transformed.
176
+
177
+ Args:
178
+ tr_obj: The transformed image object
179
+ or_obj: Original image object
180
+ operation: Operation name for expected transformation
181
+ """
182
+ if operation == "rotate90":
183
+ expected_data = np.rot90(or_obj.data)
184
+ elif operation == "rotate270":
185
+ expected_data = np.rot90(or_obj.data, k=-1)
186
+ elif operation == "fliph":
187
+ expected_data = np.fliplr(or_obj.data)
188
+ elif operation == "flipv":
189
+ expected_data = np.flipud(or_obj.data)
190
+ elif operation == "transpose":
191
+ expected_data = np.transpose(or_obj.data)
192
+ elif operation in ("resize", "binning"):
193
+ # These operations are more complex and use Sigima's functions
194
+ # We'll just verify the operation was applied (shape may change)
195
+ return
196
+ else:
197
+ raise ValueError(f"Unknown operation for data validation: {operation}")
198
+
199
+ np.testing.assert_array_equal(
200
+ tr_obj.data,
201
+ expected_data,
202
+ err_msg=f"Image data not properly transformed for {operation}",
203
+ )
204
+
205
+
206
+ # =============================================================================
207
+ # Unit Tests
208
+ # =============================================================================
209
+
210
+
211
+ def __create_unit_test(
212
+ operation: str,
213
+ param_creator: Callable[
214
+ [], sip.BinningParam | sip.ResizeParam | sip.RotateParam
215
+ ] = None,
216
+ ) -> Callable[[], None]:
217
+ """Create a unit test function for a geometry transformation operation.
218
+
219
+ Args:
220
+ operation: Operation name (e.g., "rotate90", "fliph")
221
+ param_creator: Function to create parameter object, if needed
222
+
223
+ Returns:
224
+ Test function
225
+ """
226
+
227
+ def test_func() -> None:
228
+ """Test geometry transformation at unit level."""
229
+ obj = __create_test_image()
230
+ or_geometries = __get_geometries(obj) # Store original data for comparison
231
+
232
+ # Apply transformation (same as DataLab processor does)
233
+ param = param_creator() if param_creator else None
234
+ compfunc = getattr(sipi, operation, None)
235
+ if compfunc is None:
236
+ raise ValueError(f"Unknown operation: {operation}")
237
+ if param is None:
238
+ tr_obj = compfunc(obj)
239
+ else:
240
+ tr_obj = compfunc(obj, param)
241
+
242
+ # Apply the geometry transformation to the result
243
+ # (skip geometry transformation for resize and binning as they preserve
244
+ # physical coordinates)
245
+ if operation not in ["resize", "binning"]:
246
+ apply_geometry_transform(tr_obj, operation)
247
+
248
+ # Validate basic transformation requirements
249
+ __validate_basic_transformation(tr_obj, obj)
250
+
251
+ # Validate geometry transformation
252
+ tr_geometries = __get_geometries(tr_obj)
253
+ __validate_geometry_transformation(
254
+ tr_geometries, or_geometries, operation, "Unit"
255
+ )
256
+
257
+ # Validate ROI transformation (only for simple operations)
258
+ simple_ops = ["fliph", "flipv", "transpose"]
259
+ if operation in simple_ops:
260
+ __validate_roi_transformation(tr_obj, obj, operation)
261
+
262
+ # Set proper function name and docstring
263
+ test_func.__name__ = f"test_geometry_transform_{operation}_unit"
264
+ test_func.__doc__ = (
265
+ f"Test geometry transformation for {operation} at unit level.\n\n"
266
+ f"This test verifies that the DataLab geometry transformation properly "
267
+ f"applies Sigima's {operation} function to geometry results."
268
+ )
269
+
270
+ return test_func
271
+
272
+
273
+ def __create_app_test(
274
+ operation: str,
275
+ param_creator: Callable[
276
+ [], sip.BinningParam | sip.ResizeParam | sip.RotateParam
277
+ ] = None,
278
+ ) -> Callable[[], None]:
279
+ """Create an app test function for a geometry transformation operation.
280
+
281
+ Args:
282
+ operation: Operation name (e.g., "rotate90", "fliph")
283
+ param_creator: Function to create parameter object, if needed
284
+
285
+ Returns:
286
+ Test function
287
+ """
288
+
289
+ def test_func() -> None:
290
+ """Test operation at application level through direct processing."""
291
+ with datalab_test_app_context() as win:
292
+ panel = win.imagepanel
293
+ proc = panel.processor
294
+
295
+ obj = __create_test_image()
296
+ panel.add_object(obj)
297
+ panel.objview.select_objects((1,))
298
+
299
+ # Apply operation using app workflow
300
+ param = param_creator() if param_creator else None
301
+ if param is None:
302
+ proc.run_feature(operation)
303
+ else:
304
+ proc.run_feature(operation, param=param)
305
+ tr_obj = panel[len(panel)]
306
+
307
+ # # Validate basic transformation requirements
308
+ # __validate_basic_transformation(tr_obj, obj)
309
+
310
+ # # Validate geometry transformation
311
+ # tr_geometries = __get_geometries(tr_obj)
312
+ # __validate_geometry_transformation(
313
+ # tr_geometries, or_geometries, operation, "App", param
314
+ # )
315
+
316
+ # Verify that image data is properly transformed
317
+ __validate_image_data_transformation(tr_obj, obj, operation)
318
+
319
+ # For simple transformations, validate ROI transformation
320
+ # Skip ROI validation for rotation operations due to inconsistency in Sigima
321
+ # library between image data rotation (around image center) and ROI coordinate
322
+ # rotation (around ROI center)
323
+ simple_ops = ["fliph", "flipv", "transpose"]
324
+ if operation in simple_ops:
325
+ __validate_roi_transformation(tr_obj, obj, operation)
326
+
327
+ # Set proper function name and docstring
328
+ test_func.__name__ = f"test_geometry_transform_{operation}_app"
329
+ test_func.__doc__ = (
330
+ f"Test {operation} operation at application level.\n\n"
331
+ f"This test verifies the complete transformation workflow including "
332
+ f"image processing and geometry transformation pipeline."
333
+ )
334
+
335
+ return test_func
336
+
337
+
338
+ # =============================================================================
339
+ # Parameter Creators
340
+ # =============================================================================
341
+
342
+
343
+ def __resize_param() -> sip.ResizeParam:
344
+ """Create resize parameter."""
345
+ return sip.ResizeParam.create(zoom=1.5)
346
+
347
+
348
+ def __binning_param() -> sip.BinningParam:
349
+ """Create binning parameter."""
350
+ return sip.BinningParam.create(sx=2, sy=3)
351
+
352
+
353
+ # =============================================================================
354
+ # Generate Test Functions
355
+ # =============================================================================
356
+
357
+ # Simple transformations (no parameters)
358
+ test_geometry_transform_rotate90_unit = __create_unit_test("rotate90")
359
+ test_geometry_transform_rotate90_app = __create_app_test("rotate90")
360
+
361
+ test_geometry_transform_rotate270_unit = __create_unit_test("rotate270")
362
+ test_geometry_transform_rotate270_app = __create_app_test("rotate270")
363
+
364
+ test_geometry_transform_fliph_unit = __create_unit_test("fliph")
365
+ test_geometry_transform_fliph_app = __create_app_test("fliph")
366
+
367
+ test_geometry_transform_flipv_unit = __create_unit_test("flipv")
368
+ test_geometry_transform_flipv_app = __create_app_test("flipv")
369
+
370
+ test_geometry_transform_transpose_unit = __create_unit_test("transpose")
371
+ test_geometry_transform_transpose_app = __create_app_test("transpose")
372
+
373
+ # Parametric transformations
374
+ test_geometry_transform_resize_unit = __create_unit_test("resize", __resize_param)
375
+ test_geometry_transform_resize_app = __create_app_test("resize", __resize_param)
376
+
377
+ test_geometry_transform_binning_unit = __create_unit_test("binning", __binning_param)
378
+ test_geometry_transform_binning_app = __create_app_test("binning", __binning_param)
379
+
380
+
381
+ if __name__ == "__main__":
382
+ # test_geometry_transform_rotate90_unit()
383
+ test_geometry_transform_rotate90_app()
384
+ test_geometry_transform_rotate270_unit()
385
+ test_geometry_transform_rotate270_app()
386
+ test_geometry_transform_fliph_unit()
387
+ test_geometry_transform_fliph_app()
388
+ test_geometry_transform_flipv_unit()
389
+ test_geometry_transform_flipv_app()
390
+ test_geometry_transform_transpose_unit()
391
+ test_geometry_transform_transpose_app()
392
+ test_geometry_transform_resize_unit()
393
+ test_geometry_transform_resize_app()
394
+ test_geometry_transform_binning_unit()
395
+ test_geometry_transform_binning_app()
396
+ print("✅ All geometry transformation tests passed!")
@@ -0,0 +1,51 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Image tools application test:
5
+
6
+ - Testing `ZAxisLogTool`
7
+ - Testing `profile_to_signal` function (image cross section -> curve)
8
+ """
9
+
10
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
11
+ # guitest: show
12
+
13
+ import os.path as osp
14
+
15
+ from plotpy.coords import axes_to_canvas
16
+ from plotpy.tools import CrossSectionTool
17
+ from qtpy import QtCore as QC
18
+ from sigima.objects import NewImageParam
19
+ from sigima.tests.data import create_multigaussian_image
20
+
21
+ from datalab.gui.docks import profile_to_signal
22
+ from datalab.tests import datalab_test_app_context
23
+
24
+
25
+ def test_image_tools_app():
26
+ """Run image tools test scenario"""
27
+ with datalab_test_app_context() as win:
28
+ panel = win.imagepanel
29
+ newparam = NewImageParam.create(height=200, width=200)
30
+ ima = create_multigaussian_image(newparam)
31
+ panel.add_object(ima)
32
+ panel.set_current_object_title(f"Test image for {osp.basename(__file__)}")
33
+ plotwidget = panel.plothandler.plotwidget
34
+ mgr = plotwidget.get_manager()
35
+ plot = plotwidget.get_plot()
36
+
37
+ # === Testing "profile_to_signal" ----------------------------------------------
38
+ cstool: CrossSectionTool = mgr.get_tool(CrossSectionTool)
39
+ xcs_panel, ycs_panel = mgr.get_xcs_panel(), mgr.get_ycs_panel()
40
+ xcs_panel.setVisible(True)
41
+ ycs_panel.setVisible(True)
42
+ x, y = newparam.width // 2, newparam.height // 2
43
+ active_item = plot.get_active_item()
44
+ pos = QC.QPointF(*axes_to_canvas(active_item, x, y))
45
+ cstool.add_shape_to_plot(plot, pos, pos)
46
+ for panel in (xcs_panel, ycs_panel):
47
+ profile_to_signal(plot, panel)
48
+
49
+
50
+ if __name__ == "__main__":
51
+ test_image_tools_app()
@@ -0,0 +1,27 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Image tools test
5
+
6
+ Simple image dialog for testing all image tools available in DataLab
7
+ """
8
+
9
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
10
+ # guitest: show
11
+
12
+ from guidata.qthelpers import qt_app_context
13
+ from plotpy.builder import make
14
+ from sigima.tests.data import create_noisy_gaussian_image
15
+ from sigima.tests.vistools import view_image_items
16
+
17
+
18
+ def test_image_tools_unit():
19
+ """Image tools test"""
20
+ with qt_app_context():
21
+ data = create_noisy_gaussian_image().data
22
+ items = [make.image(data, interpolation="nearest", eliminate_outliers=2.0)]
23
+ view_image_items(items)
24
+
25
+
26
+ if __name__ == "__main__":
27
+ test_image_tools_unit()
@@ -0,0 +1,73 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Load application test: high number of images
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
+ import numpy as np
13
+ import pytest
14
+ import sigima.objects
15
+ import sigima.params
16
+
17
+ from datalab.env import execenv
18
+ from datalab.tests import datalab_test_app_context
19
+
20
+
21
+ def create_random_test_data(
22
+ size: tuple[int, int] | None = None,
23
+ ) -> sigima.objects.ImageObj:
24
+ """Create a test image, based on a fast algorithm, to be able to generate
25
+ a high number of images.
26
+
27
+ Args:
28
+ size: Size of the image.
29
+ """
30
+ if size is None:
31
+ size = (2048, 2048)
32
+ # Create a base image with low frequency shapes:
33
+ x = np.linspace(-1, 1, size[0])
34
+ y = np.linspace(-1, 1, size[1])
35
+ xx, yy = np.meshgrid(x, y)
36
+ a1, a2, f1, f2 = np.random.rand(4)
37
+ data = a1 * np.sin(2 * np.pi * xx * (1 + f1 * 0.2)) + a2 * np.cos(
38
+ 2 * np.pi * yy * (1 + f2 * 0.2)
39
+ )
40
+ # Add some random noise:
41
+ data += 0.1 * np.random.randn(*data.shape)
42
+ image = sigima.objects.create_image("Random test image", data)
43
+ return image
44
+
45
+
46
+ @pytest.mark.skip("This a load test, not a functional test")
47
+ def test_high_number_of_images() -> None:
48
+ """Run a test with a high number of images."""
49
+ nb = 30
50
+ execenv.print("Creating images", end="")
51
+ images = []
52
+ for idx in range(nb):
53
+ execenv.print(".", end="")
54
+ ima = create_random_test_data()
55
+ ima.title += f" {idx}"
56
+ images.append(ima)
57
+ execenv.print(" done")
58
+ with datalab_test_app_context() as win:
59
+ panel = win.imagepanel
60
+ for ima in images:
61
+ panel.add_object(ima)
62
+ panel.objview.select_groups()
63
+
64
+ # Comment the two following lines to check if DataLab only shows the last image
65
+ # when they are all superposed
66
+ param = sigima.params.GridParam.create(cols=10)
67
+ panel.processor.distribute_on_grid(param)
68
+
69
+ panel.duplicate_object()
70
+
71
+
72
+ if __name__ == "__main__":
73
+ test_high_number_of_images()
@@ -0,0 +1,32 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Morphology processing application test
5
+ """
6
+
7
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
8
+ # guitest: show
9
+
10
+ import sigima.params
11
+ from sigima.tests.data import get_test_image
12
+
13
+ from datalab.tests import datalab_test_app_context
14
+
15
+
16
+ def test_morphology():
17
+ """Run morphology application test scenario"""
18
+ with datalab_test_app_context() as win:
19
+ win.showMaximized()
20
+ panel = win.imagepanel
21
+ panel.add_object(get_test_image("flower.npy"))
22
+ proc = panel.processor
23
+ param = sigima.params.MorphologyParam.create(radius=10)
24
+ proc.compute_all_morphology(param)
25
+ panel.objview.select_groups()
26
+ param = sigima.params.GridParam.create(cols=4)
27
+ proc.distribute_on_grid(param)
28
+ panel.add_label_with_title()
29
+
30
+
31
+ if __name__ == "__main__":
32
+ test_morphology()
@@ -0,0 +1,30 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Image offset correction application test
5
+
6
+ An application test for the image offset correction feature is necessary to ensure
7
+ that the feature works correctly with the GUI and the image processing pipeline, as
8
+ it involves user interaction and a specific dialog for selecting the offset region.
9
+ Experience has shown that this feature can be prone to issues, especially with
10
+ dialog interactions, so a dedicated test is essential to catch any regressions or
11
+ unexpected behavior in the future.
12
+ """
13
+
14
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
15
+ # guitest: show
16
+
17
+ from sigima.tests.data import get_test_image
18
+
19
+ from datalab.tests import datalab_test_app_context
20
+
21
+
22
+ def test_offset_correction():
23
+ """Run offset correction application test scenario"""
24
+ with datalab_test_app_context() as win:
25
+ win.imagepanel.add_object(get_test_image("flower.npy"))
26
+ win.imagepanel.processor.compute_offset_correction()
27
+
28
+
29
+ if __name__ == "__main__":
30
+ test_offset_correction()
@@ -0,0 +1,53 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ 2D peak detection test
5
+
6
+ Testing the following:
7
+ - Create a test image with multiple peaks
8
+ - Compute 2D peak detection and show points on image
9
+ """
10
+
11
+ # guitest: show
12
+
13
+ import sigima.params
14
+ from sigima.tests.data import create_peak_image
15
+
16
+ from datalab.tests import datalab_test_app_context, take_plotwidget_screenshot
17
+
18
+
19
+ def test_peak2d(screenshot: bool = False) -> None:
20
+ """Run 2D peak detection scenario"""
21
+ with datalab_test_app_context() as win:
22
+ panel = win.imagepanel
23
+ ima = create_peak_image()
24
+ panel.add_object(ima)
25
+
26
+ # Test with ROI creation enabled (default)
27
+ param = sigima.params.Peak2DDetectionParam.create(create_rois=True)
28
+ results = panel.processor.compute_peak_detection(param)
29
+ assert results is not None, "Peak detection should return results"
30
+
31
+ # Get the processed image object
32
+ obj = panel.objview.get_current_object()
33
+ assert obj.roi is not None, "ROI should be created when create_rois=True"
34
+ assert not obj.roi.is_empty(), "ROI should not be empty"
35
+
36
+ # Test with ROI creation disabled
37
+ ima2 = create_peak_image()
38
+ panel.add_object(ima2)
39
+ param2 = sigima.params.Peak2DDetectionParam.create(create_rois=False)
40
+ panel.processor.compute_peak_detection(param2)
41
+
42
+ obj2 = panel.objview.get_current_object()
43
+ assert obj2.roi is None or obj2.roi.is_empty(), (
44
+ "ROI should not be created when create_rois=False"
45
+ )
46
+
47
+ win.toggle_show_titles(False)
48
+ if screenshot:
49
+ take_plotwidget_screenshot(panel, "peak2d_test")
50
+
51
+
52
+ if __name__ == "__main__":
53
+ test_peak2d()