dclab 0.63.1__tar.gz → 0.64.0__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.
- {dclab-0.63.1 → dclab-0.64.0}/CHANGELOG +15 -0
- {dclab-0.63.1 → dclab-0.64.0}/PKG-INFO +2 -2
- {dclab-0.63.1 → dclab-0.64.0}/dclab/_version.py +2 -2
- {dclab-0.63.1 → dclab-0.64.0}/dclab/http_utils.py +1 -1
- {dclab-0.63.1 → dclab-0.64.0}/dclab/kde/base.py +143 -5
- {dclab-0.63.1 → dclab-0.64.0}/dclab/kde/methods.py +10 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/core.py +13 -4
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/export.py +8 -3
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/feat_basin.py +138 -3
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_dcor/api.py +70 -8
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_dcor/base.py +103 -4
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_dcor/logs.py +1 -1
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_dcor/tables.py +1 -1
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/writer.py +12 -4
- {dclab-0.63.1 → dclab-0.64.0}/dclab.egg-info/PKG-INFO +2 -2
- {dclab-0.63.1 → dclab-0.64.0}/dclab.egg-info/SOURCES.txt +3 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_dc_io.rst +19 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_scatter.rst +25 -25
- {dclab-0.63.1 → dclab-0.64.0}/pyproject.toml +1 -1
- dclab-0.64.0/tests/test_kde.py +101 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_copier.py +16 -4
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_export_hdf5.py +23 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_feat_basin.py +3 -2
- dclab-0.64.0/tests/test_rtdc_feat_basin_perishable.py +236 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_dcor.py +84 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_dcor_basin.py +12 -0
- dclab-0.64.0/tests/test_rtdc_fmt_dcor_private.py +77 -0
- {dclab-0.63.1 → dclab-0.64.0}/.gitignore +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/.readthedocs.yml +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/LICENSE +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/MANIFEST.in +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/README.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/cached.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/cli/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/cli/common.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/cli/task_compress.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/cli/task_condense.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/cli/task_join.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/cli/task_repack.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/cli/task_split.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/cli/task_tdms2rtdc.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/cli/task_verify_dataset.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/definitions/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/definitions/feat_const.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/definitions/feat_logic.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/definitions/meta_const.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/definitions/meta_logic.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/definitions/meta_parse.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/downsampling.pyx +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/packaging/LICENSE +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/packaging/LICENSE.APACHE +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/packaging/LICENSE.BSD +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/packaging/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/packaging/_structures.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/packaging/version.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/skimage/LICENSE +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/skimage/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/skimage/_find_contours.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/skimage/_find_contours_cy.pyx +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/skimage/_pnpoly.pyx +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/skimage/_shared/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/skimage/_shared/geometry.pxd +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/skimage/_shared/geometry.pyx +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/skimage/measure.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/skimage/pnpoly.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/statsmodels/LICENSE +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/statsmodels/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/statsmodels/nonparametric/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/statsmodels/nonparametric/_kernel_base.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/statsmodels/nonparametric/kernel_density.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/external/statsmodels/nonparametric/kernels.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/bright.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/bright_bc.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/bright_perc.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/contour.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/emodulus/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/emodulus/load.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/emodulus/lut_HE-2D-FEM-22.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/emodulus/lut_HE-3D-FEM-22.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/emodulus/lut_LE-2D-FEM-19.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/emodulus/pxcorr.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/emodulus/scale_linear.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/emodulus/viscosity.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/fl_crosstalk.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/inert_ratio.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/features/volume.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/isoelastics/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/isoelastics/iso_HE-2D-FEM-22-area_um-deform.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/isoelastics/iso_HE-2D-FEM-22-volume-deform.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/isoelastics/iso_HE-3D-FEM-22-area_um-deform.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/isoelastics/iso_HE-3D-FEM-22-volume-deform.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/isoelastics/iso_LE-2D-FEM-19-area_um-deform.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/isoelastics/iso_LE-2D-FEM-19-volume-deform.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/isoelastics/iso_LE-2D-ana-18-area_um-deform.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/kde/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/kde/contours.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/kde_contours.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/kde_methods.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/lme4/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/lme4/lme4_template.R +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/lme4/rsetup.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/lme4/wrapr.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/polygon_filter.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/check.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/config.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/copier.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/feat_anc_core/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/feat_anc_core/af_basic.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/feat_anc_core/af_emodulus.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/feat_anc_core/af_fl_max_ctc.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/feat_anc_core/af_image_contour.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/feat_anc_core/af_ml_class.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/feat_anc_core/ancillary_feature.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/feat_anc_ml/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/feat_anc_plugin/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/feat_anc_plugin/plugin_feature.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/feat_temp.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/filter.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_dcor/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_dcor/access_token.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_dcor/basin.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_dict.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_hdf5/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_hdf5/base.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_hdf5/basin.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_hdf5/events.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_hdf5/feat_defect.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_hdf5/logs.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_hdf5/tables.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_hierarchy/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_hierarchy/base.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_hierarchy/events.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_hierarchy/hfilter.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_hierarchy/mapper.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_http.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_s3.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_tdms/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_tdms/event_contour.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_tdms/event_image.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_tdms/event_mask.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_tdms/event_trace.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_tdms/exc.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/fmt_tdms/naming.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/load.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/rtdc_dataset/meta_table.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/statistics.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/util.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab/warn.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab.egg-info/dependency_links.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab.egg-info/entry_points.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab.egg-info/requires.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/dclab.egg-info/top_level.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/.gitignore +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/README.md +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/conf.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/data/example.poly +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/data/example.rtdc +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/data/example_plugin.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/data/example_plugin_metadata.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/data/example_traces.rtdc +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/data/example_video.rtdc +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/dclab.bib +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/extensions/dclab_defs.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/extensions/fancy_include.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/extensions/github_changelog.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/extensions/simple_argparse.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/figures/DCOR_API_Token_website.png +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/index.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/logo/dc_logo.png +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/logo/dc_logo.svg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/logo/dclab.png +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/logo/dclab.svg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/logo/dclab_large_white.png +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/logo/dclab_large_white.svg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/logo/favicon.ico +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/logo/favicon.svg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/requirements.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_advanced_usage.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_basins/basin_example_workflows.svg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_basins/index.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_dc_usage.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_dcor.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_emodulus/figures_emodulus/.gitignore +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_emodulus/figures_emodulus/emodulus_20um_HE-2D-FEM-22.png +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_emodulus/figures_emodulus/emodulus_20um_HE-3D-FEM-22.png +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_emodulus/figures_emodulus/emodulus_20um_LE-2D-FEM-19.png +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_emodulus/figures_emodulus/plot_emodulus_lut.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_emodulus/figures_emodulus/requirements.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_emodulus/figures_viscosity/LICENSE +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_emodulus/figures_viscosity/buyukurganci_22_fig3a.jpg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_emodulus/figures_viscosity/buyukurganci_22_fig3a.pdf +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_emodulus/index.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_feat_plugin.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_feat_temp.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_fluorescence.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_lme4.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_notation.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_av_s3.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_changelog.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_cli.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_code_reference.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_examples.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_getting_started.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/docs/sec_z_bib.rst +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/emodulus_dcor.jpg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/emodulus_dcor.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/generate_example_images.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/isoelastics.jpg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/isoelastics.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/isoelastics_custom.jpg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/isoelastics_custom.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/lme4_glmer_diff.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/lme4_lmer.jpg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/lme4_lmer.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/overview_plot.jpg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/overview_plot.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/plugin_example.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/plugin_usage.jpg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/plugin_usage.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/viscosity_models.jpg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/examples/viscosity_models.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/.gitignore +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/README.md +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/fem2iso_volume.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/fem2lutiso_std.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/fem2rtdc.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/lut_recipes/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/lut_recipes/hooks/LUT_analytical_linear-elastic_2Daxis.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/lut_recipes/hooks/README.md +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/lut_recipes/hooks/__init__.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/lut_recipes/hooks/common.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/lut_recipes/hooks/he_2d_fem_22.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/lut_recipes/hooks/he_3d_fem_22.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/lut_recipes/hooks/le_2d_fem_19.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/lut_recipes/lut_processor.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/pixelation_correction.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/pixelation_correction_2020.png +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/pixelation_correction_2022.png +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/scripts/requirements.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/setup.cfg +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/setup.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/README.md +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/conftest.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/README.md +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/example_access_token.dcor-access +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/example_isoelastics.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/feat_anc_plugin_creative.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-hdf5_fl-no-contour_2019.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-hdf5_fl_2017.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-hdf5_fl_2018.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-hdf5_fl_wide-channel_2023.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-hdf5_image-bg_2020.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-hdf5_image-mask-blood_2021.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-hdf5_mask-contour_2018.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-hdf5_polygon_gate_2021.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-hdf5_raw-cytoshot-exported.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-hdf5_segfault-compound_2023.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-hdf5_wide-channel_2023.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-tdms_2fl-no-image_2017.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-tdms_fl-image-bright_2017.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-tdms_fl-image-large-fov_2017.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-tdms_fl-image_2016.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-tdms_fl_2015.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-tdms_minimal_2016.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/data/fmt-tdms_shapein-2.0.1-no-image_2017.zip +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/helper_methods.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/requirements.txt +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_cache.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_cli.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_cli_argparse.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_cli_compress.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_cli_condense.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_cli_join.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_cli_repack.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_cli_split.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_config_value_mapping.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_dfn.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_downsampling.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_feat_bright.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_feat_bright_bc.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_feat_bright_perc.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_feat_contour.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_feat_emodulus.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_feat_emodulus_viscosity.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_feat_fl_crosstalk.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_feat_inert_ratio.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_feat_volume.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_http_utils.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_isoelastics.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_kde_contours.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_kde_deprecations.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_kde_methods.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_lme4.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_lut_he_2d_fem_22.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_lut_he_3d_fem_22.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_polygon_contains.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_polygon_filter.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_check_dataset.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_config.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_core_feat.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_downsampling.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_export.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_export_avi.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_export_fcs.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_export_tsv.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_feat_anc_core.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_feat_anc_ml.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_feat_anc_plugin.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_feat_basin_mapped.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_feat_temp.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_filter.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_dcor_access_token.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_dict.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_hdf5.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_hdf5_basins.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_hdf5_basins_internal.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_hierarchy.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_http.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_http_basin.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_s3.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_s3_basin.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_fmt_tdms.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_hash.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_kde.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_limit_events.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_rtdc_writer.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_statistics.py +0 -0
- {dclab-0.63.1 → dclab-0.64.0}/tests/test_util.py +0 -0
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
0.64.0
|
|
2
|
+
- feat: introduce concept of perishable (e.g. temporally expiring) basins
|
|
3
|
+
- feat: add `PerishableRecord` to presigned URLs for DCOR basins (#244)
|
|
4
|
+
- fix: do not export perishable basins (#254)
|
|
5
|
+
- fix: allow `Basin.verify_basin` to fail
|
|
6
|
+
- fix: `Basin.__repr__` failed when location did not exist
|
|
7
|
+
- fix: fetching tables information from DCOR dataset could time out
|
|
8
|
+
- fix: default to compression level 5 when exporting or writing (#272)
|
|
9
|
+
- enh: increase timeout every time fetching data from DCOR API times out
|
|
10
|
+
- docs: update docs `RTDCWriter` I/O
|
|
11
|
+
- setup: drop support for Python 3.8
|
|
12
|
+
- tests: add tests for fetching tables from a DCOR dataset (#229)
|
|
13
|
+
- ref: add `get_contour_lines` method to `KernelDensityEstimator` class
|
|
14
|
+
- ref: deprecate get_contour and use bin_width_doane_div5 in kde submodule
|
|
15
|
+
- ref: cache "basins" in `RTDC_DCOR` instead of in `RTDC_DCOR.api`
|
|
1
16
|
0.63.1
|
|
2
17
|
- docs: update documentation and code references for kde submodule
|
|
3
18
|
- enh: cache S3 sessions and clients (test suite duration reduced by 30%)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dclab
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.64.0
|
|
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>
|
|
@@ -14,7 +14,7 @@ Classifier: Operating System :: OS Independent
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3
|
|
15
15
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
16
16
|
Classifier: Intended Audience :: Science/Research
|
|
17
|
-
Requires-Python: <4,>=3.
|
|
17
|
+
Requires-Python: <4,>=3.9
|
|
18
18
|
Description-Content-Type: text/x-rst
|
|
19
19
|
License-File: LICENSE
|
|
20
20
|
Requires-Dist: h5py<4,>=3.0.0
|
|
@@ -2,7 +2,12 @@ import warnings
|
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
|
|
5
|
-
from .methods import
|
|
5
|
+
from .methods import bin_width_doane_div5, get_bad_vals, methods
|
|
6
|
+
from .contours import find_contours_level, get_quantile_levels
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ContourSpacingTooLarge(UserWarning):
|
|
10
|
+
pass
|
|
6
11
|
|
|
7
12
|
|
|
8
13
|
class KernelDensityEstimator:
|
|
@@ -107,6 +112,139 @@ class KernelDensityEstimator:
|
|
|
107
112
|
yscale: str
|
|
108
113
|
See `xscale`.
|
|
109
114
|
|
|
115
|
+
Returns
|
|
116
|
+
-------
|
|
117
|
+
X, Y, Z : coordinates
|
|
118
|
+
The kernel density Z evaluated on a rectangular grid (X,Y).
|
|
119
|
+
"""
|
|
120
|
+
warnings.warn("`get_contour` is deprecated; please use "
|
|
121
|
+
"`get_raster` instead", DeprecationWarning)
|
|
122
|
+
return self.get_raster(
|
|
123
|
+
xax=xax, yax=yax, xacc=xacc, yacc=yacc,
|
|
124
|
+
kde_type=kde_type, kde_kwargs=kde_kwargs,
|
|
125
|
+
xscale=xscale, yscale=yscale
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
def get_contour_lines(self, quantiles=None, xax="area_um", yax="deform",
|
|
129
|
+
xacc=None, yacc=None, kde_type="histogram",
|
|
130
|
+
kde_kwargs=None, xscale="linear", yscale="linear",
|
|
131
|
+
ret_levels=False):
|
|
132
|
+
"""Compute contour lines for a given kernel kensity estimate.
|
|
133
|
+
|
|
134
|
+
Parameters
|
|
135
|
+
----------
|
|
136
|
+
quantiles: list or array of floats
|
|
137
|
+
KDE Quantiles for which contour levels are computed. The
|
|
138
|
+
values must be between 0 and 1. If set to None, use
|
|
139
|
+
[0.5, 0.95] as default.
|
|
140
|
+
xax: str
|
|
141
|
+
Identifier for X axis (e.g. "area_um", "aspect", "deform")
|
|
142
|
+
yax: str
|
|
143
|
+
Identifier for Y axis
|
|
144
|
+
xacc: float
|
|
145
|
+
Contour accuracy in x direction
|
|
146
|
+
if set to None, will use :func:`bin_width_doane_div5`
|
|
147
|
+
yacc: float
|
|
148
|
+
Contour accuracy in y direction
|
|
149
|
+
if set to None, will use :func:`bin_width_doane_div5`
|
|
150
|
+
kde_type: str
|
|
151
|
+
The KDE method to use
|
|
152
|
+
kde_kwargs: dict
|
|
153
|
+
Additional keyword arguments to the KDE method
|
|
154
|
+
xscale: str
|
|
155
|
+
If set to "log", take the logarithm of the x-values before
|
|
156
|
+
computing the KDE. This is useful when data are
|
|
157
|
+
displayed on a log-scale. Defaults to "linear".
|
|
158
|
+
yscale: str
|
|
159
|
+
See `xscale`
|
|
160
|
+
ret_levels: bool
|
|
161
|
+
If set to True, return the levels of the contours
|
|
162
|
+
(default: False)
|
|
163
|
+
|
|
164
|
+
Returns
|
|
165
|
+
-------
|
|
166
|
+
contour_lines: list of lists (of lists)
|
|
167
|
+
For every number in `quantiles`, this list contains a list of
|
|
168
|
+
corresponding contour lines. Each contour line is a 2D
|
|
169
|
+
array of shape (N, 2), where N is the number of points in the
|
|
170
|
+
contour line.
|
|
171
|
+
levels: list of floats
|
|
172
|
+
The density levels corresponding to each number in `quantiles`.
|
|
173
|
+
Only returned if `ret_levels` is set to True.
|
|
174
|
+
"""
|
|
175
|
+
if not quantiles:
|
|
176
|
+
quantiles = [0.5, 0.95]
|
|
177
|
+
try:
|
|
178
|
+
x, y, density = self.get_raster(
|
|
179
|
+
xax=xax,
|
|
180
|
+
yax=yax,
|
|
181
|
+
xacc=xacc,
|
|
182
|
+
yacc=yacc,
|
|
183
|
+
xscale=xscale,
|
|
184
|
+
yscale=yscale,
|
|
185
|
+
kde_type=kde_type,
|
|
186
|
+
kde_kwargs=kde_kwargs,
|
|
187
|
+
)
|
|
188
|
+
except ValueError:
|
|
189
|
+
# most-likely there is nothing to compute a contour for
|
|
190
|
+
return []
|
|
191
|
+
if density.shape[0] < 3 or density.shape[1] < 3:
|
|
192
|
+
warnings.warn("Contour not possible; spacing may be too large!",
|
|
193
|
+
ContourSpacingTooLarge)
|
|
194
|
+
return []
|
|
195
|
+
levels = get_quantile_levels(
|
|
196
|
+
density=density,
|
|
197
|
+
x=x,
|
|
198
|
+
y=y,
|
|
199
|
+
xp=self.rtdc_ds[xax][self.rtdc_ds.filter.all],
|
|
200
|
+
yp=self.rtdc_ds[yax][self.rtdc_ds.filter.all],
|
|
201
|
+
q=np.array(quantiles),
|
|
202
|
+
normalize=False)
|
|
203
|
+
contours = []
|
|
204
|
+
# Normalize levels to [0, 1]
|
|
205
|
+
nlevels = np.array(levels) / density.max()
|
|
206
|
+
for nlev in nlevels:
|
|
207
|
+
# make sure that the contour levels are not at the boundaries
|
|
208
|
+
if not (np.allclose(nlev, 0, atol=1e-12, rtol=0)
|
|
209
|
+
or np.allclose(nlev, 1, atol=1e-12, rtol=0)):
|
|
210
|
+
cc = find_contours_level(
|
|
211
|
+
density, x=x, y=y, level=nlev)
|
|
212
|
+
contours.append(cc)
|
|
213
|
+
else:
|
|
214
|
+
contours.append([])
|
|
215
|
+
if ret_levels:
|
|
216
|
+
return contours, levels
|
|
217
|
+
else:
|
|
218
|
+
return contours
|
|
219
|
+
|
|
220
|
+
def get_raster(self, xax="area_um", yax="deform", xacc=None, yacc=None,
|
|
221
|
+
kde_type="histogram", kde_kwargs=None, xscale="linear",
|
|
222
|
+
yscale="linear"):
|
|
223
|
+
"""Evaluate the kernel density estimate on a grid
|
|
224
|
+
|
|
225
|
+
Parameters
|
|
226
|
+
----------
|
|
227
|
+
xax: str
|
|
228
|
+
Identifier for X axis (e.g. "area_um", "aspect", "deform")
|
|
229
|
+
yax: str
|
|
230
|
+
Identifier for Y axis
|
|
231
|
+
xacc: float
|
|
232
|
+
Contour accuracy in x direction
|
|
233
|
+
if set to None, will use :func:`bin_width_doane_div5`
|
|
234
|
+
yacc: float
|
|
235
|
+
Contour accuracy in y direction
|
|
236
|
+
if set to None, will use :func:`bin_width_doane_div5`
|
|
237
|
+
kde_type: str
|
|
238
|
+
The KDE method to use
|
|
239
|
+
kde_kwargs: dict
|
|
240
|
+
Additional keyword arguments to the KDE method
|
|
241
|
+
xscale: str
|
|
242
|
+
If set to "log", take the logarithm of the x-values before
|
|
243
|
+
computing the KDE. This is useful when data are
|
|
244
|
+
displayed on a log-scale. Defaults to "linear".
|
|
245
|
+
yscale: str
|
|
246
|
+
See `xscale`.
|
|
247
|
+
|
|
110
248
|
Returns
|
|
111
249
|
-------
|
|
112
250
|
X, Y, Z : coordinates
|
|
@@ -128,21 +266,21 @@ class KernelDensityEstimator:
|
|
|
128
266
|
a=x,
|
|
129
267
|
feat=xax,
|
|
130
268
|
scale=xscale,
|
|
131
|
-
method=
|
|
269
|
+
method=bin_width_doane_div5,
|
|
132
270
|
ret_scaled=True)
|
|
133
271
|
|
|
134
272
|
yacc_sc, ys = self.get_spacing(
|
|
135
273
|
a=y,
|
|
136
274
|
feat=yax,
|
|
137
275
|
scale=yscale,
|
|
138
|
-
method=
|
|
276
|
+
method=bin_width_doane_div5,
|
|
139
277
|
ret_scaled=True)
|
|
140
278
|
|
|
141
279
|
if xacc is None or xacc == 0:
|
|
142
|
-
xacc = xacc_sc
|
|
280
|
+
xacc = xacc_sc
|
|
143
281
|
|
|
144
282
|
if yacc is None or yacc == 0:
|
|
145
|
-
yacc = yacc_sc
|
|
283
|
+
yacc = yacc_sc
|
|
146
284
|
|
|
147
285
|
# Ignore infs and nans
|
|
148
286
|
bad = get_bad_vals(xs, ys)
|
|
@@ -56,6 +56,16 @@ def bin_width_doane(a):
|
|
|
56
56
|
return acc
|
|
57
57
|
|
|
58
58
|
|
|
59
|
+
def bin_width_doane_div5(a):
|
|
60
|
+
"""Compute contour spacing based on Doane's formula divided by five
|
|
61
|
+
|
|
62
|
+
See Also
|
|
63
|
+
--------
|
|
64
|
+
bin_width_doane: method used to compute the bin width
|
|
65
|
+
"""
|
|
66
|
+
return bin_width_doane(a) / 5
|
|
67
|
+
|
|
68
|
+
|
|
59
69
|
def bin_width_percentile(a):
|
|
60
70
|
"""Compute contour spacing based on data percentiles
|
|
61
71
|
|
|
@@ -635,7 +635,7 @@ class RTDCBase(abc.ABC):
|
|
|
635
635
|
The kernel density Z evaluated on a rectangular grid (X,Y).
|
|
636
636
|
"""
|
|
637
637
|
kde_instance = KernelDensityEstimator(rtdc_ds=self)
|
|
638
|
-
xmesh, ymesh, density = kde_instance.
|
|
638
|
+
xmesh, ymesh, density = kde_instance.get_raster(
|
|
639
639
|
xax=xax, yax=yax, xacc=xacc, yacc=yacc, kde_type=kde_type,
|
|
640
640
|
kde_kwargs=kde_kwargs, xscale=xscale, yscale=yscale
|
|
641
641
|
)
|
|
@@ -746,6 +746,8 @@ class RTDCBase(abc.ABC):
|
|
|
746
746
|
"ignored_basins": bd_keys,
|
|
747
747
|
# basin key
|
|
748
748
|
"key": bdict["key"],
|
|
749
|
+
# whether the basin is perishable or not
|
|
750
|
+
"perishable": bdict.get("perishable", False),
|
|
749
751
|
}
|
|
750
752
|
|
|
751
753
|
# Check whether this basin is supported and exists
|
|
@@ -783,12 +785,19 @@ class RTDCBase(abc.ABC):
|
|
|
783
785
|
b_cls = bc[bdict["format"]]
|
|
784
786
|
# Try absolute path
|
|
785
787
|
bna = b_cls(pp, **kwargs)
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
788
|
+
|
|
789
|
+
try:
|
|
790
|
+
absolute_exists = bna.verify_basin()
|
|
791
|
+
except BaseException:
|
|
792
|
+
pass
|
|
793
|
+
else:
|
|
794
|
+
if absolute_exists:
|
|
795
|
+
basins.append(bna)
|
|
796
|
+
break
|
|
789
797
|
# Try relative path
|
|
790
798
|
this_path = pathlib.Path(self.path)
|
|
791
799
|
if this_path.exists():
|
|
800
|
+
|
|
792
801
|
# Insert relative path
|
|
793
802
|
bnr = b_cls(this_path.parent / pp, **kwargs)
|
|
794
803
|
if bnr.verify_basin():
|
|
@@ -268,8 +268,8 @@ class Export(object):
|
|
|
268
268
|
compression_kwargs: dict
|
|
269
269
|
Dictionary with the keys "compression" and "compression_opts"
|
|
270
270
|
which are passed to :func:`h5py.H5File.create_dataset`. The
|
|
271
|
-
default is Zstandard compression with the
|
|
272
|
-
level `hdf5plugin.Zstd(clevel=
|
|
271
|
+
default is Zstandard compression with the compression
|
|
272
|
+
level 5 `hdf5plugin.Zstd(clevel=5)`.
|
|
273
273
|
compression: str or None
|
|
274
274
|
Compression method used for data storage;
|
|
275
275
|
one of [None, "lzf", "gzip", "szip"].
|
|
@@ -300,7 +300,7 @@ class Export(object):
|
|
|
300
300
|
# be backwards-compatible
|
|
301
301
|
compression_kwargs = {"compression": compression}
|
|
302
302
|
if compression_kwargs is None:
|
|
303
|
-
compression_kwargs = hdf5plugin.Zstd(clevel=
|
|
303
|
+
compression_kwargs = hdf5plugin.Zstd(clevel=5)
|
|
304
304
|
path = pathlib.Path(path)
|
|
305
305
|
# Make sure that path ends with .rtdc
|
|
306
306
|
if path.suffix not in [".rtdc", ".rtdc~"]:
|
|
@@ -505,6 +505,11 @@ class Export(object):
|
|
|
505
505
|
# defined in. Since we are exporting, it does not
|
|
506
506
|
# make sense to store these basins in the output file.
|
|
507
507
|
continue
|
|
508
|
+
elif bn_dict.get("perishable"):
|
|
509
|
+
# Perishable basins require secret keys or complicated
|
|
510
|
+
# logic to execute in order to refresh them. We do not
|
|
511
|
+
# store them in the output file.
|
|
512
|
+
continue
|
|
508
513
|
basinmap_orig = bn_dict.get("basin_map")
|
|
509
514
|
if not filtered:
|
|
510
515
|
# filtering disabled: just copy basins
|
|
@@ -6,9 +6,10 @@ which, when opened in dclab, can access features stored in the input file
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
import abc
|
|
9
|
+
import logging
|
|
9
10
|
import numbers
|
|
10
11
|
import threading
|
|
11
|
-
from typing import Dict, List, Literal
|
|
12
|
+
from typing import Callable, Dict, List, Literal, Union
|
|
12
13
|
import uuid
|
|
13
14
|
import warnings
|
|
14
15
|
import weakref
|
|
@@ -18,6 +19,9 @@ import numpy as np
|
|
|
18
19
|
from ..util import copy_if_needed
|
|
19
20
|
|
|
20
21
|
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
21
25
|
class BasinFeatureMissingWarning(UserWarning):
|
|
22
26
|
"""Used when a badin feature is defined but not stored"""
|
|
23
27
|
|
|
@@ -26,6 +30,10 @@ class CyclicBasinDependencyFoundWarning(UserWarning):
|
|
|
26
30
|
"""Used when a basin is defined in one of its sub-basins"""
|
|
27
31
|
|
|
28
32
|
|
|
33
|
+
class IgnoringPerishableBasinTTL(UserWarning):
|
|
34
|
+
"""Used when refreshing a basin does not support TTL"""
|
|
35
|
+
|
|
36
|
+
|
|
29
37
|
class BasinmapFeatureMissingError(KeyError):
|
|
30
38
|
"""Used when one of the `basinmap` features is not defined"""
|
|
31
39
|
pass
|
|
@@ -47,6 +55,114 @@ class BasinAvailabilityChecker(threading.Thread):
|
|
|
47
55
|
self.basin.is_available()
|
|
48
56
|
|
|
49
57
|
|
|
58
|
+
class PerishableRecord:
|
|
59
|
+
"""A class containing information about perishable basins
|
|
60
|
+
|
|
61
|
+
Perishable basins are basins than may discontinue to work after
|
|
62
|
+
e.g. a specific amount of time (e.g. presigned S3 URLs). With the
|
|
63
|
+
`PerishableRecord`, these basins may be "refreshed" (made
|
|
64
|
+
available again).
|
|
65
|
+
"""
|
|
66
|
+
def __init__(self,
|
|
67
|
+
basin,
|
|
68
|
+
expiration_func: Callable = None,
|
|
69
|
+
expiration_kwargs: Dict = None,
|
|
70
|
+
refresh_func: Callable = None,
|
|
71
|
+
refresh_kwargs: Dict = None,
|
|
72
|
+
):
|
|
73
|
+
"""
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
basin: Basin
|
|
77
|
+
Instance of the perishable basin
|
|
78
|
+
expiration_func: callable
|
|
79
|
+
A function that determines whether the basin has perished.
|
|
80
|
+
It must accept `basin` as the first argument. Calling this
|
|
81
|
+
function should be fast, as it is called every time a feature
|
|
82
|
+
is accessed.
|
|
83
|
+
Note that if you are implementing this in the time domain, then
|
|
84
|
+
you should use `time.time()` (TSE), because you need an absolute
|
|
85
|
+
time measure. `time.monotonic()` for instance does not count up
|
|
86
|
+
when the system goes to sleep. However, keep in mind that if
|
|
87
|
+
a remote machine dictates the expiration time, then that
|
|
88
|
+
remote machine should also transmit the creation time (in case
|
|
89
|
+
there are time offsets).
|
|
90
|
+
expiration_kwargs: dict
|
|
91
|
+
Additional kwargs for `expiration_func`.
|
|
92
|
+
refresh_func: callable
|
|
93
|
+
The function used to refresh the `basin`. It must accept
|
|
94
|
+
`basin` as the first argument.
|
|
95
|
+
refresh_kwargs: dict
|
|
96
|
+
Additional kwargs for `refresh_func`
|
|
97
|
+
"""
|
|
98
|
+
if not isinstance(basin, weakref.ProxyType):
|
|
99
|
+
basin = weakref.proxy(basin)
|
|
100
|
+
self.basin = basin
|
|
101
|
+
self.expiration_func = expiration_func
|
|
102
|
+
self.expiration_kwargs = expiration_kwargs or {}
|
|
103
|
+
self.refresh_func = refresh_func
|
|
104
|
+
self.refresh_kwargs = refresh_kwargs or {}
|
|
105
|
+
|
|
106
|
+
def __repr__(self):
|
|
107
|
+
state = "perished" if self.perished() else "valid"
|
|
108
|
+
return f"<PerishableRecord ({state}) at {hex(id(self))}>"
|
|
109
|
+
|
|
110
|
+
def perished(self) -> Union[bool, None]:
|
|
111
|
+
"""Determine whether the basin has perished
|
|
112
|
+
|
|
113
|
+
Returns
|
|
114
|
+
-------
|
|
115
|
+
state: bool or None
|
|
116
|
+
True means the basin has perished, False means the basin
|
|
117
|
+
has not perished, and `None` means we don't know
|
|
118
|
+
"""
|
|
119
|
+
if self.expiration_func is None:
|
|
120
|
+
return None
|
|
121
|
+
else:
|
|
122
|
+
return self.expiration_func(self.basin, **self.expiration_kwargs)
|
|
123
|
+
|
|
124
|
+
def refresh(self, extend_by: float = None) -> None:
|
|
125
|
+
"""Extend the lifetime of the associated perishable basin
|
|
126
|
+
|
|
127
|
+
Parameters
|
|
128
|
+
----------
|
|
129
|
+
extend_by: float
|
|
130
|
+
Custom argument for extending the life of the basin.
|
|
131
|
+
Normally, this would be a lifetime.
|
|
132
|
+
|
|
133
|
+
Returns
|
|
134
|
+
-------
|
|
135
|
+
basin: dict | None
|
|
136
|
+
Dictionary for instantiating a new basin
|
|
137
|
+
"""
|
|
138
|
+
if self.refresh_func is None:
|
|
139
|
+
# The basin is a perishable basin, but we have no way of
|
|
140
|
+
# refreshing it.
|
|
141
|
+
logger.error(f"Cannot refresh basin '{self.basin}'")
|
|
142
|
+
return
|
|
143
|
+
|
|
144
|
+
if extend_by and "extend_by" not in self.refresh_kwargs:
|
|
145
|
+
warnings.warn(
|
|
146
|
+
"Parameter 'extend_by' ignored, because the basin "
|
|
147
|
+
"source does not support it",
|
|
148
|
+
IgnoringPerishableBasinTTL)
|
|
149
|
+
extend_by = None
|
|
150
|
+
|
|
151
|
+
rkw = {}
|
|
152
|
+
rkw.update(self.refresh_kwargs)
|
|
153
|
+
|
|
154
|
+
if extend_by is not None:
|
|
155
|
+
rkw["extend_by"] = extend_by
|
|
156
|
+
|
|
157
|
+
self.refresh_func(self.basin, **rkw)
|
|
158
|
+
logger.info(f"Refreshed basin '{self.basin}'")
|
|
159
|
+
|
|
160
|
+
# If everything went well, reset the current dataset of the basin
|
|
161
|
+
if self.basin._ds is not None:
|
|
162
|
+
self.basin._ds.close()
|
|
163
|
+
self.basin._ds = None
|
|
164
|
+
|
|
165
|
+
|
|
50
166
|
class Basin(abc.ABC):
|
|
51
167
|
"""A basin represents data from an external source
|
|
52
168
|
|
|
@@ -76,6 +192,7 @@ class Basin(abc.ABC):
|
|
|
76
192
|
mapping_referrer: Dict = None,
|
|
77
193
|
ignored_basins: List[str] = None,
|
|
78
194
|
key: str = None,
|
|
195
|
+
perishable=False,
|
|
79
196
|
**kwargs):
|
|
80
197
|
"""
|
|
81
198
|
|
|
@@ -115,6 +232,10 @@ class Basin(abc.ABC):
|
|
|
115
232
|
Unique key to identify this basin; normally computed from
|
|
116
233
|
a JSON dump of the basin definition. A random string is used
|
|
117
234
|
if None is specified.
|
|
235
|
+
perishable: bool or PerishableRecord
|
|
236
|
+
If this is not False, then it must be a :class:`.PerishableRecord`
|
|
237
|
+
that holds the information about the expiration time, and that
|
|
238
|
+
comes with a method `refresh` to extend the lifetime of the basin.
|
|
118
239
|
kwargs:
|
|
119
240
|
Additional keyword arguments passed to the `load_dataset`
|
|
120
241
|
method of the `Basin` subclass.
|
|
@@ -130,7 +251,12 @@ class Basin(abc.ABC):
|
|
|
130
251
|
self.name = name
|
|
131
252
|
#: lengthy description of the basin
|
|
132
253
|
self.description = description
|
|
133
|
-
#
|
|
254
|
+
# perishable record
|
|
255
|
+
if isinstance(perishable, bool) and perishable:
|
|
256
|
+
# Create an empty perishable record
|
|
257
|
+
perishable = PerishableRecord(self)
|
|
258
|
+
self.perishable = perishable
|
|
259
|
+
# define key of the basin
|
|
134
260
|
self.key = key or str(uuid.uuid4())
|
|
135
261
|
# features this basin provides
|
|
136
262
|
self._features = features
|
|
@@ -164,10 +290,14 @@ class Basin(abc.ABC):
|
|
|
164
290
|
self._av_check.start()
|
|
165
291
|
|
|
166
292
|
def __repr__(self):
|
|
293
|
+
try:
|
|
294
|
+
feature_info = len(self.features)
|
|
295
|
+
except BaseException:
|
|
296
|
+
feature_info = "unknown"
|
|
167
297
|
options = [
|
|
168
298
|
self.name,
|
|
169
299
|
f"mapped {self.mapping}" if self.mapping != "same" else "",
|
|
170
|
-
f"
|
|
300
|
+
f"{feature_info} features",
|
|
171
301
|
f"location {self.location}",
|
|
172
302
|
]
|
|
173
303
|
opt_str = ", ".join([o for o in options if o])
|
|
@@ -220,6 +350,10 @@ class Basin(abc.ABC):
|
|
|
220
350
|
@property
|
|
221
351
|
def ds(self):
|
|
222
352
|
"""The :class:`.RTDCBase` instance represented by the basin"""
|
|
353
|
+
if self.perishable and self.perishable.perished():
|
|
354
|
+
# We have perished. Ask the PerishableRecord to refresh this
|
|
355
|
+
# basin so we can access it again.
|
|
356
|
+
self.perishable.refresh()
|
|
223
357
|
if self._ds is None:
|
|
224
358
|
if not self.is_available():
|
|
225
359
|
raise BasinNotAvailableError(f"Basin {self} is not available!")
|
|
@@ -265,6 +399,7 @@ class Basin(abc.ABC):
|
|
|
265
399
|
"basin_descr": self.description,
|
|
266
400
|
"basin_feats": self.features,
|
|
267
401
|
"basin_map": self.basinmap,
|
|
402
|
+
"perishable": bool(self.perishable),
|
|
268
403
|
}
|
|
269
404
|
|
|
270
405
|
def close(self):
|
|
@@ -11,8 +11,10 @@ class DCORAccessError(BaseException):
|
|
|
11
11
|
|
|
12
12
|
class APIHandler:
|
|
13
13
|
"""Handles the DCOR api with caching for simple queries"""
|
|
14
|
-
#:
|
|
15
|
-
|
|
14
|
+
#: These are cached to minimize network usage
|
|
15
|
+
#: Note that we are not caching basins, since they may contain
|
|
16
|
+
#: expiring URLs.
|
|
17
|
+
cache_queries = ["metadata", "size", "feature_list", "valid"]
|
|
16
18
|
#: DCOR API Keys/Tokens in the current session
|
|
17
19
|
api_keys = []
|
|
18
20
|
|
|
@@ -52,8 +54,36 @@ class APIHandler:
|
|
|
52
54
|
if api_key.strip() and api_key not in APIHandler.api_keys:
|
|
53
55
|
APIHandler.api_keys.append(api_key)
|
|
54
56
|
|
|
55
|
-
def _get(self,
|
|
56
|
-
|
|
57
|
+
def _get(self,
|
|
58
|
+
query: str,
|
|
59
|
+
feat: str = None,
|
|
60
|
+
trace: str = None,
|
|
61
|
+
event: str = None,
|
|
62
|
+
api_key: str = "",
|
|
63
|
+
timeout: float = None,
|
|
64
|
+
retries: int = 5):
|
|
65
|
+
"""Fetch information via the DCOR API
|
|
66
|
+
|
|
67
|
+
Parameters
|
|
68
|
+
----------
|
|
69
|
+
query: str
|
|
70
|
+
API route
|
|
71
|
+
feat: str
|
|
72
|
+
DEPRECATED (use basins instead), adds f"&feature={feat}" to query
|
|
73
|
+
trace: str
|
|
74
|
+
DEPRECATED (use basins instead), adds f"&trace={trace}" to query
|
|
75
|
+
event: str
|
|
76
|
+
DEPRECATED (use basins instead), adds f"&event={event}" to query
|
|
77
|
+
api_key: str
|
|
78
|
+
DCOR API token to use
|
|
79
|
+
timeout: float
|
|
80
|
+
Request timeout
|
|
81
|
+
retries: int
|
|
82
|
+
Number of retries to fetch the request. For every retry, the
|
|
83
|
+
timeout is increased by two seconds.
|
|
84
|
+
"""
|
|
85
|
+
if timeout is None:
|
|
86
|
+
timeout = 1
|
|
57
87
|
# "version=2" introduced in dclab 0.54.3
|
|
58
88
|
# (supported since ckanext.dc_serve 0.13.2)
|
|
59
89
|
qstr = f"&version={self.dcserv_api_version}&query={query}"
|
|
@@ -65,13 +95,13 @@ class APIHandler:
|
|
|
65
95
|
qstr += f"&event={event}"
|
|
66
96
|
apicall = self.url + qstr
|
|
67
97
|
fail_reasons = []
|
|
68
|
-
for
|
|
98
|
+
for ii in range(retries):
|
|
69
99
|
try:
|
|
70
100
|
# try-except both requests and json conversion
|
|
71
101
|
req = self.session.get(apicall,
|
|
72
102
|
headers={"Authorization": api_key},
|
|
73
103
|
verify=self.verify,
|
|
74
|
-
timeout=
|
|
104
|
+
timeout=timeout + ii * 2,
|
|
75
105
|
)
|
|
76
106
|
jreq = req.json()
|
|
77
107
|
except requests.urllib3.exceptions.ConnectionError: # requests
|
|
@@ -92,13 +122,45 @@ class APIHandler:
|
|
|
92
122
|
f"Messages: {fail_reasons}")
|
|
93
123
|
return jreq
|
|
94
124
|
|
|
95
|
-
def get(self,
|
|
125
|
+
def get(self,
|
|
126
|
+
query: str,
|
|
127
|
+
feat: str = None,
|
|
128
|
+
trace: str = None,
|
|
129
|
+
event: str = None,
|
|
130
|
+
timeout: float = None,
|
|
131
|
+
retries: int = 5,
|
|
132
|
+
):
|
|
133
|
+
"""Fetch information from DCOR
|
|
134
|
+
|
|
135
|
+
Parameters
|
|
136
|
+
----------
|
|
137
|
+
query: str
|
|
138
|
+
API route
|
|
139
|
+
feat: str
|
|
140
|
+
DEPRECATED (use basins instead), adds f"&feature={feat}" to query
|
|
141
|
+
trace: str
|
|
142
|
+
DEPRECATED (use basins instead), adds f"&trace={trace}" to query
|
|
143
|
+
event: str
|
|
144
|
+
DEPRECATED (use basins instead), adds f"&event={event}" to query
|
|
145
|
+
timeout: float
|
|
146
|
+
Request timeout
|
|
147
|
+
retries: int
|
|
148
|
+
Number of retries to fetch the request. For every retry, the
|
|
149
|
+
timeout is increased by two seconds.
|
|
150
|
+
"""
|
|
96
151
|
if query in APIHandler.cache_queries and query in self._cache:
|
|
97
152
|
result = self._cache[query]
|
|
98
153
|
else:
|
|
99
154
|
req = {"error": {"message": "No access to API (api key?)"}}
|
|
100
155
|
for api_key in [self.api_key] + APIHandler.api_keys:
|
|
101
|
-
req = self._get(query,
|
|
156
|
+
req = self._get(query=query,
|
|
157
|
+
feat=feat,
|
|
158
|
+
trace=trace,
|
|
159
|
+
event=event,
|
|
160
|
+
api_key=api_key,
|
|
161
|
+
timeout=timeout,
|
|
162
|
+
retries=retries,
|
|
163
|
+
)
|
|
102
164
|
if req["success"]:
|
|
103
165
|
self.api_key = api_key # remember working key
|
|
104
166
|
break
|