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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (496) hide show
  1. datalab/__init__.py +35 -2
  2. datalab/adapters_metadata/__init__.py +31 -0
  3. datalab/adapters_metadata/base_adapter.py +316 -0
  4. datalab/adapters_metadata/common.py +422 -0
  5. datalab/adapters_metadata/geometry_adapter.py +98 -0
  6. datalab/adapters_metadata/table_adapter.py +84 -0
  7. datalab/adapters_plotpy/__init__.py +54 -0
  8. datalab/adapters_plotpy/annotations.py +124 -0
  9. datalab/adapters_plotpy/base.py +110 -0
  10. datalab/adapters_plotpy/converters.py +86 -0
  11. datalab/adapters_plotpy/factories.py +80 -0
  12. datalab/adapters_plotpy/objects/__init__.py +0 -0
  13. datalab/adapters_plotpy/objects/base.py +197 -0
  14. datalab/adapters_plotpy/objects/image.py +157 -0
  15. datalab/adapters_plotpy/objects/scalar.py +565 -0
  16. datalab/adapters_plotpy/objects/signal.py +264 -0
  17. datalab/adapters_plotpy/roi/__init__.py +0 -0
  18. datalab/adapters_plotpy/roi/base.py +146 -0
  19. datalab/adapters_plotpy/roi/factory.py +93 -0
  20. datalab/adapters_plotpy/roi/image.py +207 -0
  21. datalab/adapters_plotpy/roi/signal.py +72 -0
  22. datalab/app.py +98 -0
  23. datalab/config.py +817 -0
  24. datalab/control/__init__.py +0 -0
  25. datalab/control/baseproxy.py +776 -0
  26. datalab/control/proxy.py +343 -0
  27. datalab/control/remote.py +1005 -0
  28. datalab/data/doc/DataLab_en.pdf +0 -0
  29. datalab/data/doc/DataLab_fr.pdf +0 -0
  30. datalab/data/icons/analysis/delete_results.svg +109 -0
  31. datalab/data/icons/analysis/fw1e2.svg +156 -0
  32. datalab/data/icons/analysis/fwhm.svg +156 -0
  33. datalab/data/icons/analysis/histogram.svg +49 -0
  34. datalab/data/icons/analysis/peak_detect.svg +160 -0
  35. datalab/data/icons/analysis/plot_results.svg +151 -0
  36. datalab/data/icons/analysis/show_results.svg +83 -0
  37. datalab/data/icons/analysis/stats.svg +49 -0
  38. datalab/data/icons/analysis.svg +120 -0
  39. datalab/data/icons/apply.svg +3 -0
  40. datalab/data/icons/check_all.svg +15 -0
  41. datalab/data/icons/collapse.svg +44 -0
  42. datalab/data/icons/collapse_selection.svg +63 -0
  43. datalab/data/icons/console.svg +101 -0
  44. datalab/data/icons/create/1d-normal.svg +8 -0
  45. datalab/data/icons/create/1d-poisson.svg +9 -0
  46. datalab/data/icons/create/1d-uniform.svg +8 -0
  47. datalab/data/icons/create/1d-zero.svg +57 -0
  48. datalab/data/icons/create/2d-gaussian.svg +56 -0
  49. datalab/data/icons/create/2d-normal.svg +38 -0
  50. datalab/data/icons/create/2d-poisson.svg +38 -0
  51. datalab/data/icons/create/2d-ramp.svg +90 -0
  52. datalab/data/icons/create/2d-sinc.svg +62 -0
  53. datalab/data/icons/create/2d-uniform.svg +38 -0
  54. datalab/data/icons/create/2d-zero.svg +13 -0
  55. datalab/data/icons/create/checkerboard.svg +39 -0
  56. datalab/data/icons/create/cosine.svg +12 -0
  57. datalab/data/icons/create/exponential.svg +55 -0
  58. datalab/data/icons/create/gaussian.svg +12 -0
  59. datalab/data/icons/create/grating.svg +29 -0
  60. datalab/data/icons/create/linear_chirp.svg +7 -0
  61. datalab/data/icons/create/logistic.svg +7 -0
  62. datalab/data/icons/create/lorentzian.svg +12 -0
  63. datalab/data/icons/create/planck.svg +12 -0
  64. datalab/data/icons/create/polynomial.svg +7 -0
  65. datalab/data/icons/create/pulse.svg +12 -0
  66. datalab/data/icons/create/ring.svg +18 -0
  67. datalab/data/icons/create/sawtooth.svg +7 -0
  68. datalab/data/icons/create/siemens.svg +35 -0
  69. datalab/data/icons/create/sinc.svg +12 -0
  70. datalab/data/icons/create/sine.svg +7 -0
  71. datalab/data/icons/create/square.svg +7 -0
  72. datalab/data/icons/create/square_pulse.svg +7 -0
  73. datalab/data/icons/create/step.svg +7 -0
  74. datalab/data/icons/create/step_pulse.svg +12 -0
  75. datalab/data/icons/create/triangle.svg +7 -0
  76. datalab/data/icons/create/voigt.svg +12 -0
  77. datalab/data/icons/edit/annotations.svg +72 -0
  78. datalab/data/icons/edit/annotations_copy.svg +114 -0
  79. datalab/data/icons/edit/annotations_delete.svg +83 -0
  80. datalab/data/icons/edit/annotations_edit.svg +98 -0
  81. datalab/data/icons/edit/annotations_export.svg +85 -0
  82. datalab/data/icons/edit/annotations_import.svg +85 -0
  83. datalab/data/icons/edit/annotations_paste.svg +100 -0
  84. datalab/data/icons/edit/copy_titles.svg +109 -0
  85. datalab/data/icons/edit/delete.svg +84 -0
  86. datalab/data/icons/edit/delete_all.svg +214 -0
  87. datalab/data/icons/edit/duplicate.svg +64 -0
  88. datalab/data/icons/edit/goto_source.svg +60 -0
  89. datalab/data/icons/edit/metadata.svg +60 -0
  90. datalab/data/icons/edit/metadata_add.svg +80 -0
  91. datalab/data/icons/edit/metadata_copy.svg +96 -0
  92. datalab/data/icons/edit/metadata_delete.svg +62 -0
  93. datalab/data/icons/edit/metadata_export.svg +68 -0
  94. datalab/data/icons/edit/metadata_import.svg +68 -0
  95. datalab/data/icons/edit/metadata_paste.svg +79 -0
  96. datalab/data/icons/edit/move_down.svg +55 -0
  97. datalab/data/icons/edit/move_up.svg +54 -0
  98. datalab/data/icons/edit/new_group.svg +76 -0
  99. datalab/data/icons/edit/recompute.svg +60 -0
  100. datalab/data/icons/edit/rename.svg +49 -0
  101. datalab/data/icons/edit.svg +16 -0
  102. datalab/data/icons/expand.svg +44 -0
  103. datalab/data/icons/expand_selection.svg +63 -0
  104. datalab/data/icons/fit/cdf_fit.svg +56 -0
  105. datalab/data/icons/fit/exponential_fit.svg +55 -0
  106. datalab/data/icons/fit/gaussian_fit.svg +62 -0
  107. datalab/data/icons/fit/interactive_fit.svg +101 -0
  108. datalab/data/icons/fit/linear_fit.svg +57 -0
  109. datalab/data/icons/fit/lorentzian_fit.svg +209 -0
  110. datalab/data/icons/fit/multigaussian_fit.svg +85 -0
  111. datalab/data/icons/fit/multilorentzian_fit.svg +85 -0
  112. datalab/data/icons/fit/piecewiseexponential_fit.svg +209 -0
  113. datalab/data/icons/fit/planckian_fit.svg +62 -0
  114. datalab/data/icons/fit/polynomial_fit.svg +59 -0
  115. datalab/data/icons/fit/sigmoid_fit.svg +56 -0
  116. datalab/data/icons/fit/sinusoidal_fit.svg +72 -0
  117. datalab/data/icons/fit/twohalfgaussian_fit.svg +63 -0
  118. datalab/data/icons/fit/voigt_fit.svg +57 -0
  119. datalab/data/icons/group.svg +56 -0
  120. datalab/data/icons/h5/h5array.svg +59 -0
  121. datalab/data/icons/h5/h5attrs.svg +75 -0
  122. datalab/data/icons/h5/h5browser.svg +133 -0
  123. datalab/data/icons/h5/h5file.svg +69 -0
  124. datalab/data/icons/h5/h5group.svg +49 -0
  125. datalab/data/icons/h5/h5scalar.svg +1 -0
  126. datalab/data/icons/help_pdf.svg +46 -0
  127. datalab/data/icons/history.svg +7 -0
  128. datalab/data/icons/image.svg +135 -0
  129. datalab/data/icons/io/fileopen_directory.svg +60 -0
  130. datalab/data/icons/io/fileopen_h5.svg +84 -0
  131. datalab/data/icons/io/fileopen_ima.svg +187 -0
  132. datalab/data/icons/io/fileopen_py.svg +123 -0
  133. datalab/data/icons/io/fileopen_sig.svg +138 -0
  134. datalab/data/icons/io/filesave_h5.svg +97 -0
  135. datalab/data/icons/io/filesave_ima.svg +200 -0
  136. datalab/data/icons/io/filesave_py.svg +136 -0
  137. datalab/data/icons/io/filesave_sig.svg +151 -0
  138. datalab/data/icons/io/import_text.svg +144 -0
  139. datalab/data/icons/io/save_to_directory.svg +134 -0
  140. datalab/data/icons/io.svg +84 -0
  141. datalab/data/icons/libre-camera-flash-off.svg +1 -0
  142. datalab/data/icons/libre-camera-flash-on.svg +1 -0
  143. datalab/data/icons/libre-gui-about.svg +1 -0
  144. datalab/data/icons/libre-gui-action-delete.svg +1 -0
  145. datalab/data/icons/libre-gui-add.svg +1 -0
  146. datalab/data/icons/libre-gui-arrow-down.svg +1 -0
  147. datalab/data/icons/libre-gui-arrow-left.svg +1 -0
  148. datalab/data/icons/libre-gui-arrow-right.svg +1 -0
  149. datalab/data/icons/libre-gui-arrow-up.svg +1 -0
  150. datalab/data/icons/libre-gui-close.svg +40 -0
  151. datalab/data/icons/libre-gui-cogs.svg +1 -0
  152. datalab/data/icons/libre-gui-globe.svg +1 -0
  153. datalab/data/icons/libre-gui-help.svg +1 -0
  154. datalab/data/icons/libre-gui-link.svg +1 -0
  155. datalab/data/icons/libre-gui-menu.svg +1 -0
  156. datalab/data/icons/libre-gui-pencil.svg +1 -0
  157. datalab/data/icons/libre-gui-plugin.svg +1 -0
  158. datalab/data/icons/libre-gui-questions.svg +1 -0
  159. datalab/data/icons/libre-gui-settings.svg +1 -0
  160. datalab/data/icons/libre-gui-unlink.svg +1 -0
  161. datalab/data/icons/libre-tech-ram.svg +1 -0
  162. datalab/data/icons/libre-toolbox.svg +1 -0
  163. datalab/data/icons/logs.svg +1 -0
  164. datalab/data/icons/markers.svg +74 -0
  165. datalab/data/icons/menu.svg +13 -0
  166. datalab/data/icons/new_ima.svg +148 -0
  167. datalab/data/icons/new_sig.svg +123 -0
  168. datalab/data/icons/operations/abs.svg +116 -0
  169. datalab/data/icons/operations/arithmetic.svg +123 -0
  170. datalab/data/icons/operations/average.svg +124 -0
  171. datalab/data/icons/operations/complex_from_magnitude_phase.svg +116 -0
  172. datalab/data/icons/operations/complex_from_real_imag.svg +124 -0
  173. datalab/data/icons/operations/constant.svg +116 -0
  174. datalab/data/icons/operations/constant_add.svg +109 -0
  175. datalab/data/icons/operations/constant_divide.svg +109 -0
  176. datalab/data/icons/operations/constant_multiply.svg +109 -0
  177. datalab/data/icons/operations/constant_subtract.svg +109 -0
  178. datalab/data/icons/operations/convert_dtype.svg +117 -0
  179. datalab/data/icons/operations/convolution.svg +46 -0
  180. datalab/data/icons/operations/deconvolution.svg +57 -0
  181. datalab/data/icons/operations/derivative.svg +127 -0
  182. datalab/data/icons/operations/difference.svg +52 -0
  183. datalab/data/icons/operations/division.svg +139 -0
  184. datalab/data/icons/operations/exp.svg +116 -0
  185. datalab/data/icons/operations/flip_horizontally.svg +69 -0
  186. datalab/data/icons/operations/flip_vertically.svg +74 -0
  187. datalab/data/icons/operations/im.svg +124 -0
  188. datalab/data/icons/operations/integral.svg +50 -0
  189. datalab/data/icons/operations/inverse.svg +143 -0
  190. datalab/data/icons/operations/log10.svg +109 -0
  191. datalab/data/icons/operations/phase.svg +116 -0
  192. datalab/data/icons/operations/power.svg +118 -0
  193. datalab/data/icons/operations/product.svg +124 -0
  194. datalab/data/icons/operations/profile.svg +379 -0
  195. datalab/data/icons/operations/profile_average.svg +399 -0
  196. datalab/data/icons/operations/profile_radial.svg +261 -0
  197. datalab/data/icons/operations/profile_segment.svg +262 -0
  198. datalab/data/icons/operations/quadratic_difference.svg +84 -0
  199. datalab/data/icons/operations/re.svg +124 -0
  200. datalab/data/icons/operations/rotate_left.svg +72 -0
  201. datalab/data/icons/operations/rotate_right.svg +72 -0
  202. datalab/data/icons/operations/signals_to_image.svg +314 -0
  203. datalab/data/icons/operations/sqrt.svg +110 -0
  204. datalab/data/icons/operations/std.svg +124 -0
  205. datalab/data/icons/operations/sum.svg +102 -0
  206. datalab/data/icons/play_demo.svg +9 -0
  207. datalab/data/icons/processing/axis_transform.svg +62 -0
  208. datalab/data/icons/processing/bandpass.svg +79 -0
  209. datalab/data/icons/processing/bandstop.svg +71 -0
  210. datalab/data/icons/processing/binning.svg +126 -0
  211. datalab/data/icons/processing/clip.svg +119 -0
  212. datalab/data/icons/processing/detrending.svg +173 -0
  213. datalab/data/icons/processing/distribute_on_grid.svg +769 -0
  214. datalab/data/icons/processing/edge_detection.svg +46 -0
  215. datalab/data/icons/processing/erase.svg +1 -0
  216. datalab/data/icons/processing/exposure.svg +143 -0
  217. datalab/data/icons/processing/fourier.svg +104 -0
  218. datalab/data/icons/processing/highpass.svg +59 -0
  219. datalab/data/icons/processing/interpolation.svg +71 -0
  220. datalab/data/icons/processing/level_adjustment.svg +70 -0
  221. datalab/data/icons/processing/lowpass.svg +60 -0
  222. datalab/data/icons/processing/morphology.svg +49 -0
  223. datalab/data/icons/processing/noise_addition.svg +114 -0
  224. datalab/data/icons/processing/noise_reduction.svg +38 -0
  225. datalab/data/icons/processing/normalize.svg +84 -0
  226. datalab/data/icons/processing/offset_correction.svg +131 -0
  227. datalab/data/icons/processing/resampling1d.svg +101 -0
  228. datalab/data/icons/processing/resampling2d.svg +240 -0
  229. datalab/data/icons/processing/reset_positions.svg +185 -0
  230. datalab/data/icons/processing/resize.svg +9 -0
  231. datalab/data/icons/processing/reverse_signal_x.svg +171 -0
  232. datalab/data/icons/processing/stability.svg +11 -0
  233. datalab/data/icons/processing/swap_x_y.svg +65 -0
  234. datalab/data/icons/processing/thresholding.svg +63 -0
  235. datalab/data/icons/processing/windowing.svg +45 -0
  236. datalab/data/icons/properties.svg +26 -0
  237. datalab/data/icons/reset.svg +9 -0
  238. datalab/data/icons/restore.svg +40 -0
  239. datalab/data/icons/roi/roi.svg +76 -0
  240. datalab/data/icons/roi/roi_coordinate.svg +78 -0
  241. datalab/data/icons/roi/roi_copy.svg +112 -0
  242. datalab/data/icons/roi/roi_delete.svg +81 -0
  243. datalab/data/icons/roi/roi_export.svg +87 -0
  244. datalab/data/icons/roi/roi_graphical.svg +78 -0
  245. datalab/data/icons/roi/roi_grid.svg +67 -0
  246. datalab/data/icons/roi/roi_ima.svg +188 -0
  247. datalab/data/icons/roi/roi_import.svg +87 -0
  248. datalab/data/icons/roi/roi_new.svg +81 -0
  249. datalab/data/icons/roi/roi_new_circle.svg +95 -0
  250. datalab/data/icons/roi/roi_new_polygon.svg +110 -0
  251. datalab/data/icons/roi/roi_new_rectangle.svg +70 -0
  252. datalab/data/icons/roi/roi_paste.svg +98 -0
  253. datalab/data/icons/roi/roi_sig.svg +124 -0
  254. datalab/data/icons/shapes.svg +134 -0
  255. datalab/data/icons/signal.svg +103 -0
  256. datalab/data/icons/table.svg +85 -0
  257. datalab/data/icons/table_unavailable.svg +102 -0
  258. datalab/data/icons/to_signal.svg +124 -0
  259. datalab/data/icons/tour/next.svg +44 -0
  260. datalab/data/icons/tour/previous.svg +44 -0
  261. datalab/data/icons/tour/rewind.svg +51 -0
  262. datalab/data/icons/tour/stop.svg +47 -0
  263. datalab/data/icons/tour/tour.svg +16 -0
  264. datalab/data/icons/uncheck_all.svg +78 -0
  265. datalab/data/icons/view/curve_antialiasing.svg +50 -0
  266. datalab/data/icons/view/new_window.svg +98 -0
  267. datalab/data/icons/view/refresh-auto.svg +57 -0
  268. datalab/data/icons/view/refresh-manual.svg +51 -0
  269. datalab/data/icons/view/reset_curve_styles.svg +96 -0
  270. datalab/data/icons/view/show_first.svg +55 -0
  271. datalab/data/icons/view/show_titles.svg +46 -0
  272. datalab/data/icons/visualization.svg +51 -0
  273. datalab/data/logo/DataLab-Banner-150.png +0 -0
  274. datalab/data/logo/DataLab-Banner-200.png +0 -0
  275. datalab/data/logo/DataLab-Banner2-100.png +0 -0
  276. datalab/data/logo/DataLab-Splash.png +0 -0
  277. datalab/data/logo/DataLab-watermark.png +0 -0
  278. datalab/data/logo/DataLab.svg +83 -0
  279. datalab/data/tests/reordering_test.h5 +0 -0
  280. datalab/data/tutorials/fabry_perot/fabry-perot1.jpg +0 -0
  281. datalab/data/tutorials/fabry_perot/fabry-perot2.jpg +0 -0
  282. datalab/data/tutorials/laser_beam/TEM00_z_13.jpg +0 -0
  283. datalab/data/tutorials/laser_beam/TEM00_z_18.jpg +0 -0
  284. datalab/data/tutorials/laser_beam/TEM00_z_23.jpg +0 -0
  285. datalab/data/tutorials/laser_beam/TEM00_z_30.jpg +0 -0
  286. datalab/data/tutorials/laser_beam/TEM00_z_35.jpg +0 -0
  287. datalab/data/tutorials/laser_beam/TEM00_z_40.jpg +0 -0
  288. datalab/data/tutorials/laser_beam/TEM00_z_45.jpg +0 -0
  289. datalab/data/tutorials/laser_beam/TEM00_z_50.jpg +0 -0
  290. datalab/data/tutorials/laser_beam/TEM00_z_55.jpg +0 -0
  291. datalab/data/tutorials/laser_beam/TEM00_z_60.jpg +0 -0
  292. datalab/data/tutorials/laser_beam/TEM00_z_65.jpg +0 -0
  293. datalab/data/tutorials/laser_beam/TEM00_z_70.jpg +0 -0
  294. datalab/data/tutorials/laser_beam/TEM00_z_75.jpg +0 -0
  295. datalab/data/tutorials/laser_beam/TEM00_z_80.jpg +0 -0
  296. datalab/env.py +542 -0
  297. datalab/gui/__init__.py +89 -0
  298. datalab/gui/actionhandler.py +1701 -0
  299. datalab/gui/docks.py +473 -0
  300. datalab/gui/h5io.py +150 -0
  301. datalab/gui/macroeditor.py +310 -0
  302. datalab/gui/main.py +2081 -0
  303. datalab/gui/newobject.py +217 -0
  304. datalab/gui/objectview.py +766 -0
  305. datalab/gui/panel/__init__.py +48 -0
  306. datalab/gui/panel/base.py +3254 -0
  307. datalab/gui/panel/image.py +157 -0
  308. datalab/gui/panel/macro.py +607 -0
  309. datalab/gui/panel/signal.py +164 -0
  310. datalab/gui/plothandler.py +800 -0
  311. datalab/gui/processor/__init__.py +84 -0
  312. datalab/gui/processor/base.py +2456 -0
  313. datalab/gui/processor/catcher.py +75 -0
  314. datalab/gui/processor/image.py +1214 -0
  315. datalab/gui/processor/signal.py +755 -0
  316. datalab/gui/profiledialog.py +333 -0
  317. datalab/gui/roieditor.py +633 -0
  318. datalab/gui/roigrideditor.py +208 -0
  319. datalab/gui/settings.py +612 -0
  320. datalab/gui/tour.py +908 -0
  321. datalab/h5/__init__.py +12 -0
  322. datalab/h5/common.py +314 -0
  323. datalab/h5/generic.py +580 -0
  324. datalab/h5/native.py +39 -0
  325. datalab/h5/utils.py +95 -0
  326. datalab/objectmodel.py +640 -0
  327. datalab/plugins/_readme_.txt +9 -0
  328. datalab/plugins/datalab_imageformats.py +175 -0
  329. datalab/plugins/datalab_testdata.py +190 -0
  330. datalab/plugins.py +355 -0
  331. datalab/tests/__init__.py +199 -0
  332. datalab/tests/backbone/__init__.py +1 -0
  333. datalab/tests/backbone/config_unit_test.py +170 -0
  334. datalab/tests/backbone/config_versioning_unit_test.py +34 -0
  335. datalab/tests/backbone/dictlistserial_app_test.py +38 -0
  336. datalab/tests/backbone/errorcatcher_unit_test.py +69 -0
  337. datalab/tests/backbone/errormsgbox_unit_test.py +50 -0
  338. datalab/tests/backbone/execenv_unit.py +262 -0
  339. datalab/tests/backbone/loadtest_gdi.py +147 -0
  340. datalab/tests/backbone/long_callback.py +96 -0
  341. datalab/tests/backbone/main_app_test.py +137 -0
  342. datalab/tests/backbone/memory_leak.py +43 -0
  343. datalab/tests/backbone/procisolation1_unit.py +128 -0
  344. datalab/tests/backbone/procisolation2_unit.py +171 -0
  345. datalab/tests/backbone/procisolation_unit_test.py +22 -0
  346. datalab/tests/backbone/profiling_app.py +27 -0
  347. datalab/tests/backbone/strings_unit_test.py +65 -0
  348. datalab/tests/backbone/title_formatting_unit_test.py +82 -0
  349. datalab/tests/conftest.py +131 -0
  350. datalab/tests/features/__init__.py +1 -0
  351. datalab/tests/features/applauncher/__init__.py +1 -0
  352. datalab/tests/features/applauncher/launcher1_app_test.py +28 -0
  353. datalab/tests/features/applauncher/launcher2_app_test.py +30 -0
  354. datalab/tests/features/common/__init__.py +1 -0
  355. datalab/tests/features/common/add_metadata_app_test.py +134 -0
  356. datalab/tests/features/common/add_metadata_unit_test.py +267 -0
  357. datalab/tests/features/common/annotations_management_unit_test.py +152 -0
  358. datalab/tests/features/common/auto_analysis_recompute_unit_test.py +240 -0
  359. datalab/tests/features/common/createobject_unit_test.py +50 -0
  360. datalab/tests/features/common/geometry_results_app_test.py +135 -0
  361. datalab/tests/features/common/interactive_processing_test.py +1109 -0
  362. datalab/tests/features/common/io_app_test.py +75 -0
  363. datalab/tests/features/common/large_results_app_test.py +187 -0
  364. datalab/tests/features/common/metadata_all_patterns_test.py +103 -0
  365. datalab/tests/features/common/metadata_app_test.py +139 -0
  366. datalab/tests/features/common/metadata_io_unit_test.py +60 -0
  367. datalab/tests/features/common/misc_app_test.py +236 -0
  368. datalab/tests/features/common/multiple_geometry_results_unit_test.py +122 -0
  369. datalab/tests/features/common/multiple_table_results_unit_test.py +64 -0
  370. datalab/tests/features/common/operation_modes_app_test.py +392 -0
  371. datalab/tests/features/common/plot_results_app_test.py +278 -0
  372. datalab/tests/features/common/reorder_app_test.py +75 -0
  373. datalab/tests/features/common/result_deletion_unit_test.py +96 -0
  374. datalab/tests/features/common/result_merged_label_unit_test.py +154 -0
  375. datalab/tests/features/common/result_shape_settings_unit_test.py +223 -0
  376. datalab/tests/features/common/roi_plotitem_unit_test.py +64 -0
  377. datalab/tests/features/common/roieditor_unit_test.py +102 -0
  378. datalab/tests/features/common/save_to_dir_app_test.py +163 -0
  379. datalab/tests/features/common/save_to_dir_unit_test.py +474 -0
  380. datalab/tests/features/common/stat_app_test.py +40 -0
  381. datalab/tests/features/common/stats_tools_unit_test.py +77 -0
  382. datalab/tests/features/common/table_results_app_test.py +52 -0
  383. datalab/tests/features/common/textimport_unit_test.py +131 -0
  384. datalab/tests/features/common/uuid_preservation_test.py +281 -0
  385. datalab/tests/features/common/worker_unit_test.py +402 -0
  386. datalab/tests/features/control/__init__.py +1 -0
  387. datalab/tests/features/control/connect_dialog.py +28 -0
  388. datalab/tests/features/control/embedded1_unit_test.py +304 -0
  389. datalab/tests/features/control/embedded2_unit_test.py +52 -0
  390. datalab/tests/features/control/remoteclient_app_test.py +219 -0
  391. datalab/tests/features/control/remoteclient_unit.py +75 -0
  392. datalab/tests/features/control/simpleclient_unit_test.py +321 -0
  393. datalab/tests/features/hdf5/__init__.py +1 -0
  394. datalab/tests/features/hdf5/h5browser1_unit_test.py +31 -0
  395. datalab/tests/features/hdf5/h5browser2_unit.py +55 -0
  396. datalab/tests/features/hdf5/h5browser_app_test.py +77 -0
  397. datalab/tests/features/hdf5/h5import_app_test.py +25 -0
  398. datalab/tests/features/hdf5/h5importer_app_test.py +34 -0
  399. datalab/tests/features/image/__init__.py +1 -0
  400. datalab/tests/features/image/annotations_app_test.py +28 -0
  401. datalab/tests/features/image/annotations_unit_test.py +80 -0
  402. datalab/tests/features/image/average_app_test.py +46 -0
  403. datalab/tests/features/image/background_dialog_test.py +70 -0
  404. datalab/tests/features/image/blobs_app_test.py +50 -0
  405. datalab/tests/features/image/contour_app_test.py +42 -0
  406. datalab/tests/features/image/contour_fabryperot_app_test.py +51 -0
  407. datalab/tests/features/image/denoise_app_test.py +31 -0
  408. datalab/tests/features/image/distribute_on_grid_app_test.py +95 -0
  409. datalab/tests/features/image/edges_app_test.py +31 -0
  410. datalab/tests/features/image/erase_app_test.py +21 -0
  411. datalab/tests/features/image/fft2d_app_test.py +27 -0
  412. datalab/tests/features/image/flatfield_app_test.py +40 -0
  413. datalab/tests/features/image/geometry_transform_unit_test.py +396 -0
  414. datalab/tests/features/image/imagetools_app_test.py +51 -0
  415. datalab/tests/features/image/imagetools_unit_test.py +27 -0
  416. datalab/tests/features/image/load_app_test.py +73 -0
  417. datalab/tests/features/image/morph_app_test.py +32 -0
  418. datalab/tests/features/image/offsetcorrection_app_test.py +30 -0
  419. datalab/tests/features/image/peak2d_app_test.py +53 -0
  420. datalab/tests/features/image/profile_app_test.py +73 -0
  421. datalab/tests/features/image/profile_dialog_test.py +56 -0
  422. datalab/tests/features/image/roi_app_test.py +98 -0
  423. datalab/tests/features/image/roi_circ_app_test.py +62 -0
  424. datalab/tests/features/image/roi_manipulation_app_test.py +268 -0
  425. datalab/tests/features/image/roigrid_unit_test.py +60 -0
  426. datalab/tests/features/image/side_by_side_app_test.py +52 -0
  427. datalab/tests/features/macro/__init__.py +1 -0
  428. datalab/tests/features/macro/macro_app_test.py +28 -0
  429. datalab/tests/features/macro/macroeditor_unit_test.py +102 -0
  430. datalab/tests/features/signal/__init__.py +1 -0
  431. datalab/tests/features/signal/baseline_dialog_test.py +53 -0
  432. datalab/tests/features/signal/deltax_dialog_unit_test.py +34 -0
  433. datalab/tests/features/signal/fft1d_app_test.py +26 -0
  434. datalab/tests/features/signal/filter_app_test.py +44 -0
  435. datalab/tests/features/signal/fitdialog_unit_test.py +50 -0
  436. datalab/tests/features/signal/interpolation_app_test.py +110 -0
  437. datalab/tests/features/signal/loadbigsignal_app_test.py +80 -0
  438. datalab/tests/features/signal/multiple_rois_unit_test.py +132 -0
  439. datalab/tests/features/signal/pulse_features_app_test.py +118 -0
  440. datalab/tests/features/signal/pulse_features_roi_app_test.py +55 -0
  441. datalab/tests/features/signal/roi_app_test.py +78 -0
  442. datalab/tests/features/signal/roi_manipulation_app_test.py +261 -0
  443. datalab/tests/features/signal/select_xy_cursor_unit_test.py +46 -0
  444. datalab/tests/features/signal/signalpeakdetection_dialog_test.py +33 -0
  445. datalab/tests/features/signal/signals_to_image_app_test.py +98 -0
  446. datalab/tests/features/signal/xarray_compat_app_test.py +128 -0
  447. datalab/tests/features/tour_unit_test.py +22 -0
  448. datalab/tests/features/utilities/__init__.py +1 -0
  449. datalab/tests/features/utilities/installconf_unit_test.py +21 -0
  450. datalab/tests/features/utilities/logview_app_test.py +21 -0
  451. datalab/tests/features/utilities/logview_error.py +24 -0
  452. datalab/tests/features/utilities/logview_unit_test.py +21 -0
  453. datalab/tests/features/utilities/memstatus_app_test.py +42 -0
  454. datalab/tests/features/utilities/settings_unit_test.py +88 -0
  455. datalab/tests/scenarios/__init__.py +1 -0
  456. datalab/tests/scenarios/beautiful_app.py +121 -0
  457. datalab/tests/scenarios/common.py +463 -0
  458. datalab/tests/scenarios/demo.py +212 -0
  459. datalab/tests/scenarios/example_app_test.py +47 -0
  460. datalab/tests/scenarios/scenario_h5_app_test.py +75 -0
  461. datalab/tests/scenarios/scenario_ima1_app_test.py +34 -0
  462. datalab/tests/scenarios/scenario_ima2_app_test.py +34 -0
  463. datalab/tests/scenarios/scenario_mac_app_test.py +58 -0
  464. datalab/tests/scenarios/scenario_sig1_app_test.py +36 -0
  465. datalab/tests/scenarios/scenario_sig2_app_test.py +35 -0
  466. datalab/utils/__init__.py +1 -0
  467. datalab/utils/conf.py +304 -0
  468. datalab/utils/dephash.py +105 -0
  469. datalab/utils/qthelpers.py +633 -0
  470. datalab/utils/strings.py +34 -0
  471. datalab/utils/tests.py +0 -0
  472. datalab/widgets/__init__.py +1 -0
  473. datalab/widgets/connection.py +138 -0
  474. datalab/widgets/filedialog.py +91 -0
  475. datalab/widgets/fileviewer.py +84 -0
  476. datalab/widgets/fitdialog.py +788 -0
  477. datalab/widgets/h5browser.py +1048 -0
  478. datalab/widgets/imagebackground.py +111 -0
  479. datalab/widgets/instconfviewer.py +175 -0
  480. datalab/widgets/logviewer.py +80 -0
  481. datalab/widgets/signalbaseline.py +90 -0
  482. datalab/widgets/signalcursor.py +208 -0
  483. datalab/widgets/signaldeltax.py +151 -0
  484. datalab/widgets/signalpeak.py +199 -0
  485. datalab/widgets/status.py +249 -0
  486. datalab/widgets/textimport.py +786 -0
  487. datalab/widgets/warningerror.py +223 -0
  488. datalab/widgets/wizard.py +286 -0
  489. datalab_platform-1.0.0.dist-info/METADATA +121 -0
  490. datalab_platform-1.0.0.dist-info/RECORD +494 -0
  491. datalab_platform-0.0.1.dev0.dist-info/METADATA +0 -67
  492. datalab_platform-0.0.1.dev0.dist-info/RECORD +0 -7
  493. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/WHEEL +0 -0
  494. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/entry_points.txt +0 -0
  495. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/licenses/LICENSE +0 -0
  496. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,422 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Common functions for metadata adapters.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import dataclasses
