dclab 0.62.8__tar.gz → 0.62.10__tar.gz

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.

Potentially problematic release.


This version of dclab might be problematic. Click here for more details.

Files changed (322) hide show
  1. {dclab-0.62.8 → dclab-0.62.10}/CHANGELOG +11 -0
  2. {dclab-0.62.8 → dclab-0.62.10}/PKG-INFO +1 -1
  3. {dclab-0.62.8 → dclab-0.62.10}/dclab/_version.py +2 -2
  4. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/copier.py +40 -31
  5. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/core.py +12 -2
  6. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/export.py +15 -12
  7. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/feat_basin.py +9 -0
  8. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/writer.py +2 -2
  9. {dclab-0.62.8 → dclab-0.62.10}/dclab.egg-info/PKG-INFO +1 -1
  10. {dclab-0.62.8 → dclab-0.62.10}/tests/test_cli_repack.py +37 -0
  11. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_copier.py +38 -0
  12. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_feat_basin.py +62 -0
  13. {dclab-0.62.8 → dclab-0.62.10}/.gitignore +0 -0
  14. {dclab-0.62.8 → dclab-0.62.10}/.readthedocs.yml +0 -0
  15. {dclab-0.62.8 → dclab-0.62.10}/LICENSE +0 -0
  16. {dclab-0.62.8 → dclab-0.62.10}/MANIFEST.in +0 -0
  17. {dclab-0.62.8 → dclab-0.62.10}/README.rst +0 -0
  18. {dclab-0.62.8 → dclab-0.62.10}/dclab/__init__.py +0 -0
  19. {dclab-0.62.8 → dclab-0.62.10}/dclab/cached.py +0 -0
  20. {dclab-0.62.8 → dclab-0.62.10}/dclab/cli/__init__.py +0 -0
  21. {dclab-0.62.8 → dclab-0.62.10}/dclab/cli/common.py +0 -0
  22. {dclab-0.62.8 → dclab-0.62.10}/dclab/cli/task_compress.py +0 -0
  23. {dclab-0.62.8 → dclab-0.62.10}/dclab/cli/task_condense.py +0 -0
  24. {dclab-0.62.8 → dclab-0.62.10}/dclab/cli/task_join.py +0 -0
  25. {dclab-0.62.8 → dclab-0.62.10}/dclab/cli/task_repack.py +0 -0
  26. {dclab-0.62.8 → dclab-0.62.10}/dclab/cli/task_split.py +0 -0
  27. {dclab-0.62.8 → dclab-0.62.10}/dclab/cli/task_tdms2rtdc.py +0 -0
  28. {dclab-0.62.8 → dclab-0.62.10}/dclab/cli/task_verify_dataset.py +0 -0
  29. {dclab-0.62.8 → dclab-0.62.10}/dclab/definitions/__init__.py +0 -0
  30. {dclab-0.62.8 → dclab-0.62.10}/dclab/definitions/feat_const.py +0 -0
  31. {dclab-0.62.8 → dclab-0.62.10}/dclab/definitions/feat_logic.py +0 -0
  32. {dclab-0.62.8 → dclab-0.62.10}/dclab/definitions/meta_const.py +0 -0
  33. {dclab-0.62.8 → dclab-0.62.10}/dclab/definitions/meta_logic.py +0 -0
  34. {dclab-0.62.8 → dclab-0.62.10}/dclab/definitions/meta_parse.py +0 -0
  35. {dclab-0.62.8 → dclab-0.62.10}/dclab/downsampling.pyx +0 -0
  36. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/__init__.py +0 -0
  37. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/packaging/LICENSE +0 -0
  38. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/packaging/LICENSE.APACHE +0 -0
  39. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/packaging/LICENSE.BSD +0 -0
  40. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/packaging/__init__.py +0 -0
  41. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/packaging/_structures.py +0 -0
  42. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/packaging/version.py +0 -0
  43. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/skimage/LICENSE +0 -0
  44. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/skimage/__init__.py +0 -0
  45. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/skimage/_find_contours.py +0 -0
  46. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/skimage/_find_contours_cy.pyx +0 -0
  47. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/skimage/_pnpoly.pyx +0 -0
  48. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/skimage/_shared/__init__.py +0 -0
  49. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/skimage/_shared/geometry.pxd +0 -0
  50. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/skimage/_shared/geometry.pyx +0 -0
  51. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/skimage/measure.py +0 -0
  52. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/skimage/pnpoly.py +0 -0
  53. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/statsmodels/LICENSE +0 -0
  54. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/statsmodels/__init__.py +0 -0
  55. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/statsmodels/nonparametric/__init__.py +0 -0
  56. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/statsmodels/nonparametric/_kernel_base.py +0 -0
  57. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/statsmodels/nonparametric/kernel_density.py +0 -0
  58. {dclab-0.62.8 → dclab-0.62.10}/dclab/external/statsmodels/nonparametric/kernels.py +0 -0
  59. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/__init__.py +0 -0
  60. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/bright.py +0 -0
  61. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/bright_bc.py +0 -0
  62. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/bright_perc.py +0 -0
  63. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/contour.py +0 -0
  64. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/emodulus/__init__.py +0 -0
  65. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/emodulus/load.py +0 -0
  66. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/emodulus/lut_HE-2D-FEM-22.txt +0 -0
  67. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/emodulus/lut_HE-3D-FEM-22.txt +0 -0
  68. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/emodulus/lut_LE-2D-FEM-19.txt +0 -0
  69. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/emodulus/pxcorr.py +0 -0
  70. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/emodulus/scale_linear.py +0 -0
  71. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/emodulus/viscosity.py +0 -0
  72. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/fl_crosstalk.py +0 -0
  73. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/inert_ratio.py +0 -0
  74. {dclab-0.62.8 → dclab-0.62.10}/dclab/features/volume.py +0 -0
  75. {dclab-0.62.8 → dclab-0.62.10}/dclab/http_utils.py +0 -0
  76. {dclab-0.62.8 → dclab-0.62.10}/dclab/isoelastics/__init__.py +0 -0
  77. {dclab-0.62.8 → dclab-0.62.10}/dclab/isoelastics/iso_HE-2D-FEM-22-area_um-deform.txt +0 -0
  78. {dclab-0.62.8 → dclab-0.62.10}/dclab/isoelastics/iso_HE-2D-FEM-22-volume-deform.txt +0 -0
  79. {dclab-0.62.8 → dclab-0.62.10}/dclab/isoelastics/iso_HE-3D-FEM-22-area_um-deform.txt +0 -0
  80. {dclab-0.62.8 → dclab-0.62.10}/dclab/isoelastics/iso_HE-3D-FEM-22-volume-deform.txt +0 -0
  81. {dclab-0.62.8 → dclab-0.62.10}/dclab/isoelastics/iso_LE-2D-FEM-19-area_um-deform.txt +0 -0
  82. {dclab-0.62.8 → dclab-0.62.10}/dclab/isoelastics/iso_LE-2D-FEM-19-volume-deform.txt +0 -0
  83. {dclab-0.62.8 → dclab-0.62.10}/dclab/isoelastics/iso_LE-2D-ana-18-area_um-deform.txt +0 -0
  84. {dclab-0.62.8 → dclab-0.62.10}/dclab/kde_contours.py +0 -0
  85. {dclab-0.62.8 → dclab-0.62.10}/dclab/kde_methods.py +0 -0
  86. {dclab-0.62.8 → dclab-0.62.10}/dclab/lme4/__init__.py +0 -0
  87. {dclab-0.62.8 → dclab-0.62.10}/dclab/lme4/lme4_template.R +0 -0
  88. {dclab-0.62.8 → dclab-0.62.10}/dclab/lme4/rsetup.py +0 -0
  89. {dclab-0.62.8 → dclab-0.62.10}/dclab/lme4/wrapr.py +0 -0
  90. {dclab-0.62.8 → dclab-0.62.10}/dclab/polygon_filter.py +0 -0
  91. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/__init__.py +0 -0
  92. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/check.py +0 -0
  93. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/config.py +0 -0
  94. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/feat_anc_core/__init__.py +0 -0
  95. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/feat_anc_core/af_basic.py +0 -0
  96. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/feat_anc_core/af_emodulus.py +0 -0
  97. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/feat_anc_core/af_fl_max_ctc.py +0 -0
  98. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/feat_anc_core/af_image_contour.py +0 -0
  99. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/feat_anc_core/af_ml_class.py +0 -0
  100. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/feat_anc_core/ancillary_feature.py +0 -0
  101. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/feat_anc_ml/__init__.py +0 -0
  102. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/feat_anc_plugin/__init__.py +0 -0
  103. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/feat_anc_plugin/plugin_feature.py +0 -0
  104. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/feat_temp.py +0 -0
  105. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/filter.py +0 -0
  106. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_dcor/__init__.py +0 -0
  107. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_dcor/access_token.py +0 -0
  108. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_dcor/api.py +0 -0
  109. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_dcor/base.py +0 -0
  110. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_dcor/basin.py +0 -0
  111. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_dcor/logs.py +0 -0
  112. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_dcor/tables.py +0 -0
  113. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_dict.py +0 -0
  114. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_hdf5/__init__.py +0 -0
  115. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_hdf5/base.py +0 -0
  116. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_hdf5/basin.py +0 -0
  117. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_hdf5/events.py +0 -0
  118. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_hdf5/feat_defect.py +0 -0
  119. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_hdf5/logs.py +0 -0
  120. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_hdf5/tables.py +0 -0
  121. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_hierarchy/__init__.py +0 -0
  122. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_hierarchy/base.py +0 -0
  123. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_hierarchy/events.py +0 -0
  124. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_hierarchy/hfilter.py +0 -0
  125. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_hierarchy/mapper.py +0 -0
  126. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_http.py +0 -0
  127. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_s3.py +0 -0
  128. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_tdms/__init__.py +0 -0
  129. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_tdms/event_contour.py +0 -0
  130. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_tdms/event_image.py +0 -0
  131. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_tdms/event_mask.py +0 -0
  132. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_tdms/event_trace.py +0 -0
  133. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_tdms/exc.py +0 -0
  134. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/fmt_tdms/naming.py +0 -0
  135. {dclab-0.62.8 → dclab-0.62.10}/dclab/rtdc_dataset/load.py +0 -0
  136. {dclab-0.62.8 → dclab-0.62.10}/dclab/statistics.py +0 -0
  137. {dclab-0.62.8 → dclab-0.62.10}/dclab/util.py +0 -0
  138. {dclab-0.62.8 → dclab-0.62.10}/dclab/warn.py +0 -0
  139. {dclab-0.62.8 → dclab-0.62.10}/dclab.egg-info/SOURCES.txt +0 -0
  140. {dclab-0.62.8 → dclab-0.62.10}/dclab.egg-info/dependency_links.txt +0 -0
  141. {dclab-0.62.8 → dclab-0.62.10}/dclab.egg-info/entry_points.txt +0 -0
  142. {dclab-0.62.8 → dclab-0.62.10}/dclab.egg-info/requires.txt +0 -0
  143. {dclab-0.62.8 → dclab-0.62.10}/dclab.egg-info/top_level.txt +0 -0
  144. {dclab-0.62.8 → dclab-0.62.10}/docs/.gitignore +0 -0
  145. {dclab-0.62.8 → dclab-0.62.10}/docs/README.md +0 -0
  146. {dclab-0.62.8 → dclab-0.62.10}/docs/conf.py +0 -0
  147. {dclab-0.62.8 → dclab-0.62.10}/docs/data/example.poly +0 -0
  148. {dclab-0.62.8 → dclab-0.62.10}/docs/data/example.rtdc +0 -0
  149. {dclab-0.62.8 → dclab-0.62.10}/docs/data/example_plugin.py +0 -0
  150. {dclab-0.62.8 → dclab-0.62.10}/docs/data/example_plugin_metadata.py +0 -0
  151. {dclab-0.62.8 → dclab-0.62.10}/docs/data/example_traces.rtdc +0 -0
  152. {dclab-0.62.8 → dclab-0.62.10}/docs/data/example_video.rtdc +0 -0
  153. {dclab-0.62.8 → dclab-0.62.10}/docs/dclab.bib +0 -0
  154. {dclab-0.62.8 → dclab-0.62.10}/docs/extensions/dclab_defs.py +0 -0
  155. {dclab-0.62.8 → dclab-0.62.10}/docs/extensions/fancy_include.py +0 -0
  156. {dclab-0.62.8 → dclab-0.62.10}/docs/extensions/github_changelog.py +0 -0
  157. {dclab-0.62.8 → dclab-0.62.10}/docs/extensions/simple_argparse.py +0 -0
  158. {dclab-0.62.8 → dclab-0.62.10}/docs/figures/DCOR_API_Token_website.png +0 -0
  159. {dclab-0.62.8 → dclab-0.62.10}/docs/index.rst +0 -0
  160. {dclab-0.62.8 → dclab-0.62.10}/docs/logo/dc_logo.png +0 -0
  161. {dclab-0.62.8 → dclab-0.62.10}/docs/logo/dc_logo.svg +0 -0
  162. {dclab-0.62.8 → dclab-0.62.10}/docs/logo/dclab.png +0 -0
  163. {dclab-0.62.8 → dclab-0.62.10}/docs/logo/dclab.svg +0 -0
  164. {dclab-0.62.8 → dclab-0.62.10}/docs/logo/dclab_large_white.png +0 -0
  165. {dclab-0.62.8 → dclab-0.62.10}/docs/logo/dclab_large_white.svg +0 -0
  166. {dclab-0.62.8 → dclab-0.62.10}/docs/logo/favicon.ico +0 -0
  167. {dclab-0.62.8 → dclab-0.62.10}/docs/logo/favicon.svg +0 -0
  168. {dclab-0.62.8 → dclab-0.62.10}/docs/requirements.txt +0 -0
  169. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_advanced_usage.rst +0 -0
  170. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_basins/index.rst +0 -0
  171. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_dc_io.rst +0 -0
  172. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_dc_usage.rst +0 -0
  173. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_dcor.rst +0 -0
  174. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_emodulus/figures_emodulus/.gitignore +0 -0
  175. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_emodulus/figures_emodulus/emodulus_20um_HE-2D-FEM-22.png +0 -0
  176. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_emodulus/figures_emodulus/emodulus_20um_HE-3D-FEM-22.png +0 -0
  177. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_emodulus/figures_emodulus/emodulus_20um_LE-2D-FEM-19.png +0 -0
  178. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_emodulus/figures_emodulus/plot_emodulus_lut.py +0 -0
  179. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_emodulus/figures_emodulus/requirements.txt +0 -0
  180. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_emodulus/figures_viscosity/LICENSE +0 -0
  181. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_emodulus/figures_viscosity/buyukurganci_22_fig3a.jpg +0 -0
  182. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_emodulus/figures_viscosity/buyukurganci_22_fig3a.pdf +0 -0
  183. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_emodulus/index.rst +0 -0
  184. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_feat_plugin.rst +0 -0
  185. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_feat_temp.rst +0 -0
  186. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_fluorescence.rst +0 -0
  187. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_lme4.rst +0 -0
  188. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_notation.rst +0 -0
  189. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_s3.rst +0 -0
  190. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_av_scatter.rst +0 -0
  191. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_changelog.rst +0 -0
  192. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_cli.rst +0 -0
  193. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_code_reference.rst +0 -0
  194. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_examples.rst +0 -0
  195. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_getting_started.rst +0 -0
  196. {dclab-0.62.8 → dclab-0.62.10}/docs/sec_z_bib.rst +0 -0
  197. {dclab-0.62.8 → dclab-0.62.10}/examples/emodulus_dcor.jpg +0 -0
  198. {dclab-0.62.8 → dclab-0.62.10}/examples/emodulus_dcor.py +0 -0
  199. {dclab-0.62.8 → dclab-0.62.10}/examples/generate_example_images.py +0 -0
  200. {dclab-0.62.8 → dclab-0.62.10}/examples/isoelastics.jpg +0 -0
  201. {dclab-0.62.8 → dclab-0.62.10}/examples/isoelastics.py +0 -0
  202. {dclab-0.62.8 → dclab-0.62.10}/examples/isoelastics_custom.jpg +0 -0
  203. {dclab-0.62.8 → dclab-0.62.10}/examples/isoelastics_custom.py +0 -0
  204. {dclab-0.62.8 → dclab-0.62.10}/examples/lme4_glmer_diff.py +0 -0
  205. {dclab-0.62.8 → dclab-0.62.10}/examples/lme4_lmer.jpg +0 -0
  206. {dclab-0.62.8 → dclab-0.62.10}/examples/lme4_lmer.py +0 -0
  207. {dclab-0.62.8 → dclab-0.62.10}/examples/overview_plot.jpg +0 -0
  208. {dclab-0.62.8 → dclab-0.62.10}/examples/overview_plot.py +0 -0
  209. {dclab-0.62.8 → dclab-0.62.10}/examples/plugin_example.py +0 -0
  210. {dclab-0.62.8 → dclab-0.62.10}/examples/plugin_usage.jpg +0 -0
  211. {dclab-0.62.8 → dclab-0.62.10}/examples/plugin_usage.py +0 -0
  212. {dclab-0.62.8 → dclab-0.62.10}/examples/viscosity_models.jpg +0 -0
  213. {dclab-0.62.8 → dclab-0.62.10}/examples/viscosity_models.py +0 -0
  214. {dclab-0.62.8 → dclab-0.62.10}/pyproject.toml +0 -0
  215. {dclab-0.62.8 → dclab-0.62.10}/scripts/.gitignore +0 -0
  216. {dclab-0.62.8 → dclab-0.62.10}/scripts/README.md +0 -0
  217. {dclab-0.62.8 → dclab-0.62.10}/scripts/fem2iso_volume.py +0 -0
  218. {dclab-0.62.8 → dclab-0.62.10}/scripts/fem2lutiso_std.py +0 -0
  219. {dclab-0.62.8 → dclab-0.62.10}/scripts/fem2rtdc.py +0 -0
  220. {dclab-0.62.8 → dclab-0.62.10}/scripts/lut_recipes/__init__.py +0 -0
  221. {dclab-0.62.8 → dclab-0.62.10}/scripts/lut_recipes/hooks/LUT_analytical_linear-elastic_2Daxis.txt +0 -0
  222. {dclab-0.62.8 → dclab-0.62.10}/scripts/lut_recipes/hooks/README.md +0 -0
  223. {dclab-0.62.8 → dclab-0.62.10}/scripts/lut_recipes/hooks/__init__.py +0 -0
  224. {dclab-0.62.8 → dclab-0.62.10}/scripts/lut_recipes/hooks/common.py +0 -0
  225. {dclab-0.62.8 → dclab-0.62.10}/scripts/lut_recipes/hooks/he_2d_fem_22.py +0 -0
  226. {dclab-0.62.8 → dclab-0.62.10}/scripts/lut_recipes/hooks/he_3d_fem_22.py +0 -0
  227. {dclab-0.62.8 → dclab-0.62.10}/scripts/lut_recipes/hooks/le_2d_fem_19.py +0 -0
  228. {dclab-0.62.8 → dclab-0.62.10}/scripts/lut_recipes/lut_processor.py +0 -0
  229. {dclab-0.62.8 → dclab-0.62.10}/scripts/pixelation_correction.py +0 -0
  230. {dclab-0.62.8 → dclab-0.62.10}/scripts/pixelation_correction_2020.png +0 -0
  231. {dclab-0.62.8 → dclab-0.62.10}/scripts/pixelation_correction_2022.png +0 -0
  232. {dclab-0.62.8 → dclab-0.62.10}/scripts/requirements.txt +0 -0
  233. {dclab-0.62.8 → dclab-0.62.10}/setup.cfg +0 -0
  234. {dclab-0.62.8 → dclab-0.62.10}/setup.py +0 -0
  235. {dclab-0.62.8 → dclab-0.62.10}/tests/README.md +0 -0
  236. {dclab-0.62.8 → dclab-0.62.10}/tests/conftest.py +0 -0
  237. {dclab-0.62.8 → dclab-0.62.10}/tests/data/README.md +0 -0
  238. {dclab-0.62.8 → dclab-0.62.10}/tests/data/example_access_token.dcor-access +0 -0
  239. {dclab-0.62.8 → dclab-0.62.10}/tests/data/example_isoelastics.txt +0 -0
  240. {dclab-0.62.8 → dclab-0.62.10}/tests/data/feat_anc_plugin_creative.py +0 -0
  241. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-hdf5_fl-no-contour_2019.zip +0 -0
  242. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-hdf5_fl_2017.zip +0 -0
  243. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-hdf5_fl_2018.zip +0 -0
  244. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-hdf5_fl_wide-channel_2023.zip +0 -0
  245. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-hdf5_image-bg_2020.zip +0 -0
  246. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-hdf5_image-mask-blood_2021.zip +0 -0
  247. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-hdf5_mask-contour_2018.zip +0 -0
  248. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-hdf5_polygon_gate_2021.zip +0 -0
  249. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-hdf5_raw-cytoshot-exported.zip +0 -0
  250. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-hdf5_segfault-compound_2023.zip +0 -0
  251. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-hdf5_wide-channel_2023.zip +0 -0
  252. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-tdms_2fl-no-image_2017.zip +0 -0
  253. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-tdms_fl-image-bright_2017.zip +0 -0
  254. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-tdms_fl-image-large-fov_2017.zip +0 -0
  255. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-tdms_fl-image_2016.zip +0 -0
  256. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-tdms_fl_2015.zip +0 -0
  257. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-tdms_minimal_2016.zip +0 -0
  258. {dclab-0.62.8 → dclab-0.62.10}/tests/data/fmt-tdms_shapein-2.0.1-no-image_2017.zip +0 -0
  259. {dclab-0.62.8 → dclab-0.62.10}/tests/helper_methods.py +0 -0
  260. {dclab-0.62.8 → dclab-0.62.10}/tests/requirements.txt +0 -0
  261. {dclab-0.62.8 → dclab-0.62.10}/tests/test_cache.py +0 -0
  262. {dclab-0.62.8 → dclab-0.62.10}/tests/test_cli.py +0 -0
  263. {dclab-0.62.8 → dclab-0.62.10}/tests/test_cli_argparse.py +0 -0
  264. {dclab-0.62.8 → dclab-0.62.10}/tests/test_cli_compress.py +0 -0
  265. {dclab-0.62.8 → dclab-0.62.10}/tests/test_cli_condense.py +0 -0
  266. {dclab-0.62.8 → dclab-0.62.10}/tests/test_cli_join.py +0 -0
  267. {dclab-0.62.8 → dclab-0.62.10}/tests/test_cli_split.py +0 -0
  268. {dclab-0.62.8 → dclab-0.62.10}/tests/test_config_value_mapping.py +0 -0
  269. {dclab-0.62.8 → dclab-0.62.10}/tests/test_dfn.py +0 -0
  270. {dclab-0.62.8 → dclab-0.62.10}/tests/test_downsampling.py +0 -0
  271. {dclab-0.62.8 → dclab-0.62.10}/tests/test_feat_bright.py +0 -0
  272. {dclab-0.62.8 → dclab-0.62.10}/tests/test_feat_bright_bc.py +0 -0
  273. {dclab-0.62.8 → dclab-0.62.10}/tests/test_feat_bright_perc.py +0 -0
  274. {dclab-0.62.8 → dclab-0.62.10}/tests/test_feat_contour.py +0 -0
  275. {dclab-0.62.8 → dclab-0.62.10}/tests/test_feat_emodulus.py +0 -0
  276. {dclab-0.62.8 → dclab-0.62.10}/tests/test_feat_emodulus_viscosity.py +0 -0
  277. {dclab-0.62.8 → dclab-0.62.10}/tests/test_feat_fl_crosstalk.py +0 -0
  278. {dclab-0.62.8 → dclab-0.62.10}/tests/test_feat_inert_ratio.py +0 -0
  279. {dclab-0.62.8 → dclab-0.62.10}/tests/test_feat_volume.py +0 -0
  280. {dclab-0.62.8 → dclab-0.62.10}/tests/test_http_utils.py +0 -0
  281. {dclab-0.62.8 → dclab-0.62.10}/tests/test_isoelastics.py +0 -0
  282. {dclab-0.62.8 → dclab-0.62.10}/tests/test_kde_contours.py +0 -0
  283. {dclab-0.62.8 → dclab-0.62.10}/tests/test_kde_methods.py +0 -0
  284. {dclab-0.62.8 → dclab-0.62.10}/tests/test_lme4.py +0 -0
  285. {dclab-0.62.8 → dclab-0.62.10}/tests/test_lut_he_2d_fem_22.py +0 -0
  286. {dclab-0.62.8 → dclab-0.62.10}/tests/test_lut_he_3d_fem_22.py +0 -0
  287. {dclab-0.62.8 → dclab-0.62.10}/tests/test_polygon_contains.py +0 -0
  288. {dclab-0.62.8 → dclab-0.62.10}/tests/test_polygon_filter.py +0 -0
  289. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_check_dataset.py +0 -0
  290. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_config.py +0 -0
  291. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_core_feat.py +0 -0
  292. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_downsampling.py +0 -0
  293. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_export.py +0 -0
  294. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_export_avi.py +0 -0
  295. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_export_fcs.py +0 -0
  296. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_export_hdf5.py +0 -0
  297. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_export_tsv.py +0 -0
  298. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_feat_anc_core.py +0 -0
  299. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_feat_anc_ml.py +0 -0
  300. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_feat_anc_plugin.py +0 -0
  301. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_feat_basin_mapped.py +0 -0
  302. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_feat_temp.py +0 -0
  303. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_filter.py +0 -0
  304. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_dcor.py +0 -0
  305. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_dcor_access_token.py +0 -0
  306. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_dcor_basin.py +0 -0
  307. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_dict.py +0 -0
  308. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_hdf5.py +0 -0
  309. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_hdf5_basins.py +0 -0
  310. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_hdf5_basins_internal.py +0 -0
  311. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_hierarchy.py +0 -0
  312. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_http.py +0 -0
  313. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_http_basin.py +0 -0
  314. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_s3.py +0 -0
  315. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_s3_basin.py +0 -0
  316. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_fmt_tdms.py +0 -0
  317. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_hash.py +0 -0
  318. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_kde.py +0 -0
  319. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_limit_events.py +0 -0
  320. {dclab-0.62.8 → dclab-0.62.10}/tests/test_rtdc_writer.py +0 -0
  321. {dclab-0.62.8 → dclab-0.62.10}/tests/test_statistics.py +0 -0
  322. {dclab-0.62.8 → dclab-0.62.10}/tests/test_util.py +0 -0
