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,28 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Macro Panel application test
5
+ (essentially for the screenshot...)
6
+ """
7
+
8
+ # guitest: show
9
+
10
+ from datalab import config
11
+ from datalab.gui.main import DLMainWindow
12
+ from datalab.utils import qthelpers as qth
13
+
14
+
15
+ def test_macro(screenshots: bool = False) -> None:
16
+ """Run image tools test scenario"""
17
+ config.reset() # Reset configuration (remove configuration file and initialize it)
18
+ with qth.datalab_app_context(exec_loop=True):
19
+ win = DLMainWindow()
20
+ win.show()
21
+ win.set_current_panel("macro")
22
+ win.macropanel.add_macro()
23
+ if screenshots:
24
+ qth.grab_save_window(win.macropanel, "macro_panel")
25
+
26
+
27
+ if __name__ == "__main__":
28
+ test_macro()
@@ -0,0 +1,102 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Macro Panel unit tests
5
+ ----------------------
6
+
7
+ The objective of this test is to check all the functionalities of the Macro Panel
8
+ widget, by calling all its methods and checking the results.
9
+
10
+ Some methods are not tested here, as they are tested in remote control tests
11
+ (see datalab/tests/features/control/remoteclient_app.py):
12
+ - `run_macro`
13
+ - `stop_macro`
14
+
15
+ All other methods should be tested here.
16
+ """
17
+
18
+ # guitest: show
19
+
20
+ import os.path as osp
21
+
22
+ from guidata.qthelpers import qt_app_context
23
+
24
+ from datalab.env import execenv
25
+ from datalab.gui.macroeditor import Macro
26
+ from datalab.gui.panel import macro
27
+ from datalab.tests import helpers
28
+
29
+
30
+ def get_macro_example_path() -> str:
31
+ """Return macro example path"""
32
+ path = helpers.get_temporary_directory()
33
+ contents = """
34
+ # Simple DataLab macro example
35
+
36
+ import numpy as np
37
+
38
+ from datalab.control.proxy import RemoteProxy
39
+
40
+ proxy = RemoteProxy()
41
+
42
+ z = np.random.rand(20, 20)
43
+ proxy.add_image("toto", z)
44
+ proxy.calc("fft")
45
+
46
+ print("All done! :)")
47
+ """
48
+ filename = osp.join(path, "macro_example.py")
49
+ with open(filename, "w", encoding="utf-8") as f:
50
+ f.write(contents)
51
+ return filename
52
+
53
+
54
+ def test_macro_editor():
55
+ """Test dep viewer window"""
56
+ with qt_app_context(exec_loop=True):
57
+ widget = macro.MacroPanel(None)
58
+ widget.resize(800, 600)
59
+ widget.show()
60
+
61
+ # Create a new macro
62
+ new_macro = widget.add_macro()
63
+ assert new_macro is widget.get_macro()
64
+
65
+ # Check out the macro title, serializable name, number, ...
66
+ execenv.print("Macro title:", new_macro.title)
67
+ execenv.print("Serializable name:", widget.get_serializable_name(new_macro))
68
+ nb1 = widget.get_number_from_macro(new_macro)
69
+ nb2 = widget.get_number_from_title(new_macro.title)
70
+ assert nb1 == nb2 and nb1 == 1
71
+ execenv.print("Macro number:", nb1)
72
+ titles = widget.get_macro_titles()
73
+ assert titles[0] == new_macro.title and len(titles) == 1
74
+ new_title = "New title"
75
+ widget.rename_macro(1, new_title)
76
+ assert widget.get_macro_titles()[0] == new_title
77
+
78
+ with helpers.WorkdirRestoringTempDir() as tmpdir:
79
+ fname = osp.join(tmpdir, "macro.py")
80
+ widget.export_macro_to_file(1, fname)
81
+ widget.import_macro_from_file(fname)
82
+ imported_macro: Macro = widget.get_macro(2)
83
+ assert imported_macro.title == new_macro.title
84
+ assert imported_macro.get_code() == new_macro.get_code()
85
+ widget.rename_macro(1, "Other title")
86
+ widget.remove_macro(1)
87
+ assert len(widget.get_macro_titles()) == 1
88
+ assert widget.get_macro_titles()[0] == imported_macro.title
89
+
90
+ # Remove all macros
91
+ widget.remove_all_objects()
92
+ assert len(widget.get_macro_titles()) == 0
93
+
94
+ # Load a macro from file
95
+ macro_path = get_macro_example_path()
96
+ widget.import_macro_from_file(macro_path)
97
+ assert len(widget.get_macro_titles()) == 1
98
+ assert widget.get_macro_titles()[0] == osp.basename(macro_path)
99
+
100
+
101
+ if __name__ == "__main__":
102
+ test_macro_editor()
@@ -0,0 +1 @@
1
+ #
@@ -0,0 +1,53 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Baseline dialog test
5
+ """
6
+
7
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
8
+ # pylint: disable=duplicate-code
9
+ # guitest: show
10
+
11
+ from __future__ import annotations
12
+
13
+ import numpy as np
14
+ import sigima.objects
15
+ import sigima.proc.signal as sips
16
+ from guidata.qthelpers import exec_dialog, qt_app_context
17
+ from sigima.tests.data import create_paracetamol_signal
18
+ from sigima.tests.vistools import view_curves
19
+
20
+ from datalab.env import execenv
21
+ from datalab.widgets.signalbaseline import SignalBaselineDialog
22
+
23
+
24
+ def test_signal_baseline_selection():
25
+ """Signal baseline selection dialog test"""
26
+ sig = create_paracetamol_signal()
27
+ with qt_app_context():
28
+ dlg = SignalBaselineDialog(sig)
29
+ dlg.resize(640, 480)
30
+ dlg.setObjectName(dlg.objectName() + "_00") # to avoid timestamp suffix
31
+ exec_dialog(dlg)
32
+ execenv.print(f"baseline: {dlg.get_baseline()}")
33
+ execenv.print(f"X range: {dlg.get_x_range()}")
34
+ # Check baseline value:
35
+ i0, i1 = np.searchsorted(sig.x, dlg.get_x_range())
36
+ assert dlg.get_baseline() == sig.data[i0:i1].mean()
37
+
38
+
39
+ def test_signal_baseline_dialog() -> None:
40
+ """Test the signal baseline dialog for offset correction."""
41
+ with qt_app_context():
42
+ s1 = create_paracetamol_signal()
43
+ dlg = SignalBaselineDialog(s1)
44
+ if exec_dialog(dlg):
45
+ param = sigima.objects.ROI1DParam()
46
+ param.xmin, param.xmax = dlg.get_x_range()
47
+ s2 = sips.offset_correction(s1, param)
48
+ view_curves([s1, s2], title="Signal offset correction")
49
+
50
+
51
+ if __name__ == "__main__":
52
+ test_signal_baseline_selection()
53
+ test_signal_baseline_dialog()
@@ -0,0 +1,34 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Signal delta x dialog unit 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 create_paracetamol_signal
12
+ from sigima.tools.signal.pulse import full_width_at_y
13
+
14
+ from datalab.widgets.signaldeltax import SignalDeltaXDialog
15
+
16
+
17
+ def test_signal_delta_x_dialog():
18
+ """Test the SignalDeltaXDialog widget."""
19
+ sig = create_paracetamol_signal()
20
+ with qt_app_context():
21
+ dlg = SignalDeltaXDialog(signal=sig)
22
+ dlg.resize(640, 480)
23
+ dlg.setObjectName(dlg.objectName() + "_00") # to avoid timestamp suffix
24
+ exec_dialog(dlg)
25
+ y = dlg.get_y_value()
26
+ x0, y0, x1, y1 = dlg.get_coords()
27
+ exp_x0, exp_y0, exp_x1, exp_y1 = full_width_at_y(sig.x, sig.y, y)
28
+ assert (x0, y0, x1, y1) == (exp_x0, exp_y0, exp_x1, exp_y1), (
29
+ f"Expected: {(exp_x0, exp_y0, exp_x1, exp_y1)} but got: {(x0, y0, x1, y1)}"
30
+ )
31
+
32
+
33
+ if __name__ == "__main__":
34
+ test_signal_delta_x_dialog()
@@ -0,0 +1,26 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Signal FFT 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 CosineParam, create_signal_from_param
11
+
12
+ from datalab.tests import datalab_test_app_context
13
+
14
+
15
+ def test_fft1d_app():
16
+ """FFT application test."""
17
+ with datalab_test_app_context() as win:
18
+ panel = win.signalpanel
19
+ s1 = create_signal_from_param(CosineParam.create(size=10000))
20
+ panel.add_object(s1)
21
+ panel.processor.run_feature("fft")
22
+ panel.processor.run_feature("ifft")
23
+
24
+
25
+ if __name__ == "__main__":
26
+ test_fft1d_app()
@@ -0,0 +1,44 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Frequential filtering 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.objects import create_signal_from_param
12
+ from sigima.tests.helpers import check_array_result
13
+ from sigima.tests.signal.pulse.pulse_unit_test import create_test_square_params
14
+
15
+ from datalab.tests import datalab_test_app_context
16
+
17
+
18
+ def test_signal_freq_filter_app():
19
+ """Signal frequency filtering application test."""
20
+ with datalab_test_app_context(console=False) as win:
21
+ panel = win.signalpanel
22
+ s1 = create_signal_from_param(create_test_square_params())
23
+ panel.add_object(s1)
24
+ for feature, paramclass in (
25
+ ("lowpass", sigima.params.LowPassFilterParam),
26
+ ("highpass", sigima.params.HighPassFilterParam),
27
+ ("bandstop", sigima.params.BandStopFilterParam),
28
+ ):
29
+ for zero_padding in (True, False):
30
+ panel.objview.select_objects([1]) # Select the first signal
31
+ param = paramclass.create(method="brickwall", zero_padding=zero_padding)
32
+ param.update_from_obj(s1)
33
+ panel.processor.run_feature(feature, param)
34
+
35
+ s2 = panel.objview.get_sel_objects()[0]
36
+ check_array_result(
37
+ f"{feature} filter output X data (zero_padding={zero_padding})",
38
+ s2.x,
39
+ s1.x,
40
+ )
41
+
42
+
43
+ if __name__ == "__main__":
44
+ test_signal_freq_filter_app()
@@ -0,0 +1,50 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """Curve fitting dialog test
4
+
5
+ Testing fit dialogs: Gaussian, Lorentzian, Voigt, etc.
6
+ """
7
+
8
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
9
+ # guitest: show
10
+
11
+ from guidata.qthelpers import qt_app_context
12
+ from sigima.objects import NormalDistribution1DParam
13
+ from sigima.tests.data import create_noisy_signal, get_test_signal
14
+ from sigima.tools.signal.peakdetection import peak_indices
15
+
16
+ from datalab.env import execenv
17
+ from datalab.tests import helpers
18
+ from datalab.widgets import fitdialog as fdlg
19
+
20
+
21
+ def test_fit_dialog():
22
+ """Test function"""
23
+ with qt_app_context():
24
+ # Multi-gaussian curve fitting test
25
+ s1 = get_test_signal("paracetamol.txt")
26
+ peakidx = peak_indices(s1.y)
27
+ s2 = create_noisy_signal(NormalDistribution1DParam.create(sigma=5.0))
28
+ s3 = get_test_signal("gaussian_fit.txt")
29
+ s4 = get_test_signal("piecewiseexponential_fit.txt")
30
+
31
+ ep = execenv.print
32
+ tn = helpers.get_default_test_name
33
+
34
+ ep(fdlg.polynomial_fit(s2.x, s2.y, 4, name=tn("00")))
35
+ ep(fdlg.linear_fit(s2.x, s2.y, name=tn("01")))
36
+ ep(fdlg.gaussian_fit(s3.x, s3.y, name=tn("02")))
37
+ ep(fdlg.lorentzian_fit(s3.x, s3.y, name=tn("03")))
38
+ ep(fdlg.multigaussian_fit(s1.x, s1.y, peakidx, name=tn("04")))
39
+ ep(fdlg.multilorentzian_fit(s1.x, s1.y, peakidx, name=tn("05")))
40
+ ep(fdlg.voigt_fit(s3.x, s3.y, name=tn("06")))
41
+ ep(fdlg.exponential_fit(s2.x, s2.y, name=tn("07")))
42
+ ep(fdlg.sinusoidal_fit(s2.x, s2.y, name=tn("08")))
43
+ ep(fdlg.cdf_fit(s2.x, s2.y, name=tn("09")))
44
+ ep(fdlg.planckian_fit(s3.x, s3.y, name=tn("10")))
45
+ ep(fdlg.twohalfgaussian_fit(s3.x, s3.y, name=tn("11")))
46
+ ep(fdlg.piecewiseexponential_fit(s4.x, s4.y, name=tn("12")))
47
+
48
+
49
+ if __name__ == "__main__":
50
+ test_fit_dialog()
@@ -0,0 +1,110 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Interpolation application test and X-array compatibility behavior.
5
+ """
6
+
7
+ # pylint: disable=invalid-name # Allows short reference names like x, y, ...
8
+ # guitest: show
9
+
10
+ import numpy as np
11
+ import sigima.params
12
+ from sigima.objects import SignalObj, create_signal
13
+
14
+ from datalab.tests import datalab_test_app_context
15
+
16
+
17
+ def test_interpolation_app():
18
+ """Test interpolation feature in DataLab application.
19
+
20
+ This test ensures that interpolation works correctly when signals have
21
+ different X arrays (which is the whole point of interpolation).
22
+ """
23
+ with datalab_test_app_context() as win:
24
+ panel = win.signalpanel
25
+
26
+ # Create interpolation parameters
27
+ param = sigima.params.InterpolationParam.create(method="linear")
28
+
29
+ # Create X arrays
30
+ x_dense = np.linspace(0, 10, 100)
31
+ x_sparse = np.linspace(1, 9, 20)
32
+
33
+ for x1, x2 in [(x_dense, x_sparse), (x_sparse, x_dense)]:
34
+ context = f"Source X {'dense' if len(x1) > len(x2) else 'sparse'} → "
35
+ context += f"Target X {'sparse' if len(x1) > len(x2) else 'dense'}"
36
+
37
+ # Create source signal with dense sampling
38
+ y1 = np.sin(x1)
39
+ sig1 = create_signal("Source signal", x1, y1)
40
+ panel.add_object(sig1)
41
+
42
+ # Create target signal with sparse sampling and different range
43
+ y2 = np.zeros_like(x2) # Y values don't matter for interpolation target
44
+ sig2 = create_signal("Target X values", x2, y2)
45
+ panel.add_object(sig2)
46
+
47
+ # This is the key test - interpolation should work even when X arrays differ
48
+ # The X-array compatibility check should NOT interfere
49
+ panel.objview.select_objects([sig1])
50
+ panel.processor.run_feature("interpolate", sig2, param)
51
+
52
+ # Verify the result
53
+ result_objects = panel.objview.get_sel_objects()
54
+ assert len(result_objects) == 1, (
55
+ f"[{context}] Should have one interpolated result"
56
+ )
57
+ result = result_objects[0]
58
+ assert isinstance(result, SignalObj), (
59
+ f"[{context}] Result should be a SignalObj"
60
+ )
61
+ assert result.x.shape == sig2.x.shape, (
62
+ f"[{context}] Result X should match target X shape"
63
+ )
64
+ assert np.allclose(result.x, sig2.x), (
65
+ f"[{context}] Result X should match target X"
66
+ )
67
+ expected_y = np.interp(x2, x1, y1)
68
+ assert np.allclose(result.y, expected_y, atol=1e-10), (
69
+ f"[{context}] Result Y should be properly interpolated"
70
+ )
71
+
72
+
73
+ def test_xarray_compatibility_still_works_for_other_operations():
74
+ """Test that X-array compatibility still works for operations that need it.
75
+
76
+ This test ensures that the fix for interpolation doesn't break X-array
77
+ compatibility for other operations like addition.
78
+ """
79
+ with datalab_test_app_context() as win:
80
+ panel = win.signalpanel
81
+
82
+ # Create signals with different X arrays (should trigger compatibility check)
83
+ x1 = np.linspace(0, 10, 100)
84
+ y1 = np.ones_like(x1)
85
+ sig1 = create_signal("Signal 1", x1, y1)
86
+ panel.add_object(sig1)
87
+
88
+ x2 = np.linspace(0, 10, 50) # Different sampling
89
+ y2 = np.ones_like(x2)
90
+ sig2 = create_signal("Signal 2", x2, y2)
91
+ panel.add_object(sig2)
92
+
93
+ # Test addition (should still use X-array compatibility)
94
+ panel.objview.select_objects([sig1, sig2])
95
+ panel.processor.run_feature("addition")
96
+
97
+ # Get the result
98
+ result_objects = panel.objview.get_sel_objects()
99
+ assert len(result_objects) == 1, "Should have one addition result"
100
+ result = result_objects[0]
101
+
102
+ # For addition, the X-array compatibility should have handled the different
103
+ # arrays. The result should have consistent X values and proper Y values (2.0)
104
+ assert np.allclose(result.y, 2.0, atol=1e-10), (
105
+ "Addition result should be 2.0 (1.0 + 1.0)"
106
+ )
107
+
108
+
109
+ if __name__ == "__main__":
110
+ test_interpolation_app()
@@ -0,0 +1,80 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Load big signal application test:
5
+
6
+ - Generate a big signal (open an existing CSV file and create a dummy CSV file by
7
+ duplicating the data several times)
8
+
9
+ - Load the big signal in the signal panel
10
+ """
11
+
12
+ # guitest: show
13
+
14
+ import os.path as osp
15
+
16
+ import numpy as np
17
+ import pandas as pd
18
+ import pytest
19
+
20
+ from datalab.env import execenv
21
+ from datalab.tests import datalab_test_app_context, helpers
22
+
23
+
24
+ def create_large_random_dataframe(nrows: int, ncols: int) -> pd.DataFrame:
25
+ """Create a large DataFrame with random data.
26
+
27
+ Args:
28
+ nrows: The number of rows to generate.
29
+ ncols: The number of columns to generate.
30
+ """
31
+ # The number of initial random rows to generate
32
+ initial_rows = min(nrows, 1000)
33
+
34
+ # Generate the initial "SignalXX" data with random values
35
+ initial_signal_data = np.random.rand(initial_rows, ncols)
36
+
37
+ # Duplicate the "SignalXX" data to fill the desired number of rows
38
+ full_signal_data = np.tile(
39
+ initial_signal_data,
40
+ (nrows // initial_rows + (1 if nrows % initial_rows > 0 else 0), 1),
41
+ )
42
+
43
+ # If nrows is not an exact multiple of initial_rows, trim the excess rows
44
+ full_signal_data = full_signal_data[:nrows, :]
45
+
46
+ # Generate the "Time" column as a sequential array from 0 to nrows-1
47
+ time_data = np.arange(nrows).reshape(-1, 1)
48
+
49
+ # Combine the "Time" column with the "SignalXX" data
50
+ full_data = np.hstack((time_data, full_signal_data))
51
+
52
+ # Prepare the column names
53
+ column_names = ["Time"] + [f"Signal{str(i).zfill(2)}" for i in range(1, ncols + 1)]
54
+
55
+ # Create and return the DataFrame
56
+ df = pd.DataFrame(full_data, columns=column_names)
57
+ return df
58
+
59
+
60
+ @pytest.mark.parametrize("nrows, ncols", [(10000, 16)])
61
+ def test_loadbigsignal_app(nrows: int, ncols: int) -> None:
62
+ """Load big signal application test"""
63
+ with helpers.WorkdirRestoringTempDir() as tmpdir:
64
+ with datalab_test_app_context() as win:
65
+ execenv.print("Loading big signal application test:")
66
+ execenv.print(" - Working in temporary directory:", tmpdir)
67
+ execenv.print(f" - Creating a big dataset ({nrows} rows, {ncols} columns)")
68
+ df = create_large_random_dataframe(nrows, ncols)
69
+ big_csv = osp.join(tmpdir, "big.csv")
70
+ df.to_csv(big_csv, index=False)
71
+ execenv.print(" - Loading the big signal in the signal panel")
72
+ panel = win.signalpanel
73
+ panel.load_from_files([big_csv])
74
+ execenv.print(" - Saving the big signal")
75
+ panel.save_to_files([big_csv.replace(".csv", "_copy.csv")])
76
+ execenv.print("OK")
77
+
78
+
79
+ if __name__ == "__main__":
80
+ test_loadbigsignal_app(1000000, 16)
@@ -0,0 +1,132 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Test for multiple geometry results with multiple ROIs
5
+ ======================================================
6
+
7
+ This test verifies that multiple geometry results (e.g., FWHM and FW1e2) can coexist
8
+ when computed on signals with multiple ROIs (e.g., multiple pulse peaks).
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import numpy as np
14
+ import sigima.objects as sio
15
+ import sigima.params
16
+ import sigima.proc.signal as sig_proc
17
+
18
+ from datalab.adapters_metadata import GeometryAdapter
19
+
20
+
21
+ def test_multiple_results_with_multiple_rois():
22
+ """Test that FWHM and FW1e2 work correctly with multiple ROIs."""
23
+ # Create a signal with three Gaussian pulses
24
+ x = np.linspace(0, 30, 3000)
25
+
26
+ # Three pulses at different positions
27
+ pulse1 = 1.0 * np.exp(-((x - 5) ** 2) / 2) # Peak at x=5, sigma=1
28
+ pulse2 = 0.8 * np.exp(-((x - 15) ** 2) / 4) # Peak at x=15, sigma=2
29
+ pulse3 = 1.2 * np.exp(-((x - 25) ** 2) / 1) # Peak at x=25, sigma=0.707
30
+
31
+ y = pulse1 + pulse2 + pulse3
32
+ signal = sio.create_signal("Triple Pulse Signal", x, y)
33
+
34
+ # Create three ROIs around each pulse (pass all coordinates at once)
35
+ signal.roi = sio.create_signal_roi(
36
+ [[0.0, 10.0], [10.0, 20.0], [20.0, 30.0]] # Three ROI ranges
37
+ )
38
+
39
+ roi_count = len(list(signal.iterate_roi_indices()))
40
+ print(f"Signal has {roi_count} ROIs")
41
+ fwhm_param = sigima.params.FWHMParam()
42
+ fwhm_param.method = "zero-crossing"
43
+ fwhm_result = sig_proc.fwhm(signal, fwhm_param)
44
+
45
+ assert fwhm_result is not None, "FWHM computation failed"
46
+ print(f"FWHM result has {len(fwhm_result.coords)} rows")
47
+ assert len(fwhm_result.coords) == 3, "Expected 3 FWHM measurements (one per ROI)"
48
+
49
+ GeometryAdapter(fwhm_result).add_to(signal)
50
+
51
+ # Compute FW1e2 (should also get one result per ROI)
52
+ fw1e2_result = sig_proc.fw1e2(signal)
53
+
54
+ assert fw1e2_result is not None, "FW1e2 computation failed"
55
+ print(f"FW1e² result has {len(fw1e2_result.coords)} rows")
56
+ assert len(fw1e2_result.coords) == 3, "Expected 3 FW1e2 measurements (one per ROI)"
57
+
58
+ GeometryAdapter(fw1e2_result).add_to(signal)
59
+
60
+ # Verify both results are stored separately
61
+ results = list(GeometryAdapter.iterate_from_obj(signal))
62
+ assert len(results) == 2, f"Expected 2 distinct results, got {len(results)}"
63
+
64
+ # Verify the titles
65
+ titles = {adapter.title for adapter in results}
66
+ assert "fwhm" in titles, "FWHM result not found"
67
+ assert "fw1e2" in titles, "FW1e2 result not found"
68
+
69
+ # Verify each result has measurements for all 3 ROIs
70
+ for adapter in results:
71
+ assert len(adapter.result.coords) == 3, (
72
+ f"{adapter.title} should have 3 measurements"
73
+ )
74
+
75
+ # Verify ROI indices are correct
76
+ roi_indices = adapter.result.roi_indices
77
+ assert roi_indices is not None, f"{adapter.title} should have ROI indices"
78
+ assert len(roi_indices) == 3, f"{adapter.title} should have 3 ROI indices"
79
+ assert set(roi_indices) == {0, 1, 2}, (
80
+ f"{adapter.title} ROI indices should be [0, 1, 2]"
81
+ )
82
+
83
+ print(f"\n{adapter.title.upper()} measurements:")
84
+ for coords, roi_idx in zip(adapter.result.coords, roi_indices):
85
+ width = abs(coords[2] - coords[0])
86
+ print(f" ROI {roi_idx}: width = {width:.4f}")
87
+
88
+ print("\n✓ Multiple results with multiple ROIs work correctly")
89
+
90
+
91
+ def test_roi_filtering():
92
+ """Test that we can filter results by ROI index."""
93
+ # Create a signal with two pulses
94
+ x = np.linspace(0, 20, 2000)
95
+ pulse1 = np.exp(-((x - 5) ** 2) / 2)
96
+ pulse2 = np.exp(-((x - 15) ** 2) / 2)
97
+ y = pulse1 + pulse2
98
+ signal = sio.create_signal("Dual Pulse Signal", x, y)
99
+
100
+ # Create two ROIs (pass all coordinates at once)
101
+ signal.roi = sio.create_signal_roi([[0.0, 10.0], [10.0, 20.0]])
102
+
103
+ # Compute FWHM
104
+ fwhm_param = sigima.params.FWHMParam()
105
+ fwhm_param.method = "zero-crossing"
106
+ fwhm_result = sig_proc.fwhm(signal, fwhm_param)
107
+
108
+ assert fwhm_result is not None
109
+ assert len(fwhm_result.coords) == 2
110
+
111
+ GeometryAdapter(fwhm_result).add_to(signal)
112
+
113
+ # Retrieve and filter by ROI
114
+ adapters = list(GeometryAdapter.iterate_from_obj(signal))
115
+ assert len(adapters) == 1
116
+
117
+ adapter = adapters[0]
118
+
119
+ # Get data for specific ROI
120
+ roi0_df = adapter.get_roi_data(0)
121
+ roi1_df = adapter.get_roi_data(1)
122
+
123
+ assert len(roi0_df) == 1, "ROI 0 should have 1 measurement"
124
+ assert len(roi1_df) == 1, "ROI 1 should have 1 measurement"
125
+
126
+ print("\n✓ ROI filtering works correctly")
127
+
128
+
129
+ if __name__ == "__main__":
130
+ test_multiple_results_with_multiple_rois()
131
+ test_roi_filtering()
132
+ print("\n✅ All multi-ROI tests passed!")