celldetective 1.5.0b3__tar.gz → 1.5.0b5__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.
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/PKG-INFO +1 -1
- celldetective-1.5.0b5/celldetective/_version.py +1 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/base/figure_canvas.py +17 -3
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/measure_annotator.py +3 -3
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/_settings_segmentation_model_training.py +6 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/viewers/base_viewer.py +72 -19
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/viewers/channel_offset_viewer.py +119 -5
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/viewers/threshold_viewer.py +14 -6
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/cellpose_utils/__init__.py +23 -7
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective.egg-info/PKG-INFO +1 -1
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective.egg-info/SOURCES.txt +2 -0
- celldetective-1.5.0b5/tests/gui/test_measure_annotator_bugfix.py +130 -0
- celldetective-1.5.0b5/tests/test_cellpose_fallback.py +101 -0
- celldetective-1.5.0b3/celldetective/_version.py +0 -1
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/LICENSE +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/README.md +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/__main__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/datasets/segmentation_annotations/blank +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/datasets/signal_annotations/blank +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/events.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/exceptions.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/extra_properties.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/filters.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/InitWindow.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/about.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/analyze_block.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/base/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/base/channel_norm_generator.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/base/components.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/base/feature_choice.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/base/list_widget.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/base/styles.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/base/utils.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/base_annotator.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/classifier_widget.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/configure_new_exp.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/control_panel.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/dynamic_progress.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/event_annotator.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/generic_signal_plot.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/gui_utils.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/help/DL-segmentation-strategy.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/help/Threshold-vs-DL.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/help/cell-populations.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/help/exp-structure.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/help/feature-btrack.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/help/neighborhood.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/help/prefilter-for-segmentation.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/help/preprocessing.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/help/propagate-classification.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/help/track-postprocessing.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/help/tracking.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/interactions_block.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/interactive_timeseries_viewer.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/json_readers.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/layouts/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/layouts/background_model_free_layout.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/layouts/channel_offset_layout.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/layouts/local_correction_layout.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/layouts/model_fit_layout.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/layouts/operation_layout.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/layouts/protocol_designer_layout.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/pair_event_annotator.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/plot_measurements.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/plot_signals_ui.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/preprocessing_block.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/process_block.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/seg_model_loader.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/_cellpose_model_params.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/_event_detection_model_params.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/_segmentation_model_params.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/_settings_base.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/_settings_event_model_training.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/_settings_measurements.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/_settings_neighborhood.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/_settings_segmentation.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/_settings_signal_annotator.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/_settings_tracking.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/settings/_stardist_model_params.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/survival_ui.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/tableUI.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/table_ops/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/table_ops/_maths.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/table_ops/_merge_groups.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/table_ops/_merge_one_hot.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/table_ops/_query_table.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/table_ops/_rename_col.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/thresholds_gui.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/viewers/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/viewers/contour_viewer.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/viewers/size_viewer.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/viewers/spot_detection_viewer.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/workers.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/icons/logo-large.png +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/icons/logo.png +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/icons/signals_icon.png +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/icons/splash-test.png +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/icons/splash.png +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/icons/splash0.png +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/icons/survival2.png +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/icons/vignette_signals2.png +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/icons/vignette_signals2.svg +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/links/zenodo.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/log_manager.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/measure.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/models/pair_signal_detection/blank +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/models/segmentation_effectors/blank +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/models/segmentation_generic/blank +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/models/segmentation_targets/blank +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/models/signal_detection/blank +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/models/tracking_configs/biased_motion.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/models/tracking_configs/mcf7.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/models/tracking_configs/no_z_motion.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/models/tracking_configs/ricm.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/models/tracking_configs/ricm2.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/napari/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/napari/utils.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/neighborhood.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/preprocessing.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/processes/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/processes/background_correction.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/processes/compute_neighborhood.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/processes/detect_events.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/processes/downloader.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/processes/load_table.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/processes/measure_cells.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/processes/segment_cells.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/processes/track_cells.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/processes/train_segmentation_model.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/processes/train_signal_model.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/processes/unified_process.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/regionprops/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/regionprops/_regionprops.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/regionprops/props.json +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/relative_measurements.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/scripts/analyze_signals.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/scripts/measure_cells.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/scripts/measure_relative.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/scripts/segment_cells.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/scripts/segment_cells_thresholds.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/scripts/track_cells.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/scripts/train_segmentation_model.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/scripts/train_signal_model.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/segmentation.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/signals.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/tracking.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/color_mappings.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/data_cleaning.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/data_loaders.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/dataset_helpers.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/downloaders.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/event_detection/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/experiment.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/image_augmenters.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/image_cleaning.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/image_loaders.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/image_transforms.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/io.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/mask_cleaning.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/mask_transforms.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/masks.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/maths.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/model_getters.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/model_loaders.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/normalization.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/parsing.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/plots/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/plots/regression.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/resources.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/stardist_utils/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/stats.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/types.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective.egg-info/dependency_links.txt +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective.egg-info/entry_points.txt +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective.egg-info/not-zip-safe +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective.egg-info/requires.txt +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective.egg-info/top_level.txt +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/setup.cfg +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/setup.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/gui/__init__.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/gui/test_enhancements.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/gui/test_new_project.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/gui/test_project.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/test_events.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/test_filters.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/test_io.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/test_measure.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/test_neighborhood.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/test_notebooks.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/test_preprocessing.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/test_segmentation.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/test_signals.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/test_tracking.py +0 -0
- {celldetective-1.5.0b3 → celldetective-1.5.0b5}/tests/test_utils.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.5.0b5"
|
|
@@ -22,19 +22,33 @@ class FigureCanvas(CelldetectiveWidget):
|
|
|
22
22
|
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT
|
|
23
23
|
|
|
24
24
|
self.toolbar = NavigationToolbar2QT(self.canvas)
|
|
25
|
+
self.toolbar.setStyleSheet(
|
|
26
|
+
"QToolButton:hover {background-color: lightgray;} QToolButton {background-color: transparent; border: none;}"
|
|
27
|
+
)
|
|
25
28
|
self.layout = QVBoxLayout(self)
|
|
26
29
|
self.layout.addWidget(self.canvas, 90)
|
|
27
30
|
if interactive:
|
|
28
31
|
self.layout.addWidget(self.toolbar)
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
self.manual_layout = False
|
|
34
|
+
# center_window(self)
|
|
31
35
|
self.setAttribute(Qt.WA_DeleteOnClose)
|
|
32
36
|
|
|
33
37
|
def resizeEvent(self, event):
|
|
34
|
-
|
|
38
|
+
print("DEBUG: resizeEvent called")
|
|
35
39
|
super().resizeEvent(event)
|
|
36
40
|
try:
|
|
37
|
-
self
|
|
41
|
+
manual_layout = getattr(self, "manual_layout", False)
|
|
42
|
+
|
|
43
|
+
# Double check for profile axes manually (robust fallback)
|
|
44
|
+
if not manual_layout and hasattr(self.fig, "axes"):
|
|
45
|
+
for ax in self.fig.axes:
|
|
46
|
+
if ax.get_label() == "profile_axes":
|
|
47
|
+
manual_layout = True
|
|
48
|
+
break
|
|
49
|
+
|
|
50
|
+
if not manual_layout:
|
|
51
|
+
self.fig.tight_layout()
|
|
38
52
|
except:
|
|
39
53
|
pass
|
|
40
54
|
|
|
@@ -950,9 +950,9 @@ class MeasureAnnotator(BaseAnnotator):
|
|
|
950
950
|
].to_numpy()
|
|
951
951
|
)
|
|
952
952
|
self.colors.append(
|
|
953
|
-
self.df_tracks.loc[
|
|
954
|
-
|
|
955
|
-
|
|
953
|
+
self.df_tracks.loc[self.df_tracks["FRAME"] == t, ["group_color"]]
|
|
954
|
+
.to_numpy()
|
|
955
|
+
.copy()
|
|
956
956
|
)
|
|
957
957
|
if "TRACK_ID" in self.df_tracks.columns:
|
|
958
958
|
self.tracks.append(
|
|
@@ -84,6 +84,12 @@ class SettingsSegmentationModelTraining(CelldetectiveSettingsPanel):
|
|
|
84
84
|
self.bg_loader = BackgroundLoader()
|
|
85
85
|
self.bg_loader.start()
|
|
86
86
|
|
|
87
|
+
def closeEvent(self, event):
|
|
88
|
+
if self.bg_loader.isRunning():
|
|
89
|
+
logger.info("Waiting for background loader to finish...")
|
|
90
|
+
self.bg_loader.wait()
|
|
91
|
+
super().closeEvent(event)
|
|
92
|
+
|
|
87
93
|
def _add_to_layout(self):
|
|
88
94
|
|
|
89
95
|
self._layout.addWidget(self.model_frame)
|
|
@@ -111,6 +111,11 @@ class StackLoader(QThread):
|
|
|
111
111
|
# If nothing to load, wait
|
|
112
112
|
self.mutex.lock()
|
|
113
113
|
self.condition.wait(self.mutex, 500) # Wait 500ms or until new priority
|
|
114
|
+
|
|
115
|
+
if not self.running:
|
|
116
|
+
self.mutex.unlock()
|
|
117
|
+
break
|
|
118
|
+
|
|
114
119
|
self.mutex.unlock()
|
|
115
120
|
|
|
116
121
|
|
|
@@ -280,6 +285,10 @@ class StackVisualizer(CelldetectiveWidget):
|
|
|
280
285
|
self.lock_y_action.setEnabled(True)
|
|
281
286
|
self.canvas.toolbar.mode = ""
|
|
282
287
|
|
|
288
|
+
# Enable manual layout control to prevent tight_layout interference
|
|
289
|
+
if hasattr(self.canvas, "manual_layout"):
|
|
290
|
+
self.canvas.manual_layout = True
|
|
291
|
+
|
|
283
292
|
# Connect events
|
|
284
293
|
self.cid_press = self.fig.canvas.mpl_connect(
|
|
285
294
|
"button_press_event", self.on_line_press
|
|
@@ -292,8 +301,8 @@ class StackVisualizer(CelldetectiveWidget):
|
|
|
292
301
|
)
|
|
293
302
|
|
|
294
303
|
# Save original position if not saved
|
|
295
|
-
if not hasattr(self, "ax_original_pos"):
|
|
296
|
-
|
|
304
|
+
# if not hasattr(self, "ax_original_pos"):
|
|
305
|
+
# self.ax_original_pos = self.ax.get_position()
|
|
297
306
|
|
|
298
307
|
# Disable tight_layout/layout engine to prevent fighting manual positioning
|
|
299
308
|
if hasattr(self.fig, "set_layout_engine"):
|
|
@@ -329,6 +338,7 @@ class StackVisualizer(CelldetectiveWidget):
|
|
|
329
338
|
self.ax_profile.set_position(gs[1].get_position(self.fig))
|
|
330
339
|
|
|
331
340
|
self.ax_profile.set_visible(True)
|
|
341
|
+
self.ax_profile.set_label("profile_axes")
|
|
332
342
|
self.ax_profile.set_facecolor("none")
|
|
333
343
|
self.ax_profile.tick_params(axis="y", which="major", labelsize=8)
|
|
334
344
|
self.ax_profile.set_xticks([])
|
|
@@ -341,11 +351,40 @@ class StackVisualizer(CelldetectiveWidget):
|
|
|
341
351
|
self.ax_profile.spines["bottom"].set_color("black")
|
|
342
352
|
self.ax_profile.spines["left"].set_color("black")
|
|
343
353
|
|
|
354
|
+
# Update Toolbar Home State to match new layout BUT with full field of view
|
|
355
|
+
# 1. Save current zoom
|
|
356
|
+
current_xlim = self.ax.get_xlim()
|
|
357
|
+
current_ylim = self.ax.get_ylim()
|
|
358
|
+
|
|
359
|
+
# 2. Set limits to full extent (Home State)
|
|
360
|
+
if hasattr(self, "im"):
|
|
361
|
+
extent = self.im.get_extent() # (left, right, bottom, top) or similar
|
|
362
|
+
self.ax.set_xlim(extent[0], extent[1])
|
|
363
|
+
self.ax.set_ylim(extent[2], extent[3])
|
|
364
|
+
|
|
365
|
+
# 3. Reset Stack and save Home
|
|
366
|
+
self.canvas.toolbar._nav_stack.clear()
|
|
367
|
+
self.canvas.toolbar.push_current()
|
|
368
|
+
|
|
369
|
+
# 4. Restore User Zoom
|
|
370
|
+
self.ax.set_xlim(current_xlim)
|
|
371
|
+
self.ax.set_ylim(current_ylim)
|
|
372
|
+
|
|
373
|
+
# 5. Push restored zoom state so "Back"/"Forward" logic works from here?
|
|
374
|
+
# Actually, if we just restore, we are "live" at a new state.
|
|
375
|
+
# If we don't push, "Home" works. "Back" might not exist yet. That's fine.
|
|
376
|
+
self.canvas.toolbar.push_current()
|
|
377
|
+
|
|
344
378
|
self.canvas.draw()
|
|
345
379
|
else:
|
|
346
380
|
self.line_mode = False
|
|
347
381
|
self.lock_y_action.setChecked(False)
|
|
348
382
|
self.lock_y_action.setEnabled(False)
|
|
383
|
+
|
|
384
|
+
# Disable manual layout control
|
|
385
|
+
if hasattr(self.canvas, "manual_layout"):
|
|
386
|
+
self.canvas.manual_layout = False
|
|
387
|
+
|
|
349
388
|
# Disconnect events
|
|
350
389
|
if hasattr(self, "cid_press"):
|
|
351
390
|
self.fig.canvas.mpl_disconnect(self.cid_press)
|
|
@@ -367,17 +406,24 @@ class StackVisualizer(CelldetectiveWidget):
|
|
|
367
406
|
self.ax_profile = None
|
|
368
407
|
|
|
369
408
|
# Restore original layout
|
|
370
|
-
if hasattr(self, "ax_original_pos"):
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
409
|
+
# if hasattr(self, "ax_original_pos"):
|
|
410
|
+
# standard 1x1 GridSpec or manual restore
|
|
411
|
+
import matplotlib.gridspec as gridspec
|
|
412
|
+
|
|
413
|
+
gs = gridspec.GridSpec(1, 1)
|
|
414
|
+
self.ax.set_subplotspec(gs[0])
|
|
415
|
+
# self.ax.set_position(gs[0].get_position(self.fig))
|
|
416
|
+
self.fig.subplots_adjust(
|
|
417
|
+
top=1, bottom=0, right=1, left=0, hspace=0, wspace=0
|
|
418
|
+
)
|
|
419
|
+
# self.ax.set_position(self.ax_original_pos) # tight layout should fix it
|
|
420
|
+
|
|
421
|
+
# Re-enable tight_layout via standard resize event later or explicit call
|
|
422
|
+
self.fig.tight_layout()
|
|
423
|
+
|
|
424
|
+
# Reset Toolbar Stack for Standard View
|
|
425
|
+
self.canvas.toolbar._nav_stack.clear()
|
|
426
|
+
self.canvas.toolbar.push_current()
|
|
381
427
|
|
|
382
428
|
self.canvas.draw()
|
|
383
429
|
self.info_lbl.setText("")
|
|
@@ -548,7 +594,10 @@ class StackVisualizer(CelldetectiveWidget):
|
|
|
548
594
|
self.mode = "direct"
|
|
549
595
|
self.stack_length = len(self.stack)
|
|
550
596
|
self.mid_time = self.stack_length // 2
|
|
551
|
-
self.
|
|
597
|
+
self.current_time_index = 0
|
|
598
|
+
self.init_frame = self.stack[
|
|
599
|
+
self.current_time_index, :, :, self.target_channel
|
|
600
|
+
]
|
|
552
601
|
self.last_frame = self.stack[-1, :, :, self.target_channel]
|
|
553
602
|
else:
|
|
554
603
|
self.mode = "virtual"
|
|
@@ -561,6 +610,7 @@ class StackVisualizer(CelldetectiveWidget):
|
|
|
561
610
|
|
|
562
611
|
self.stack_length = auto_load_number_of_frames(self.stack_path)
|
|
563
612
|
self.mid_time = self.stack_length // 2
|
|
613
|
+
self.current_time_index = 0
|
|
564
614
|
self.img_num_per_channel = _get_img_num_per_channel(
|
|
565
615
|
np.arange(self.n_channels), self.stack_length, self.n_channels
|
|
566
616
|
)
|
|
@@ -573,7 +623,7 @@ class StackVisualizer(CelldetectiveWidget):
|
|
|
573
623
|
self.loader_thread.start()
|
|
574
624
|
|
|
575
625
|
self.init_frame = load_frames(
|
|
576
|
-
self.img_num_per_channel[self.target_channel, self.
|
|
626
|
+
self.img_num_per_channel[self.target_channel, self.current_time_index],
|
|
577
627
|
self.stack_path,
|
|
578
628
|
normalize_input=False,
|
|
579
629
|
)[:, :, 0]
|
|
@@ -708,7 +758,7 @@ class StackVisualizer(CelldetectiveWidget):
|
|
|
708
758
|
layout = QHBoxLayout()
|
|
709
759
|
self.frame_slider = QLabeledSlider(Qt.Horizontal)
|
|
710
760
|
self.frame_slider.setRange(0, self.stack_length - 1)
|
|
711
|
-
self.frame_slider.setValue(self.
|
|
761
|
+
self.frame_slider.setValue(self.current_time_index)
|
|
712
762
|
self.frame_slider.valueChanged.connect(self.change_frame)
|
|
713
763
|
layout.addWidget(QLabel("Time: "), 15)
|
|
714
764
|
layout.addWidget(self.frame_slider, 85)
|
|
@@ -716,7 +766,7 @@ class StackVisualizer(CelldetectiveWidget):
|
|
|
716
766
|
|
|
717
767
|
def set_target_channel(self, value):
|
|
718
768
|
self.target_channel = value
|
|
719
|
-
self.init_frame = self.stack[self.
|
|
769
|
+
self.init_frame = self.stack[self.current_time_index, :, :, self.target_channel]
|
|
720
770
|
self.im.set_data(self.init_frame)
|
|
721
771
|
self.canvas.draw()
|
|
722
772
|
self.update_profile()
|
|
@@ -734,7 +784,9 @@ class StackVisualizer(CelldetectiveWidget):
|
|
|
734
784
|
self.change_frame_from_channel_switch(self.frame_slider.value())
|
|
735
785
|
else:
|
|
736
786
|
if self.stack is not None and self.stack.ndim == 4:
|
|
737
|
-
self.init_frame = self.stack[
|
|
787
|
+
self.init_frame = self.stack[
|
|
788
|
+
self.current_time_index, :, :, self.target_channel
|
|
789
|
+
]
|
|
738
790
|
self.im.set_data(self.init_frame)
|
|
739
791
|
self.canvas.draw()
|
|
740
792
|
self.update_profile()
|
|
@@ -747,7 +799,8 @@ class StackVisualizer(CelldetectiveWidget):
|
|
|
747
799
|
p01 = np.nanpercentile(self.init_frame, 0.1)
|
|
748
800
|
p99 = np.nanpercentile(self.init_frame, 99.9)
|
|
749
801
|
self.im.set_clim(vmin=p01, vmax=p99)
|
|
750
|
-
self.
|
|
802
|
+
if self.create_contrast_slider and hasattr(self, "contrast_slider"):
|
|
803
|
+
self.contrast_slider.setValue((p01, p99))
|
|
751
804
|
self.channel_trigger = False
|
|
752
805
|
self.canvas.draw()
|
|
753
806
|
|
{celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/viewers/channel_offset_viewer.py
RENAMED
|
@@ -9,11 +9,16 @@ from superqt import QLabeledDoubleSlider, QLabeledDoubleRangeSlider
|
|
|
9
9
|
from celldetective.gui.base.components import QHSeperationLine
|
|
10
10
|
from celldetective.gui.gui_utils import QuickSliderLayout, ThresholdLineEdit
|
|
11
11
|
from celldetective.gui.viewers.base_viewer import StackVisualizer
|
|
12
|
-
from celldetective.utils.image_loaders import
|
|
12
|
+
from celldetective.utils.image_loaders import (
|
|
13
|
+
load_frames,
|
|
14
|
+
auto_load_number_of_frames,
|
|
15
|
+
_get_img_num_per_channel,
|
|
16
|
+
)
|
|
13
17
|
from celldetective import get_logger
|
|
14
18
|
|
|
15
19
|
logger = get_logger(__name__)
|
|
16
20
|
|
|
21
|
+
|
|
17
22
|
class ChannelOffsetViewer(StackVisualizer):
|
|
18
23
|
|
|
19
24
|
def __init__(self, parent_window=None, *args, **kwargs):
|
|
@@ -22,16 +27,32 @@ class ChannelOffsetViewer(StackVisualizer):
|
|
|
22
27
|
self.overlay_target_channel = -1
|
|
23
28
|
self.shift_vertical = 0
|
|
24
29
|
self.shift_horizontal = 0
|
|
30
|
+
self.overlay_init_contrast = False
|
|
25
31
|
super().__init__(*args, **kwargs)
|
|
26
32
|
|
|
27
33
|
self.load_stack()
|
|
34
|
+
|
|
35
|
+
if self.mode == "direct":
|
|
36
|
+
# Initialize overlay frames for direct mode
|
|
37
|
+
default_overlay_idx = -1
|
|
38
|
+
if self.stack.ndim == 4:
|
|
39
|
+
self.overlay_init_frame = self.stack[
|
|
40
|
+
self.current_time_index, :, :, default_overlay_idx
|
|
41
|
+
]
|
|
42
|
+
self.overlay_last_frame = self.stack[-1, :, :, default_overlay_idx]
|
|
43
|
+
else:
|
|
44
|
+
# Should rely on 4D stack assumption from StackVisualizer
|
|
45
|
+
self.overlay_init_frame = self.init_frame
|
|
46
|
+
self.overlay_last_frame = self.last_frame
|
|
47
|
+
|
|
28
48
|
self.canvas.layout.addWidget(QHSeperationLine())
|
|
29
49
|
|
|
30
50
|
self.generate_overlay_channel_cb()
|
|
31
51
|
self.generate_overlay_imshow()
|
|
32
52
|
|
|
33
53
|
self.generate_overlay_alpha_slider()
|
|
34
|
-
self.
|
|
54
|
+
if self.create_contrast_slider:
|
|
55
|
+
self.generate_overlay_contrast_slider()
|
|
35
56
|
|
|
36
57
|
self.generate_overlay_shift()
|
|
37
58
|
self.generate_add_to_parent_btn()
|
|
@@ -190,7 +211,7 @@ class ChannelOffsetViewer(StackVisualizer):
|
|
|
190
211
|
|
|
191
212
|
self.im_overlay.set_data(self.overlay_init_frame)
|
|
192
213
|
|
|
193
|
-
if self.overlay_init_contrast:
|
|
214
|
+
if self.overlay_init_contrast and self.create_contrast_slider:
|
|
194
215
|
self.im_overlay.autoscale()
|
|
195
216
|
I_min, I_max = self.im_overlay.get_clim()
|
|
196
217
|
self.overlay_contrast_slider.setRange(
|
|
@@ -214,12 +235,13 @@ class ChannelOffsetViewer(StackVisualizer):
|
|
|
214
235
|
gc.collect()
|
|
215
236
|
|
|
216
237
|
self.mid_time = self.stack_length // 2
|
|
238
|
+
self.current_time_index = 0
|
|
217
239
|
self.img_num_per_channel = _get_img_num_per_channel(
|
|
218
240
|
np.arange(self.n_channels), self.stack_length, self.n_channels
|
|
219
241
|
)
|
|
220
242
|
|
|
221
243
|
self.init_frame = load_frames(
|
|
222
|
-
self.img_num_per_channel[self.target_channel, self.
|
|
244
|
+
self.img_num_per_channel[self.target_channel, self.current_time_index],
|
|
223
245
|
self.stack_path,
|
|
224
246
|
normalize_input=False,
|
|
225
247
|
).astype(float)[:, :, 0]
|
|
@@ -229,7 +251,9 @@ class ChannelOffsetViewer(StackVisualizer):
|
|
|
229
251
|
normalize_input=False,
|
|
230
252
|
).astype(float)[:, :, 0]
|
|
231
253
|
self.overlay_init_frame = load_frames(
|
|
232
|
-
self.img_num_per_channel[
|
|
254
|
+
self.img_num_per_channel[
|
|
255
|
+
self.overlay_target_channel, self.current_time_index
|
|
256
|
+
],
|
|
233
257
|
self.stack_path,
|
|
234
258
|
normalize_input=False,
|
|
235
259
|
).astype(float)[:, :, 0]
|
|
@@ -306,6 +330,7 @@ class ChannelOffsetViewer(StackVisualizer):
|
|
|
306
330
|
)
|
|
307
331
|
self.im_overlay.set_data(self.shifted_frame)
|
|
308
332
|
self.fig.canvas.draw_idle()
|
|
333
|
+
self.update_profile()
|
|
309
334
|
|
|
310
335
|
def generate_add_to_parent_btn(self):
|
|
311
336
|
|
|
@@ -318,6 +343,95 @@ class ChannelOffsetViewer(StackVisualizer):
|
|
|
318
343
|
add_hbox.addWidget(QLabel(""), 33)
|
|
319
344
|
self.canvas.layout.addLayout(add_hbox)
|
|
320
345
|
|
|
346
|
+
def update_profile(self):
|
|
347
|
+
if not self.line_mode or not hasattr(self, "line_x") or not self.line_x:
|
|
348
|
+
return
|
|
349
|
+
|
|
350
|
+
# Calculate profile
|
|
351
|
+
x0, y0 = self.line_x[0], self.line_y[0]
|
|
352
|
+
x1, y1 = self.line_x[1], self.line_y[1]
|
|
353
|
+
length_px = np.hypot(x1 - x0, y1 - y0)
|
|
354
|
+
if length_px == 0:
|
|
355
|
+
return
|
|
356
|
+
|
|
357
|
+
num_points = int(length_px)
|
|
358
|
+
if num_points < 2:
|
|
359
|
+
num_points = 2
|
|
360
|
+
|
|
361
|
+
x, y = np.linspace(x0, x1, num_points), np.linspace(y0, y1, num_points)
|
|
362
|
+
|
|
363
|
+
# Use self.init_frame and overlay frame
|
|
364
|
+
profiles = []
|
|
365
|
+
colors = ["black", "tab:blue"]
|
|
366
|
+
|
|
367
|
+
# Main channel profile
|
|
368
|
+
if hasattr(self, "init_frame") and self.init_frame is not None:
|
|
369
|
+
from scipy.ndimage import map_coordinates
|
|
370
|
+
|
|
371
|
+
profile = map_coordinates(
|
|
372
|
+
self.init_frame, np.vstack((y, x)), order=1, mode="nearest"
|
|
373
|
+
)
|
|
374
|
+
profiles.append(profile)
|
|
375
|
+
else:
|
|
376
|
+
profiles.append(None)
|
|
377
|
+
|
|
378
|
+
# Overlay channel profile
|
|
379
|
+
# Use data currently in im_overlay, which accounts for shifts
|
|
380
|
+
overlay_data = self.im_overlay.get_array()
|
|
381
|
+
if overlay_data is not None:
|
|
382
|
+
from scipy.ndimage import map_coordinates
|
|
383
|
+
|
|
384
|
+
profile_overlay = map_coordinates(
|
|
385
|
+
overlay_data, np.vstack((y, x)), order=1, mode="nearest"
|
|
386
|
+
)
|
|
387
|
+
profiles.append(profile_overlay)
|
|
388
|
+
else:
|
|
389
|
+
profiles.append(None)
|
|
390
|
+
|
|
391
|
+
# Basic setup
|
|
392
|
+
self.ax_profile.clear()
|
|
393
|
+
self.ax_profile.set_facecolor("none")
|
|
394
|
+
|
|
395
|
+
# Distance axis
|
|
396
|
+
dist_axis = np.arange(num_points)
|
|
397
|
+
title_str = f"{round(length_px,2)} [px]"
|
|
398
|
+
if self.PxToUm is not None:
|
|
399
|
+
title_str += f" | {round(length_px*self.PxToUm,3)} [µm]"
|
|
400
|
+
|
|
401
|
+
# Handle Y-Axis Locking
|
|
402
|
+
current_ylim = None
|
|
403
|
+
if self.lock_y_action.isChecked():
|
|
404
|
+
current_ylim = self.ax_profile.get_ylim()
|
|
405
|
+
|
|
406
|
+
# Plot profiles
|
|
407
|
+
for i, (profile, color) in enumerate(zip(profiles, colors)):
|
|
408
|
+
if profile is not None:
|
|
409
|
+
if np.all(np.isnan(profile)):
|
|
410
|
+
profile = np.zeros_like(profile)
|
|
411
|
+
profile[:] = np.nan
|
|
412
|
+
|
|
413
|
+
self.ax_profile.plot(
|
|
414
|
+
dist_axis, profile, color=color, linestyle="-", label=f"Ch{i}"
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
self.ax_profile.set_xticks([])
|
|
418
|
+
self.ax_profile.set_ylabel("Intensity", fontsize=8)
|
|
419
|
+
self.ax_profile.set_xlabel(title_str, fontsize=8)
|
|
420
|
+
self.ax_profile.tick_params(axis="y", which="major", labelsize=6)
|
|
421
|
+
|
|
422
|
+
# Hide spines
|
|
423
|
+
self.ax_profile.spines["top"].set_visible(False)
|
|
424
|
+
self.ax_profile.spines["right"].set_visible(False)
|
|
425
|
+
self.ax_profile.spines["bottom"].set_color("black")
|
|
426
|
+
self.ax_profile.spines["left"].set_color("black")
|
|
427
|
+
|
|
428
|
+
self.fig.set_facecolor("none")
|
|
429
|
+
|
|
430
|
+
if current_ylim:
|
|
431
|
+
self.ax_profile.set_ylim(current_ylim)
|
|
432
|
+
|
|
433
|
+
self.fig.canvas.draw_idle()
|
|
434
|
+
|
|
321
435
|
def set_parent_attributes(self):
|
|
322
436
|
|
|
323
437
|
idx = self.channels_overlay_cb.currentIndex()
|
{celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/gui/viewers/threshold_viewer.py
RENAMED
|
@@ -65,8 +65,6 @@ class ThresholdedStackVisualizer(StackVisualizer):
|
|
|
65
65
|
self.thresh_min = 0.0
|
|
66
66
|
self.thresh_max = 30.0
|
|
67
67
|
|
|
68
|
-
self.thresh_max = 30.0
|
|
69
|
-
|
|
70
68
|
# Cache for processed images
|
|
71
69
|
self.processed_cache = OrderedDict()
|
|
72
70
|
self.processed_image = None
|
|
@@ -74,6 +72,15 @@ class ThresholdedStackVisualizer(StackVisualizer):
|
|
|
74
72
|
|
|
75
73
|
self.generate_threshold_slider()
|
|
76
74
|
|
|
75
|
+
# Ensure we start at frame 0 for consistent mask caching and UX
|
|
76
|
+
if self.create_frame_slider and hasattr(self, "frame_slider"):
|
|
77
|
+
self.frame_slider.blockSignals(True)
|
|
78
|
+
self.frame_slider.setValue(0)
|
|
79
|
+
self.frame_slider.blockSignals(False)
|
|
80
|
+
self.change_frame(0)
|
|
81
|
+
elif self.stack_length > 0:
|
|
82
|
+
self.change_frame(0)
|
|
83
|
+
|
|
77
84
|
if self.thresh is not None:
|
|
78
85
|
self.compute_mask(self.thresh)
|
|
79
86
|
|
|
@@ -138,8 +145,8 @@ class ThresholdedStackVisualizer(StackVisualizer):
|
|
|
138
145
|
slider_range=(self.thresh_min, np.amax([self.thresh_max, init_value])),
|
|
139
146
|
decimal_option=True,
|
|
140
147
|
precision=4,
|
|
148
|
+
layout_ratio=(0.15, 0.85),
|
|
141
149
|
)
|
|
142
|
-
thresh_layout.setContentsMargins(15, 0, 15, 0)
|
|
143
150
|
self.threshold_slider.valueChanged.connect(self.change_threshold)
|
|
144
151
|
if self.show_threshold_slider:
|
|
145
152
|
self.canvas.layout.addLayout(thresh_layout)
|
|
@@ -154,8 +161,8 @@ class ThresholdedStackVisualizer(StackVisualizer):
|
|
|
154
161
|
slider_range=(0, 1),
|
|
155
162
|
decimal_option=True,
|
|
156
163
|
precision=3,
|
|
164
|
+
layout_ratio=(0.15, 0.85),
|
|
157
165
|
)
|
|
158
|
-
opacity_layout.setContentsMargins(15, 0, 15, 0)
|
|
159
166
|
self.opacity_slider.valueChanged.connect(self.change_mask_opacity)
|
|
160
167
|
if self.show_opacity_slider:
|
|
161
168
|
self.canvas.layout.addLayout(opacity_layout)
|
|
@@ -190,7 +197,8 @@ class ThresholdedStackVisualizer(StackVisualizer):
|
|
|
190
197
|
if self.thresh is not None:
|
|
191
198
|
self.compute_mask(self.thresh)
|
|
192
199
|
mask = np.ma.masked_where(self.mask == 0, self.mask)
|
|
193
|
-
self
|
|
200
|
+
if hasattr(self, "im_mask"):
|
|
201
|
+
self.im_mask.set_data(mask)
|
|
194
202
|
self.canvas.canvas.draw_idle()
|
|
195
203
|
|
|
196
204
|
def change_frame(self, value):
|
|
@@ -219,7 +227,7 @@ class ThresholdedStackVisualizer(StackVisualizer):
|
|
|
219
227
|
threshold_image,
|
|
220
228
|
)
|
|
221
229
|
|
|
222
|
-
edge = estimate_unreliable_edge(self.preprocessing)
|
|
230
|
+
edge = estimate_unreliable_edge(self.preprocessing or [])
|
|
223
231
|
|
|
224
232
|
if isinstance(threshold_value, (list, np.ndarray, tuple)):
|
|
225
233
|
self.mask = threshold_image(
|
{celldetective-1.5.0b3 → celldetective-1.5.0b5}/celldetective/utils/cellpose_utils/__init__.py
RENAMED
|
@@ -113,13 +113,29 @@ def _prep_cellpose_model(
|
|
|
113
113
|
|
|
114
114
|
from cellpose.models import CellposeModel
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
116
|
+
try:
|
|
117
|
+
model = CellposeModel(
|
|
118
|
+
gpu=use_gpu,
|
|
119
|
+
device=device,
|
|
120
|
+
pretrained_model=path + model_name,
|
|
121
|
+
model_type=None,
|
|
122
|
+
nchan=n_channels,
|
|
123
|
+
) # diam_mean=30.0,
|
|
124
|
+
except AssertionError as e:
|
|
125
|
+
if use_gpu:
|
|
126
|
+
print(
|
|
127
|
+
f"[WARNING] Could not load Cellpose model with GPU ({e}). Retrying with CPU..."
|
|
128
|
+
)
|
|
129
|
+
device = torch.device("cpu")
|
|
130
|
+
model = CellposeModel(
|
|
131
|
+
gpu=False,
|
|
132
|
+
device=device,
|
|
133
|
+
pretrained_model=path + model_name,
|
|
134
|
+
model_type=None,
|
|
135
|
+
nchan=n_channels,
|
|
136
|
+
)
|
|
137
|
+
else:
|
|
138
|
+
raise e
|
|
123
139
|
if scale is None:
|
|
124
140
|
scale_model = model.diam_mean / model.diam_labels
|
|
125
141
|
else:
|
|
@@ -177,6 +177,7 @@ celldetective/utils/plots/__init__.py
|
|
|
177
177
|
celldetective/utils/plots/regression.py
|
|
178
178
|
celldetective/utils/stardist_utils/__init__.py
|
|
179
179
|
tests/__init__.py
|
|
180
|
+
tests/test_cellpose_fallback.py
|
|
180
181
|
tests/test_events.py
|
|
181
182
|
tests/test_filters.py
|
|
182
183
|
tests/test_io.py
|
|
@@ -190,5 +191,6 @@ tests/test_tracking.py
|
|
|
190
191
|
tests/test_utils.py
|
|
191
192
|
tests/gui/__init__.py
|
|
192
193
|
tests/gui/test_enhancements.py
|
|
194
|
+
tests/gui/test_measure_annotator_bugfix.py
|
|
193
195
|
tests/gui/test_new_project.py
|
|
194
196
|
tests/gui/test_project.py
|