10
+ import warnings
11
+ from typing import TYPE_CHECKING
12
+
13
+ import numpy as np
14
+ import pandas as pd
15
+ from guidata.qthelpers import exec_dialog
16
+ from guidata.widgets.dataframeeditor import DataFrameEditor
17
+ from sigima.objects import ImageObj, SignalObj
18
+
19
+ from datalab.adapters_metadata.base_adapter import BaseResultAdapter
20
+ from datalab.adapters_metadata.geometry_adapter import GeometryAdapter
21
+ from datalab.adapters_metadata.table_adapter import TableAdapter
22
+ from datalab.config import Conf, _
23
+ from datalab.objectmodel import get_short_id
24
+
25
+ if TYPE_CHECKING:
26
+ from qtpy.QtWidgets import QWidget
27
+
28
+
29
+ @dataclasses.dataclass
30
+ class ResultData:
31
+ """Result data associated to a shapetype"""
32
+
33
+ # We now store adapted objects from the new architecture
34
+ results: list[BaseResultAdapter] | None = None
35
+ ylabels: list[str] | None = None
36
+ short_ids: list[str] | None = None
37
+
38
+ def __bool__(self) -> bool:
39
+ """Return True if there are results stored"""
40
+ return bool(self.results)
41
+
42
+ @property
43
+ def category(self) -> str:
44
+ """Return category of results"""
45
+ if not self.results:
46
+ raise ValueError("No result available")
47
+ return self.results[0].category
48
+
49
+ @property
50
+ def headers(self) -> list[str]:
51
+ """Return headers of results"""
52
+ if not self.results:
53
+ raise ValueError("No result available")
54
+ # Return the intersection of all headers
55
+ headers = set(self.results[0].headers)
56
+ if len(self.results) > 1:
57
+ for adapter in self.results[1:]:
58
+ headers.intersection_update(adapter.headers)
59
+ return list(headers)
60
+
61
+ def __post_init__(self):
62
+ """Check and initialize fields"""
63
+ if self.results is None:
64
+ self.results = []
65
+ if self.ylabels is None:
66
+ self.ylabels = []
67
+ if self.short_ids is None:
68
+ self.short_ids = []
69
+
70
+ def append(self, adapter: BaseResultAdapter, obj: SignalObj | ImageObj) -> None:
71
+ """Append a result adapter
72
+
73
+ Args:
74
+ adapter: Adapter to append
75
+ obj: Object associated to the adapter
76
+ """
77
+ # Check that the adapter is compatible with existing ones
78
+ if self.results:
79
+ if adapter.category != self.results[0].category:
80
+ raise ValueError("Incompatible adapter category")
81
+ if len(set(self.headers).intersection(set(adapter.headers))) == 0:
82
+ raise ValueError("Incompatible adapter headers")
83
+ self.results.append(adapter)
84
+ df = adapter.to_dataframe()
85
+ for i_row_res in range(len(df)):
86
+ sid = get_short_id(obj)
87
+ ylabel = f"{adapter.func_name}({sid})"
88
+ if "roi_index" in df.columns:
89
+ i_roi = int(df.iloc[i_row_res]["roi_index"])
90
+ roititle = ""
91
+ if i_roi >= 0:
92
+ roititle = obj.roi.get_single_roi_title(i_roi)
93
+ ylabel += f"|{roititle}"
94
+ self.ylabels.append(ylabel)
95
+ self.short_ids.append(sid)
96
+
97
+
98
+ def have_results(objs: list[SignalObj | ImageObj]) -> bool:
99
+ """Return True if any object has results
100
+
101
+ Args:
102
+ objs: List of objects
103
+
104
+ Returns:
105
+ True if any object has results, False otherwise
106
+ """
107
+ return any(
108
+ item for obj in objs for item in GeometryAdapter.iterate_from_obj(obj)
109
+ ) or any(item for obj in objs for item in TableAdapter.iterate_from_obj(obj))
110
+
111
+
112
+ def have_geometry_results(objs: list[SignalObj | ImageObj]) -> bool:
113
+ """Return True if any object has geometry results
114
+
115
+ Args:
116
+ objs: List of objects
117
+
118
+ Returns:
119
+ True if any object has geometry results, False otherwise
120
+ """
121
+ return any(item for obj in objs for item in GeometryAdapter.iterate_from_obj(obj))
122
+
123
+
124
+ def create_resultdata_dict(
125
+ objs: list[SignalObj | ImageObj],
126
+ ) -> dict[str, ResultData]:
127
+ """Return result data dictionary
128
+
129
+ Args:
130
+ objs: List of objects
131
+
132
+ Returns:
133
+ Result data dictionary: keys are result categories, values are ResultData
134
+ """
135
+ rdatadict: dict[str, ResultData] = {}
136
+ for obj in objs:
137
+ for adapter in list(GeometryAdapter.iterate_from_obj(obj)) + list(
138
+ TableAdapter.iterate_from_obj(obj)
139
+ ):
140
+ rdata = rdatadict.setdefault(adapter.category, ResultData())
141
+ rdata.append(adapter, obj)
142
+ return rdatadict
143
+
144
+
145
+ def show_resultdata(parent: QWidget, rdata: ResultData, object_name: str = "") -> None:
146
+ """Show result data in a DataFrame editor window
147
+
148
+ Args:
149
+ parent: Parent widget
150
+ rdata: Result data to show
151
+ object_name: Optional object name for the dialog
152
+ """
153
+ with warnings.catch_warnings():
154
+ warnings.simplefilter("ignore", RuntimeWarning)
155
+
156
+ # Generate dataframes with visible columns only
157
+ # Use the object-level visible_only parameter for cleaner implementation
158
+ dfs = [result.to_dataframe(visible_only=True) for result in rdata.results]
159
+
160
+ # Combine all dataframes
161
+ df = pd.concat(dfs, ignore_index=True)
162
+
163
+ # Add comparison columns if we have multiple results of the same kind
164
+ if len(dfs) > 1:
165
+ df = _add_comparison_columns_to_dataframe(df, rdata)
166
+
167
+ # Remove roi_index column for display (not needed in the GUI)
168
+ if "roi_index" in df.columns:
169
+ df = df.drop(columns=["roi_index"])
170
+
171
+ df.set_index(pd.Index(rdata.ylabels), inplace=True)
172
+ dlg = DataFrameEditor(parent)
173
+ dlg.setup_and_check(
174
+ df,
175
+ _("Results") + f" ({rdata.category})",
176
+ readonly=True,
177
+ add_title_suffix=False,
178
+ )
179
+ if object_name:
180
+ dlg.setObjectName(object_name)
181
+ dlg.resize(750, 300)
182
+ exec_dialog(dlg)
183
+
184
+
185
+ def _add_comparison_columns_to_dataframe(
186
+ df: pd.DataFrame, rdata: ResultData
187
+ ) -> pd.DataFrame:
188
+ """Add comparison columns to dataframe with ROI-aware grouping.
189
+
190
+ For each original column, adds one comparison column showing the difference
191
+ between the current row and the corresponding reference row.
192
+
193
+ Args:
194
+ df: Combined DataFrame with all results
195
+ rdata: ResultData containing ylabels and short_ids
196
+
197
+ Returns:
198
+ DataFrame with comparison columns added (one Δ column per original column)
199
+ """
200
+ # Build signal/image groups:
201
+ # list of (object_id, start_row, end_row) for each signal/image
202
+ obj_groups = []
203
+ current_obj_id = None
204
+ group_start = 0
205
+
206
+ for i, obj_id in enumerate(rdata.short_ids):
207
+ if obj_id != current_obj_id:
208
+ # New signal group
209
+ if current_obj_id is not None:
210
+ # Close previous group
211
+ obj_groups.append((current_obj_id, group_start, i - 1))
212
+ current_obj_id = obj_id
213
+ group_start = i
214
+
215
+ # Close the last group
216
+ if current_obj_id is not None:
217
+ obj_groups.append((current_obj_id, group_start, len(rdata.ylabels) - 1))
218
+
219
+ # If we only have one signal group, no need for comparisons
220
+ if len(obj_groups) <= 1:
221
+ return df
222
+
223
+ # Use the first signal group as reference
224
+ reference_group = obj_groups[0]
225
+ _ref_obj_id, reference_start, reference_end = reference_group
226
+
227
+ # Get columns to compare (exclude roi_index)
228
+ cols_to_compare = [col for col in df.columns if col != "roi_index"]
229
+
230
+ # Create new dataframe with original columns plus one comparison column per
231
+ # original column
232
+ result_df = df.copy()
233
+
234
+ # Add comparison columns - one per original column
235
+ for col in cols_to_compare:
236
+ comparison_col_name = f"Δ({col})"
237
+ comparison_values = []
238
+
239
+ # For each row in the entire dataframe
240
+ for row_idx in range(len(df)):
241
+ # Find which group this row belongs to
242
+ row_group_idx = None
243
+ for group_idx, (obj_id, start, end) in enumerate(obj_groups):
244
+ if start <= row_idx <= end:
245
+ row_group_idx = group_idx
246
+ break
247
+
248
+ if row_group_idx == 0:
249
+ # Reference group - no comparison needed
250
+ comparison_values.append("")
251
+ elif row_group_idx is not None:
252
+ # Non-reference group - calculate comparison with corresponding
253
+ # reference row
254
+ group_start = obj_groups[row_group_idx][1]
255
+ ref_row_idx = reference_start + (row_idx - group_start)
256
+ if ref_row_idx <= reference_end:
257
+ ref_val = df.iloc[ref_row_idx][col]
258
+ curr_val = df.iloc[row_idx][col]
259
+ comparison_values.append(
260
+ _compute_comparison_value(ref_val, curr_val)
261
+ )
262
+ else:
263
+ comparison_values.append("")
264
+ else:
265
+ # Should not happen, but handle gracefully
266
+ comparison_values.append("")
267
+
268
+ # Insert comparison column right after the original column
269
+ col_idx = result_df.columns.get_loc(col)
270
+ result_df.insert(col_idx + 1, comparison_col_name, comparison_values)
271
+
272
+ return result_df
273
+
274
+
275
+ def _compute_comparison_value(ref_val, curr_val) -> str:
276
+ """Compute a comparison value between reference and current values.
277
+
278
+ Args:
279
+ ref_val: Reference value
280
+ curr_val: Current value to compare
281
+
282
+ Returns:
283
+ String representation of the comparison
284
+ """
285
+ # Handle different data types
286
+ if pd.isna(ref_val) or pd.isna(curr_val):
287
+ return "N/A"
288
+ if isinstance(ref_val, str) or isinstance(curr_val, str):
289
+ # String comparison
290
+ return "=" if str(ref_val) == str(curr_val) else "≠"
291
+ if isinstance(ref_val, (int, float, np.integer, np.floating)) and isinstance(
292
+ curr_val, (int, float, np.integer, np.floating)
293
+ ):
294
+ # Numeric comparison - show difference
295
+ diff = curr_val - ref_val
296
+ # For integers, check exact equality; for floats, use small tolerance
297
+ if isinstance(ref_val, (int, np.integer)) and isinstance(
298
+ curr_val, (int, np.integer)
299
+ ):
300
+ tolerance = 0
301
+ else:
302
+ tolerance = 1e-10
303
+
304
+ if abs(diff) <= tolerance:
305
+ return "="
306
+
307
+ # Format the difference with appropriate sign
308
+ sign = "+" if diff > 0 else ""
309
+ return f"{sign}{diff:.4g}"
310
+
311
+ # Default comparison
312
+ return "=" if ref_val == curr_val else "≠"
313
+
314
+
315
+ def resultadapter_to_html(
316
+ adapter: BaseResultAdapter | list[BaseResultAdapter],
317
+ obj: SignalObj | ImageObj,
318
+ visible_only: bool = True,
319
+ transpose_single_row: bool = True,
320
+ max_cells: int | None = None,
321
+ **kwargs,
322
+ ) -> str:
323
+ """Convert a result adapter to HTML format
324
+
325
+ Args:
326
+ adapter: Adapter to convert, or list of adapters to concatenate
327
+ obj: Object associated to the adapter
328
+ visible_only: If True, include only visible headers based on display
329
+ preferences. Default is False.
330
+ transpose_single_row: If True, transpose the table when there's only one row
331
+ max_cells: Maximum number of table cells (rows × columns) to display per
332
+ result. If None, use the configuration value. If a result has more cells,
333
+ it will be truncated with a notice.
334
+ **kwargs: Additional arguments passed to DataFrame.to_html()
335
+
336
+ Returns:
337
+ HTML representation of the adapter
338
+ """
339
+ if not isinstance(adapter, BaseResultAdapter) and not all(
340
+ isinstance(adp, BaseResultAdapter) for adp in adapter
341
+ ):
342
+ raise ValueError(
343
+ "Adapter must be a BaseResultAdapter "
344
+ "or a list of BaseResultAdapter instances"
345
+ )
346
+
347
+ # Get max_cells from config if not provided
348
+ if max_cells is None:
349
+ max_cells = Conf.view.max_cells_in_label.get(100)
350
+
351
+ if isinstance(adapter, BaseResultAdapter):
352
+ # Get the dataframe FIRST to check truncation needs
353
+ df = adapter.to_dataframe(visible_only=visible_only)
354
+
355
+ # Remove roi_index column for display calculations
356
+ display_df = df.drop(columns=["roi_index"]) if "roi_index" in df.columns else df
357
+
358
+ # For merged labels, limit display columns for readability
359
+ max_display_cols = Conf.view.max_cols_in_label.get(20)
360
+ num_cols = len(display_df.columns)
361
+ cols_truncated = num_cols > max_display_cols
362
+
363
+ if cols_truncated:
364
+ display_df = display_df.iloc[:, :max_display_cols]
365
+ num_cols = max_display_cols
366
+
367
+ # Calculate number of cells (rows × columns)
368
+ num_rows = len(adapter.result)
369
+ num_cells = num_rows * num_cols
370
+
371
+ # Check if truncation is needed BEFORE calling to_html()
372
+ if num_cells > max_cells or cols_truncated:
373
+ # Calculate how many rows we can display given max_cells
374
+ max_rows = max(1, max_cells // num_cols) if num_cols > 0 else num_rows
375
+
376
+ # Truncate to max_rows and make a copy to avoid SettingWithCopyWarning
377
+ df_truncated = display_df.head(max_rows).copy()
378
+
379
+ # Generate HTML directly from truncated DataFrame for performance
380
+ # This is MUCH faster than calling adapter.to_html() on full data
381
+ html_kwargs = {"border": 0}
382
+ html_kwargs.update(kwargs)
383
+
384
+ # Format numeric columns efficiently
385
+ for col in df_truncated.select_dtypes(include=["number"]).columns:
386
+ df_truncated[col] = df_truncated[col].map(
387
+ lambda x: f"{x:.3g}" if pd.notna(x) else x
388
+ )
389
+
390
+ text = f'<u><b style="color: #5294e2">{adapter.result.title}</b></u>:'
391
+ text += df_truncated.to_html(**html_kwargs)
392
+
393
+ # Add truncation notice
394
+ omitted_parts = []
395
+ if num_rows > max_rows:
396
+ omitted_parts.append(_("%d more rows") % (num_rows - max_rows))
397
+ if cols_truncated:
398
+ num_omitted_cols = len(df.columns) - max_display_cols
399
+ omitted_parts.append(_("%d more columns") % num_omitted_cols)
400
+ if omitted_parts:
401
+ omitted_str = _("%s omitted") % ", ".join(omitted_parts)
402
+ text += f"<p><i>... ({omitted_str})</i></p>"
403
+
404
+ return text
405
+
406
+ # No truncation needed, use the standard adapter.to_html() method
407
+ return adapter.to_html(
408
+ obj=obj,
409
+ visible_only=visible_only,
410
+ transpose_single_row=transpose_single_row,
411
+ **kwargs,
412
+ )
413
+
414
+ # For lists of adapters, recursively process each one
415
+ return "<hr>".join(
416
+ [
417
+ resultadapter_to_html(
418
+ res, obj, visible_only, transpose_single_row, max_cells
419
+ )
420
+ for res in adapter
421
+ ]
422
+ )
@@ -0,0 +1,98 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Adapter for Sigima's GeometryResult, providing features
5
+ for storing and retrieving those objects as metadata for DataLab's signal
6
+ and image objects.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import ClassVar
12
+
13
+ from sigima.objects import GeometryResult, ImageObj, SignalObj
14
+
15
+ from datalab.adapters_metadata.base_adapter import BaseResultAdapter
16
+
17
+
18
+ class GeometryAdapter(BaseResultAdapter):
19
+ """Adapter for GeometryResult objects.
20
+
21
+ This adapter provides a unified interface for working with GeometryResult objects,
22
+ including metadata storage/retrieval and various data representations.
23
+
24
+ Args:
25
+ geometry: GeometryResult object to adapt
26
+ """
27
+
28
+ # Class constants for metadata storage
29
+ META_PREFIX: ClassVar[str] = "Geometry_"
30
+
31
+ def __init__(self, geometry: GeometryResult) -> None:
32
+ super().__init__(geometry)
33
+
34
+ @classmethod
35
+ def from_geometry_result(cls, geometry: GeometryResult) -> GeometryAdapter:
36
+ """Create GeometryAdapter from GeometryResult.
37
+
38
+ Args:
39
+ geometry: GeometryResult object
40
+
41
+ Returns:
42
+ GeometryAdapter instance
43
+ """
44
+ return cls(geometry)
45
+
46
+ @property
47
+ def headers(self) -> list[str]:
48
+ """Get column headers for the coordinates.
49
+
50
+ Returns:
51
+ List of column headers
52
+ """
53
+ # Get headers directly from the DataFrame
54
+ df = self.result.to_dataframe()
55
+ # Return coordinate columns (exclude 'roi_index' if present)
56
+ return [col for col in df.columns if col != "roi_index"]
57
+
58
+ @property
59
+ def category(self) -> str:
60
+ """Get the category.
61
+
62
+ Returns:
63
+ Category
64
+ """
65
+ return f"shape_{self.result.kind.value}"
66
+
67
+ @staticmethod
68
+ def add_geometry_result_to_obj(
69
+ geometry: GeometryResult, obj: SignalObj | ImageObj
70
+ ) -> None:
71
+ """Static method to add GeometryResult to object.
72
+
73
+ Args:
74
+ geometry: GeometryResult object
75
+ obj: Signal or image object
76
+ """
77
+ # Create adapter and add to object
78
+ adapter = GeometryAdapter.from_geometry_result(geometry)
79
+ adapter.add_to(obj)
80
+
81
+ @classmethod
82
+ def from_metadata_entry(cls, obj: SignalObj | ImageObj, key: str):
83
+ """Create a geometry result adapter from a metadata entry.
84
+
85
+ Args:
86
+ obj: Object containing the metadata
87
+ key: Metadata key for the array data
88
+
89
+ Returns:
90
+ GeometryAdapter object
91
+
92
+ Raises:
93
+ ValueError: Invalid metadata entry
94
+ """
95
+ # Load the geometry data from the dictionary
96
+ geometry_dict = obj.metadata[key]
97
+ geometry = GeometryResult.from_dict(geometry_dict)
98
+ return cls(geometry)
@@ -0,0 +1,84 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Adapter for Sigima's TableResult, providing features
5
+ for storing and retrieving those objects as metadata for DataLab's signal
6
+ and image objects.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import ClassVar, Union
12
+
13
+ from sigima.objects import ImageObj, SignalObj
14
+ from sigima.objects.scalar import NO_ROI, TableResult
15
+
16
+ from datalab.adapters_metadata.base_adapter import BaseResultAdapter
17
+
18
+
19
+ class TableAdapter(BaseResultAdapter):
20
+ """Adapter for TableResult objects.
21
+
22
+ This adapter provides a unified interface for working with TableResult objects,
23
+ including metadata storage/retrieval and various data representations.
24
+
25
+ Args:
26
+ table: TableResult object to adapt
27
+ """
28
+
29
+ # Class constants for metadata storage
30
+ META_PREFIX: ClassVar[str] = "Table_"
31
+
32
+ def __init__(self, table: TableResult) -> None:
33
+ super().__init__(table)
34
+
35
+ @property
36
+ def headers(self) -> list[str]:
37
+ """Get the column headers.
38
+
39
+ Returns:
40
+ Column headers
41
+ """
42
+ return list(self.result.headers)
43
+
44
+ @property
45
+ def category(self) -> str:
46
+ """Get the category.
47
+
48
+ Returns:
49
+ Category (uses the title for backward compatibility)
50
+ """
51
+ return self.result.title
52
+
53
+ def get_unique_roi_indices(self) -> list[int]:
54
+ """Get unique ROI indices present in the data.
55
+
56
+ Returns:
57
+ List of unique ROI indices
58
+ """
59
+ df = self.to_dataframe()
60
+ if "roi_index" in df.columns:
61
+ return sorted(df["roi_index"].unique().tolist())
62
+ return [NO_ROI] if len(df) > 0 else []
63
+
64
+ @classmethod
65
+ def from_metadata_entry(cls, obj: Union[SignalObj, ImageObj], key: str):
66
+ """Create a table result adapter from a metadata entry.
67
+
68
+ Args:
69
+ obj: Object containing the metadata
70
+ key: Metadata key for the table data
71
+
72
+ Returns:
73
+ TableAdapter object
74
+
75
+ Raises:
76
+ ValueError: Invalid metadata entry
77
+ """
78
+ if not cls.match(key, obj.metadata[key]):
79
+ raise ValueError(f"Invalid metadata key for table result: {key}")
80
+
81
+ # Parse the metadata entry as a TableResult dictionary
82
+ table_dict = obj.metadata[key]
83
+ table = TableResult.from_dict(table_dict)
84
+ return cls(table)
@@ -0,0 +1,54 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Adapters for PlotPy
5
+ ===================
6
+
7
+ The :mod:`datalab.adapters_plotpy` package provides adapters for
8
+ PlotPy to integrate with DataLab's data model and GUI.
9
+ """
10
+
11
+ __all__ = [
12
+ "CURVESTYLES",
13
+ "CircularROIPlotPyAdapter",
14
+ "GeometryPlotPyAdapter",
15
+ "ImageObjPlotPyAdapter",
16
+ "PolygonalROIPlotPyAdapter",
17
+ "RectangularROIPlotPyAdapter",
18
+ "SegmentROIPlotPyAdapter",
19
+ "SignalObjPlotPyAdapter",
20
+ "SignalROIPlotPyAdapter",
21
+ "TablePlotPyAdapter",
22
+ "TypePlotItem",
23
+ "TypeROIItem",
24
+ "configure_roi_item",
25
+ "create_adapter_from_object",
26
+ "items_to_json",
27
+ "json_to_items",
28
+ "plotitem_to_singleroi",
29
+ "singleroi_to_plotitem",
30
+ ]
31
+
32
+
33
+ from .base import items_to_json, json_to_items
34
+ from .converters import (
35
+ create_adapter_from_object,
36
+ plotitem_to_singleroi,
37
+ singleroi_to_plotitem,
38
+ )
39
+ from .objects.base import TypePlotItem
40
+ from .objects.image import (
41
+ ImageObjPlotPyAdapter,
42
+ )
43
+ from .objects.scalar import (
44
+ GeometryPlotPyAdapter,
45
+ TablePlotPyAdapter,
46
+ )
47
+ from .objects.signal import CURVESTYLES, SignalObjPlotPyAdapter
48
+ from .roi.base import TypeROIItem, configure_roi_item
49
+ from .roi.image import (
50
+ CircularROIPlotPyAdapter,
51
+ PolygonalROIPlotPyAdapter,
52
+ RectangularROIPlotPyAdapter,
53
+ )
54
+ from .roi.signal import SegmentROIPlotPyAdapter, SignalROIPlotPyAdapter