@@ -1,3 +1,14 @@
1
+ 0.62.10
2
+ - fix: `basin_definition_copy` failed when more than one basins defined
3
+ due to redundant loop
4
+ - fix: JSON logs during export were not sorted and indented
5
+ 0.62.9
6
+ - enh: sort basin definition before exporting to JSON; the side-effect
7
+ is that the unique key for a basin changes, possibly resulting in
8
+ duplicated basin definitions for existing datasets
9
+ - enh: make sure every basin can be identified with a key created from
10
+ its definition; important for connecting the basin dictionaries
11
+ with the instantiated basins
1
12
  0.62.8
2
13
  - fix: metadata of tables not copied by `copier.py`
3
14
  - docs: formatting typo (#270)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dclab
3
- Version: 0.62.8
3
+ Version: 0.62.10
4
4
  Summary: Library for real-time deformability cytometry (RT-DC)
5
5
  Author: Benedikt Hartmann, Eoghan O'Connell, Maik Herbig, Maximilian Schlögel, Nadia Sbaa, Paul Müller, Philipp Rosendahl, Raghava Alajangi
6
6
  Maintainer-email: Paul Müller <dev@craban.de>
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.62.8'
16
- __version_tuple__ = version_tuple = (0, 62, 8)
15
+ __version__ = version = '0.62.10'
16
+ __version_tuple__ = version_tuple = (0, 62, 10)
@@ -178,42 +178,51 @@ def basin_definition_copy(src_h5file, dst_h5file, features_iter):
178
178
  relevant for the internal basin.
179
179
  """
180
180
  dst_h5file.require_group("basins")
181
- for b_key in src_h5file["basins"]:
181
+ # Load the basin information
182
+ basin_dicts = RTDC_HDF5.basin_get_dicts_from_h5file(src_h5file)
183
+ for bn in basin_dicts:
184
+ b_key = bn["key"]
185
+
182
186
  if b_key in dst_h5file["basins"]:
183
- # This basin already exists.
187
+ # already stored therein
184
188
  continue
185
- # Load the basin information
186
- basin_dicts = RTDC_HDF5.basin_get_dicts_from_h5file(src_h5file)
187
- for bn in basin_dicts:
188
- if bn["type"] == "internal":
189
- # Make sure we define the internal features selected
190
- feat_used = [f for f in bn["features"] if f in features_iter]
191
- if len(feat_used) == 0:
192
- # We don't have any internal features, don't write anything
193
- continue
194
- elif feat_used != bn["features"]:
195
- bn["features"] = feat_used
196
- rewrite = True
197
- else:
198
- rewrite = False
189
+
190
+ # sanity check
191
+ if b_key not in src_h5file["basins"]:
192
+ raise ValueError(
193
+ f"Failed to parse basin information correctly. Source file "
194
+ f"{src_h5file} does not contain basin {b_key} which I got "
195
+ f"from `RTDC_HDF5.basin_get_dicts_from_h5file`.")
196
+
197
+ if bn["type"] == "internal":
198
+ # Make sure we define the internal features selected
199
+ feat_used = [f for f in bn["features"] if f in features_iter]
200
+ if len(feat_used) == 0:
201
+ # We don't have any internal features, don't write anything
202
+ continue
203
+ elif feat_used != bn["features"]:
204
+ bn["features"] = feat_used
205
+ rewrite = True
199
206
  else:
200
- # We do not have an internal basin, just copy everything
201
207
  rewrite = False
208
+ else:
209
+ # We do not have an internal basin, just copy everything
210
+ rewrite = False
202
211
 
203
- if rewrite:
204
- # Convert edited `bn` to JSON and write feature data
205
- b_lines = json.dumps(bn, indent=2).split("\n")
206
- key = hashobj(b_lines)
207
- if key not in dst_h5file["basins"]:
208
- with RTDCWriter(dst_h5file) as hw:
209
- hw.write_text(dst_h5file["basins"], key, b_lines)
210
- else:
211
- # copy only
212
- h5ds_copy(src_loc=src_h5file["basins"],
213
- src_name=b_key,
214
- dst_loc=dst_h5file["basins"],
215
- dst_name=b_key,
216
- recursive=False)
212
+ if rewrite:
213
+ # Convert edited `bn` to JSON and write feature data
214
+ b_lines = json.dumps(bn, indent=2).split("\n")
215
+ key = hashobj(b_lines)
216
+ if key not in dst_h5file["basins"]:
217
+ with RTDCWriter(dst_h5file) as hw:
218
+ hw.write_text(dst_h5file["basins"], key, b_lines)
219
+ else:
220
+ # copy only
221
+ h5ds_copy(src_loc=src_h5file["basins"],
222
+ src_name=b_key,
223
+ dst_loc=dst_h5file["basins"],
224
+ dst_name=b_key,
225
+ recursive=False)
217
226
 
218
227
 
219
228
  def h5ds_copy(src_loc, src_name, dst_loc, dst_name=None,
@@ -1,6 +1,7 @@
1
1
  """RT-DC dataset core classes and methods"""
2
2
  import abc
3
3
  import hashlib
4
+ import json
4
5
  import os.path
5
6
  import pathlib
6
7
  import traceback
@@ -15,6 +16,7 @@ from .. import definitions as dfn
15
16
  from .. import downsampling
16
17
  from ..polygon_filter import PolygonFilter
17
18
  from .. import kde_methods
19
+ from ..util import hashobj
18
20
 
19
21
  from .feat_anc_core import AncillaryFeature, FEATURES_RAPID
20
22
  from . import feat_basin
@@ -825,14 +827,20 @@ class RTDCBase(abc.ABC):
825
827
  # Sort basins according to priority
826
828
  bdicts_srt = sorted(self.basins_get_dicts(),
827
829
  key=feat_basin.basin_priority_sorted_key)
828
- bd_keys = [bd["key"] for bd in bdicts_srt if "key" in bd]
830
+ # complement basin "key"s (we do the same in writer)
831
+ for bdict in bdicts_srt:
832
+ if "key" not in bdict:
833
+ b_dat = json.dumps(bdict, indent=2, sort_keys=True).split("\n")
834
+ bdict["key"] = hashobj(b_dat)
835
+
836
+ bd_keys = [bd["key"] for bd in bdicts_srt]
829
837
  bd_keys += self._basins_ignored
830
838
  for bdict in bdicts_srt:
831
839
  if bdict["format"] not in bc:
832
840
  warnings.warn(f"Encountered unsupported basin "
833
841
  f"format '{bdict['format']}'!")
834
842
  continue
835
- if "key" in bdict and bdict["key"] in self._basins_ignored:
843
+ if bdict["key"] in self._basins_ignored:
836
844
  warnings.warn(
837
845
  f"Encountered cyclic basin dependency '{bdict['key']}'",
838
846
  feat_basin.CyclicBasinDependencyFoundWarning)
@@ -853,6 +861,8 @@ class RTDCBase(abc.ABC):
853
861
  "measurement_identifier": self.get_measurement_identifier(),
854
862
  # allow to ignore basins
855
863
  "ignored_basins": bd_keys,
864
+ # basin key
865
+ "key": bdict["key"],
856
866
  }
857
867
 
858
868
  # Check whether this basin is supported and exists
@@ -319,18 +319,21 @@ class Export(object):
319
319
 
320
320
  # write export log
321
321
  hw.store_log(time.strftime("dclab-export_%Y-%m-%d_%H.%M.%S"),
322
- json.dumps({
323
- "dclab version": version_tuple,
324
- "kwargs": {
325
- "features": features,
326
- "filtered": filtered,
327
- "logs": logs,
328
- "tables": tables,
329
- "basins": basins,
330
- "meta_prefix": meta_prefix,
331
- "skip_checks": skip_checks
332
- }
333
- }).split("\n"))
322
+ json.dumps(
323
+ {"dclab version": version_tuple,
324
+ "kwargs": {
325
+ "features": features,
326
+ "filtered": filtered,
327
+ "logs": logs,
328
+ "tables": tables,
329
+ "basins": basins,
330
+ "meta_prefix": meta_prefix,
331
+ "skip_checks": skip_checks
332
+ }
333
+ },
334
+ indent=2,
335
+ sort_keys=True,
336
+ ).split("\n"))
334
337
 
335
338
  if logs:
336
339
  # write logs
@@ -9,6 +9,7 @@ import abc
9
9
  import numbers
10
10
  import threading
11
11
  from typing import Dict, List, Literal
12
+ import uuid
12
13
  import warnings
13
14
  import weakref
14
15
 
@@ -74,6 +75,7 @@ class Basin(abc.ABC):
74
75
  ] = "same",
75
76
  mapping_referrer: Dict = None,
76
77
  ignored_basins: List[str] = None,
78
+ key: str = None,
77
79
  **kwargs):
78
80
  """
79
81
 
@@ -109,6 +111,10 @@ class Basin(abc.ABC):
109
111
  :class:`.RTDCBase`.
110
112
  ignored_basins: list of str
111
113
  List of basins to ignore in subsequent basin instantiations
114
+ key: str
115
+ Unique key to identify this basin; normally computed from
116
+ a JSON dump of the basin definition. A random string is used
117
+ if None is specified.
112
118
  kwargs:
113
119
  Additional keyword arguments passed to the `load_dataset`
114
120
  method of the `Basin` subclass.
@@ -124,6 +130,8 @@ class Basin(abc.ABC):
124
130
  self.name = name
125
131
  #: lengthy description of the basin
126
132
  self.description = description
133
+ # defining key of the basin
134
+ self.key = key or str(uuid.uuid4())
127
135
  # features this basin provides
128
136
  self._features = features
129
137
  #: measurement identifier of the referencing dataset
@@ -367,6 +375,7 @@ class BasinProxy:
367
375
  dataset to the downstream dataset
368
376
  """
369
377
  self.ds = ds
378
+ self.basins_get_dicts = ds.basins_get_dicts
370
379
  self.basinmap = basinmap
371
380
  self._features = {}
372
381
 
@@ -389,7 +389,7 @@ class RTDCWriter:
389
389
  flocs.append(str(pp.resolve()))
390
390
  # Also store the relative path for user convenience.
391
391
  # Don't use pathlib.Path.relative_to, because that
392
- # is deprecated in Python 3.12.
392
+ # only has `walk_up` since Python 3.12.
393
393
  # Also, just look in subdirectories which simplifies
394
394
  # path resolution.
395
395
  this_parent = str(self.path.parent) + os.sep
@@ -408,7 +408,7 @@ class RTDCWriter:
408
408
  else:
409
409
  raise ValueError(f"Unknown basin type '{basin_type}'")
410
410
 
411
- b_lines = json.dumps(b_data, indent=2).split("\n")
411
+ b_lines = json.dumps(b_data, indent=2, sort_keys=True).split("\n")
412
412
  basins = self.h5file.require_group("basins")
413
413
  key = hashobj(b_lines)
414
414
  if key not in basins:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dclab
3
- Version: 0.62.8
3
+ Version: 0.62.10
4
4
  Summary: Library for real-time deformability cytometry (RT-DC)
5
5
  Author: Benedikt Hartmann, Eoghan O'Connell, Maik Herbig, Maximilian Schlögel, Nadia Sbaa, Paul Müller, Philipp Rosendahl, Raghava Alajangi
6
6
  Maintainer-email: Paul Müller <dev@craban.de>
@@ -80,6 +80,43 @@ def test_repack_basin_internal(use_basins):
80
80
  assert "userdef1" not in ds.features_basin
81
81
 
82
82
 
83
+ @pytest.mark.filterwarnings(
84
+ "ignore::dclab.rtdc_dataset.config.WrongConfigurationTypeWarning")
85
+ def test_repack_multiple_basins():
86
+ h5path = retrieve_data("fmt-hdf5_fl_wide-channel_2023.zip")
87
+ h5path_small = h5path.with_name("smaller.rtdc")
88
+ h5path_out = h5path.with_name("repacked.rtdc")
89
+
90
+ # Dataset creation
91
+ with h5py.File(h5path) as src, RTDCWriter(h5path_small) as hw:
92
+ # first, copy all the scalar features to the new file
93
+ rtdc_dataset.rtdc_copy(src_h5file=src,
94
+ dst_h5file=hw.h5file,
95
+ features="scalar")
96
+ hw.store_basin(basin_name="example basin",
97
+ basin_type="file",
98
+ basin_format="hdf5",
99
+ basin_locs=[h5path],
100
+ basin_descr="an example test basin",
101
+ )
102
+
103
+ hw.store_basin(basin_name="example basin",
104
+ basin_type="file",
105
+ basin_format="hdf5",
106
+ basin_locs=[h5path],
107
+ basin_descr="a different test basin",
108
+ )
109
+
110
+ assert len(hw.h5file["basins"].keys()) == 2
111
+
112
+ # repack the basin-based dataset
113
+ cli.repack(path_in=h5path_small,
114
+ path_out=h5path_out)
115
+
116
+ with new_dataset(h5path_out) as ds:
117
+ assert len(ds.basins) == 2
118
+
119
+
83
120
  def test_repack_no_data_from_basins_written():
84
121
  """
85
122
  When repacking a dataset, feature data from the basin should not be
@@ -203,6 +203,44 @@ def test_copy_basins_mapped():
203
203
  assert is_properly_compressed(hc["events/basinmap0"])
204
204
 
205
205
 
206
+ def test_copy_basins_multiple():
207
+ path = retrieve_data("fmt-hdf5_image-bg_2020.zip")
208
+ path_copy = path.with_name("test_copy.rtdc")
209
+
210
+ # add log to source file
211
+ with RTDCWriter(path, mode="append") as hw:
212
+ hw.store_basin(
213
+ basin_type="file",
214
+ basin_format="hdf5",
215
+ basin_name="test_basin",
216
+ basin_locs=["does-not-exist-but-does-not-matter.rtdc"],
217
+ basin_map=np.arange(len(hw.h5file["events/deform"])),
218
+ basin_descr="A first basin",
219
+ verify=False
220
+ )
221
+
222
+ hw.store_basin(
223
+ basin_type="file",
224
+ basin_format="hdf5",
225
+ basin_name="test_basin",
226
+ basin_locs=["does-not-exist-but-does-not-matter.rtdc"],
227
+ basin_map=np.arange(len(hw.h5file["events/deform"])),
228
+ basin_descr="A second basin",
229
+ verify=False
230
+ )
231
+
232
+ assert len(hw.h5file["basins"]) == 2
233
+
234
+ # copy
235
+ with h5py.File(path) as h5, h5py.File(path_copy, "w") as hc:
236
+ rtdc_copy(src_h5file=h5,
237
+ dst_h5file=hc)
238
+
239
+ # Make sure this worked
240
+ with h5py.File(path_copy) as hc:
241
+ assert len(hc["basins"]) == 2
242
+
243
+
206
244
  def test_copy_basins_no_basin():
207
245
  path = retrieve_data("fmt-hdf5_image-bg_2020.zip")
208
246
  path_copy = path.with_name("test_copy.rtdc")
@@ -356,6 +356,68 @@ def test_basin_relative_paths(path_sep):
356
356
  assert "image" in ds
357
357
 
358
358
 
359
+ @pytest.mark.filterwarnings(
360
+ "ignore::dclab.rtdc_dataset.config.WrongConfigurationTypeWarning")
361
+ def test_basin_key_reproducible():
362
+ """Since 0.62.9 we sort basin keys"""
363
+ h5path = retrieve_data("fmt-hdf5_fl_wide-channel_2023.zip")
364
+ h5path_small = h5path.parent / "subdirectory" / "relative.rtdc"
365
+ h5path_small.parent.mkdir()
366
+ h5path_small_2 = h5path_small.with_name("from_writer.rtdc")
367
+
368
+ # Dataset creation
369
+ with h5py.File(h5path) as src, RTDCWriter(h5path_small) as hw:
370
+ # first, copy all the scalar features to the new file
371
+ rtdc_dataset.rtdc_copy(src_h5file=src,
372
+ dst_h5file=hw.h5file,
373
+ features="scalar")
374
+ # Next, store the basin information in the new dataset manually
375
+ bdat = {
376
+ "type": "file",
377
+ "format": "hdf5",
378
+ "features": ["image"],
379
+ "paths": [f"../{h5path.name}"]
380
+ }
381
+ blines = json.dumps(bdat, indent=2).split("\n")
382
+ basins = hw.h5file.require_group("basins")
383
+ hw.write_text(basins, "relative_paths_basin", blines)
384
+
385
+ # When loading a basin, dclab should use the existing key
386
+ # from the input file.
387
+ with dclab.new_dataset(h5path_small) as ds:
388
+ assert len(ds.basins) == 1
389
+ assert ds.basins[0].key == "relative_paths_basin"
390
+
391
+ # By default, dclab should store the basin with a key made from
392
+ # its hash.
393
+ # Dataset creation
394
+ with h5py.File(h5path) as src, RTDCWriter(h5path_small_2) as hw:
395
+ # first, copy all the scalar features to the new file
396
+ rtdc_dataset.rtdc_copy(src_h5file=src,
397
+ dst_h5file=hw.h5file,
398
+ features="scalar")
399
+ # Next, store the basin information in the new dataset with dclab
400
+ hw.store_basin(
401
+ basin_name="relative_paths_basin",
402
+ basin_type="file",
403
+ basin_format="hdf5",
404
+ basin_feats=["image"],
405
+ basin_locs=[f"../{h5path.name}"],
406
+ verify=False,
407
+ )
408
+ # When loading a basin, dclab should use the existing key
409
+ # from the input file.
410
+ with dclab.new_dataset(h5path_small_2) as ds:
411
+ assert len(ds.basins) == 1
412
+ # dclab 0.62.9
413
+ assert ds.basins[0].key in [
414
+ # posix linesep
415
+ "b8763fad05e17b58407875fe9c28d90b",
416
+ # win linesep
417
+ "a495fd2d495e0d991f3a4a313ec3a3fc",
418
+ ]
419
+
420
+
359
421
  def test_basin_sorting_basic():
360
422
  bnlist = [
361
423
  {"type": "remote", "format": "dcor", "ident": 0},
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes