pycat-napari 1.6.332__tar.gz → 1.6.333__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.
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/CHANGELOG.md +23 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/PKG-INFO +1 -1
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/pyproject.toml +1 -1
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/central_manager.py +1 -1
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/executor.py +16 -3
- pycat_napari-1.6.333/src/pycat/navigator/parameters.py +192 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/navigator_dock.py +84 -5
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/.gitignore +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/CONTRIBUTING.md +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/LICENSE +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/README.md +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/THIRD_PARTY_LICENSES.txt +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/benchmarks/README.md +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/config/README.md +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/config/requirements-arm-mac.txt +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/config/requirements-base.txt +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/config/requirements-devbio-napari-arm-mac.txt +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/config/requirements-devbio-napari.txt +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/batch/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/batch/steps/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/batch/steps/_common.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/batch/steps/analysis_steps.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/batch/steps/brightfield_steps.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/batch/steps/invitro_steps.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/batch/steps/io_steps.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/batch/steps/preprocessing_steps.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/batch/steps/segmentation_steps.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/batch_processor.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/batch_step_registry.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/data/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/data/data_modules.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/czi_seam.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/dialogs.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/file_io.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/frap_io.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/image_reader.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/image_source.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/image_structure.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/lazy_guard.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/lazy_sources.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/load_channel_identity.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/local_cache.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/metadata_extract.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/multidim_io.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/naming.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/napari_adapter.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/readers/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/readers/czi_bioformats.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/readers/image_reader_2d.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/readers/ims_reader.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/readers/mask_reader.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/readers/stack_layer_builders.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/readers/stack_metadata.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/routing.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/scenes.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/session.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/session_loader.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/session_manifest.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/sidecar_discovery.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/stack_access.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/stack_load.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/stack_openers.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/storage_probe.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/tagging.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/tiff_planes.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/tifffile_zarr_shim.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/viewer_load.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/writers.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/zarr_compat.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/fix_tifffile.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/icons/pycat_logo_512.png +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/icons/pycat_mark.png +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/adapters.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/canonical.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/capabilities.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/context.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/contracts.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/data/PyCAT_layer_tag_hierarchy_and_module_flow.xlsx +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/data/PyCAT_module_information_contracts.xlsx +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/data/PyCAT_question_tree_and_method_mapping.xlsx +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/data/operation_catalog.json +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/execution.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/gates.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/loader.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/modules.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/op_catalog.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/operation_spec.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/planner.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/quality_gates.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/question_engine.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/registry.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/scientific_tree.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/session.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/tags.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/navigator/templates.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/run_pycat.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/advanced_analysis_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/analysis_plots.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/batch_roi_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/benchmark_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/biological_qc_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/brightfield_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/brightfield_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/clean_spot_detection_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/condensate_modes.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/condensate_physics/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/condensate_physics/coarsening.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/condensate_physics/frame_quality.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/condensate_physics/intensity.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/condensate_physics/moduli.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/condensate_physics/msd.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/condensate_physics/photobleaching.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/condensate_physics/relaxation.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/condensate_physics/survival.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/condensate_physics_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/condensate_physics_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/contrast_cascade_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/contrast_cascade_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/control_validation.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/correlation_func_analysis_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/data_qc_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/data_qc_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/data_viz_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/drawing_layers.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/dynamic_spatial_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/fd_curve_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/fd_curve_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/feature_analysis_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/feature_redundancy.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/fft_bandpass_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/fibril_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/fibril_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/frap_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/frap_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/fusion_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/fusion_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/gaussian_localization_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/general_image_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/gpu_utils.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/image_processing/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/image_processing/_base.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/image_processing/background.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/image_processing/deblur.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/image_processing/filters.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/image_processing/preprocessing.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/image_processing/size_estimation.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/image_processing/upscaling.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/image_processing_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/intensity_profile_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/invitro/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/invitro/analysis.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/invitro/field_summary.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/invitro/partition.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/invitro/size_distribution.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/invitro_bf_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/invitro_fluor_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/invitro_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/kymograph_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/label_and_mask_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/layer_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/measurement_stability.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/molecular_counting_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/morphological_complexity_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/nb_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/nb_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/numba_utils.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/obj_based_coloc_analysis_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/organizational_metrics_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/partial_volume_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/partition_enrichment_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/pipeline_diagnostic_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/pipeline_snr_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/pixel_wise_corr_analysis_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/qc_gallery.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/qc_gallery_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/ratiometric_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/scan_qc_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/segmentation/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/segmentation/_common.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/segmentation/cellpose.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/segmentation/fz.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/segmentation/intensity.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/segmentation/local_thresholding.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/segmentation/morphology.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/segmentation/puncta_refinement.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/segmentation/subcellular.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/segmentation/watershed.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/segmentation_scale_advisor.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/segmentation_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/smlm_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/spatial_acf_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/spatial_metrology_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/spatial_metrology_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/spatial_randomness_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/spida_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/spida_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/temperature_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/temperature_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/temporal_enhancement_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/timeseries/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/timeseries/analysis.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/timeseries/correlation.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/timeseries/execution.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/timeseries/frame_access.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/timeseries/preprocessing.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/timeseries/ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/timeseries_condensate_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/timeseries_invitro_fluor_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/timeseries_invitro_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/topology_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/trackmate_bridge.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/ts_cache_manager.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/ts_cellpose_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/two_channel_coloc_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/unmixing_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/video_export_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt/analysis.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt/detection.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt/drift.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt/host.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt/msd_adapter.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt/napari_adapter.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt/panels.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt/populations.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt/results_dock.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt/table_adapter.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt/viscosity.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/vpt_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/zstack_segmentation_tools.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/toolbox/zstack_segmentation_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/brushable_table.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/brushable_workspace.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/channel_identity_dialog.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/comparative_figures_ui.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/coordinate_readout.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/feature_explorer_dock.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/field_status.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/home_dock.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/linked_selection_dock.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/menu_manager.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/metadata_contradiction_panel.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/operation_gating.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/preferences_dialog.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/preset_picker.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/scene_switcher.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/ui_analysis_mixin.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/ui_diagnostics_mixin.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/ui_filtering_mixin.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/ui_imageops_mixin.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/ui_labels_mixin.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/ui_modules.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/ui_segmentation_mixin.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/ui_utils.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/ui/workflow_checklist.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/__init__.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/analysis_presets.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/app_mode.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/batch_brushing.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/brushing.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/calibration.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/channel_designations.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/channel_modality.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/channel_naming.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/cohort_targets.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/comparative_figures.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/comparative_stats.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/consolidated_table.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/dataset_identity.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/dock_space.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/entity_ref.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/entity_registry.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/environment_check.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/errors.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/feature_cards.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/feature_explorer.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/feature_families.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/feature_provenance.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/feature_registry.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/field_registry_hub.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/figure_refine.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/figure_spec.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/filter_store.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/fit_quality.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/frame_interval.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/general_utils.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/intensity_semantics.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/layer_bindings.json +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/layer_tag_hook.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/layer_tags.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/logging_utils.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/marker_logic.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/math_utils.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/measurement.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/measurement_ontology.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/metadata_contradictions.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/metadata_validity.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/notify.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/object_graph.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/object_ref.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/operation_runner.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/pixel_size.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/plot_backend_pyqtgraph.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/plot_backend_selection.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/plot_backends.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/preferences.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/qt_worker.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/quality_gate.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/reliability.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/result_models.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/results_store.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/sample_metadata.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/selection_overlay.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/selection_service.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/tag_registry.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/tag_resolver.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/utils/user_settings.py +0 -0
- {pycat_napari-1.6.332 → pycat_napari-1.6.333}/tests/README.md +0 -0
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
## [1.6.333] - 2026-07-24
|
|
2
|
+
### Added — **Navigator execution-adapter layer, Phase 2: an honest parameter review — seeded, editable, provenance-recorded.**
|
|
3
|
+
The navigator asks *what* to do, not *with which parameters* — but a guided run that silently picks a
|
|
4
|
+
rolling-ball radius (or a segmentation method) the user never saw is worse than asking. Phase 2 adds the
|
|
5
|
+
minimal parameter review, Qt-free at its core:
|
|
6
|
+
- New **`navigator/parameters.py`**: each adapter-covered step declares its **material** parameters (the handful
|
|
7
|
+
the science turns on, not every argument). `build_param_review(plan, ctx)` seeds them by a declared
|
|
8
|
+
precedence — **a matching preset → a session value → the grounded function default** — never an invented one.
|
|
9
|
+
`ReviewedStep` generalises the preset `populate-but-never-lock` contract to the no-preset case too: the user
|
|
10
|
+
may edit any value, and the edit is tracked as **provenance in the exact `PresetApplication.record()` shape**
|
|
11
|
+
(`preset_key`, `modified_parameters`, `is_modified`, `parameters`), `preset_key=None` when no preset seeded it.
|
|
12
|
+
- **The reviewed values drive the run.** `run_plan(…, params_by_step=, provenance_by_step=)` merges the reviewed
|
|
13
|
+
values over the adapter's derived params (routing keys like `active_layer` still come from the adapter) and
|
|
14
|
+
records the provenance onto each ran step's `StepOutcome`. `tests/navigator/test_navigator_parameters.py`
|
|
15
|
+
(`base`, 9) pins it: an edited rolling-ball radius makes the guided result equal the **manual operation at
|
|
16
|
+
that radius** — and *not* at the default — so the edit provably reaches the computation.
|
|
17
|
+
- **The dock surfaces it**: the plan view renders an editable "Review parameters" form (a spin/combo per
|
|
18
|
+
material parameter, seeded, tooltip-documented) above Run; the Run passes the `ParamReview` through
|
|
19
|
+
`run_plan_via_central_manager`, which also reports which steps ran with modified parameters. A programmatic
|
|
20
|
+
run with no form still builds a default-seeded review, so provenance is recorded either way.
|
|
21
|
+
- **Later phases** (per the `navigator_execution_adapters` spec): more adapters one workflow at a time (each
|
|
22
|
+
behind its route-equivalence test), then dock progress + cancel.
|
|
23
|
+
|
|
1
24
|
## [1.6.332] - 2026-07-24
|
|
2
25
|
### Added — **Navigator execution-adapter layer, Phase 1: "Run analysis" computes a plan through the batch handlers, gate-respecting (guided == batch == manual).**
|
|
3
26
|
`selection_scale` Part 2 established there is no uniform "run this op" — but the batch `_STEP_MAP` handlers ARE
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycat-napari
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.333
|
|
4
4
|
Summary: Python Condensate Analysis Toolbox - A napari-based tool for biomolecular condensate analysis
|
|
5
5
|
Project-URL: Homepage, https://github.com/BanerjeeLab-repertoire/pycat-napari
|
|
6
6
|
Project-URL: Repository, https://github.com/BanerjeeLab-repertoire/pycat-napari
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pycat-napari"
|
|
7
|
-
version = "1.6.
|
|
7
|
+
version = "1.6.333"
|
|
8
8
|
description = "Python Condensate Analysis Toolbox - A napari-based tool for biomolecular condensate analysis"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
# 3.13 is BLOCKED UPSTREAM, not by PyCAT's own code (which compiles and passes core on 3.13).
|
|
@@ -124,7 +124,7 @@ class CentralManager:
|
|
|
124
124
|
from pycat.ui.navigator_dock import install_navigator_action, run_plan_via_central_manager
|
|
125
125
|
self._navigator_action = install_navigator_action(
|
|
126
126
|
self.viewer, central_manager=self,
|
|
127
|
-
on_run=lambda plan: run_plan_via_central_manager(self, plan))
|
|
127
|
+
on_run=lambda plan, review=None: run_plan_via_central_manager(self, plan, review))
|
|
128
128
|
# Populate the feature registry so any consumer (the beginner home dock, a capability query) sees
|
|
129
129
|
# every surfaced-but-otherwise-hidden feature (navigator inc 4). Guarded: a registration hiccup must
|
|
130
130
|
# never break startup, and the cards' openers import Qt/toolbox lazily so this stays cheap.
|
|
@@ -58,10 +58,13 @@ def has_adapter(step_name: str) -> bool:
|
|
|
58
58
|
@dataclasses.dataclass(frozen=True)
|
|
59
59
|
class StepOutcome:
|
|
60
60
|
"""What happened to one step. ``outcome`` is ``'ran'`` / ``'ran_with_caveat'`` / ``'blocked'`` (the run
|
|
61
|
-
stops here) / ``'skipped'`` (after a blocker) / ``'needs_panel'`` (no adapter yet) / ``'error'``.
|
|
61
|
+
stops here) / ``'skipped'`` (after a blocker) / ``'needs_panel'`` (no adapter yet) / ``'error'``.
|
|
62
|
+
``provenance`` (Phase 2) records how the step was parameterised — the ``PresetApplication.record()`` shape
|
|
63
|
+
(which preset, if any, seeded it and what the user changed) — empty when the step carried no review."""
|
|
62
64
|
name: str
|
|
63
65
|
outcome: str
|
|
64
66
|
detail: str = ""
|
|
67
|
+
provenance: dict = dataclasses.field(default_factory=dict)
|
|
65
68
|
|
|
66
69
|
|
|
67
70
|
@dataclasses.dataclass
|
|
@@ -96,6 +99,7 @@ def _build_step_registry() -> dict:
|
|
|
96
99
|
|
|
97
100
|
|
|
98
101
|
def run_plan(plan, state, *, intent=None, ctx=None, image_path=None, output_dir=None, runner=None,
|
|
102
|
+
params_by_step: Optional[dict] = None, provenance_by_step: Optional[dict] = None,
|
|
99
103
|
on_step: Optional[Callable] = None) -> ExecReport:
|
|
100
104
|
"""Execute ``plan``'s steps in gate order by driving the batch handlers, threading ``state`` (a dict the
|
|
101
105
|
handlers read/write, exactly as a batch replay). Returns an :class:`ExecReport`.
|
|
@@ -104,7 +108,11 @@ def run_plan(plan, state, *, intent=None, ctx=None, image_path=None, output_dir=
|
|
|
104
108
|
run at that step (nothing after it runs); a **caveat** runs with the caveat recorded; **probes** run first.
|
|
105
109
|
A step with no :class:`ExecAdapter` is reported ``'needs_panel'`` — never invoked with guessed arguments.
|
|
106
110
|
A step that raises halts the run (downstream depends on its output). ``runner`` (an ``OperationRunner``)
|
|
107
|
-
runs each handler off the Qt thread when given; otherwise handlers run synchronously (headless / tests).
|
|
111
|
+
runs each handler off the Qt thread when given; otherwise handlers run synchronously (headless / tests).
|
|
112
|
+
|
|
113
|
+
``params_by_step`` (Phase 2) overrides the adapter's derived params per step with the user-reviewed values
|
|
114
|
+
(:mod:`pycat.navigator.parameters`); ``provenance_by_step`` records how each ran step was parameterised
|
|
115
|
+
(the ``PresetApplication.record()`` shape) onto its :class:`StepOutcome`."""
|
|
108
116
|
intent = intent if intent is not None else getattr(plan, "intent", None)
|
|
109
117
|
registry = _build_step_registry()
|
|
110
118
|
report = ExecReport()
|
|
@@ -143,6 +151,10 @@ def run_plan(plan, state, *, intent=None, ctx=None, image_path=None, output_dir=
|
|
|
143
151
|
continue
|
|
144
152
|
|
|
145
153
|
params = adapter.params_from(intent, ctx, state)
|
|
154
|
+
if params_by_step and es.name in params_by_step:
|
|
155
|
+
# Reviewed values override the adapter's derived params, but the adapter still supplies the
|
|
156
|
+
# non-reviewed routing keys (e.g. active_layer) — merge, don't replace.
|
|
157
|
+
params = {**params, **params_by_step[es.name]}
|
|
146
158
|
try:
|
|
147
159
|
if runner is not None:
|
|
148
160
|
runner.execute(fn, state, image_path, params, output_dir)
|
|
@@ -153,8 +165,9 @@ def run_plan(plan, state, *, intent=None, ctx=None, image_path=None, output_dir=
|
|
|
153
165
|
halted = True
|
|
154
166
|
continue
|
|
155
167
|
|
|
168
|
+
prov = (provenance_by_step or {}).get(es.name, {})
|
|
156
169
|
report.steps.append(StepOutcome(
|
|
157
|
-
es.name, "ran_with_caveat" if es.status == "caveat" else "ran", es.reason))
|
|
170
|
+
es.name, "ran_with_caveat" if es.status == "caveat" else "ran", es.reason, prov))
|
|
158
171
|
if on_step:
|
|
159
172
|
on_step(report.steps[-1])
|
|
160
173
|
finally:
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""**The minimal parameter review — surface the handful of parameters that change the result, seeded honestly.**
|
|
2
|
+
|
|
3
|
+
Execution-adapter layer, Phase 2. The navigator asks *what* to do, not *with which parameters* — but a guided
|
|
4
|
+
run that silently picks a rolling-ball radius (or a segmentation method) the user never saw is worse than
|
|
5
|
+
asking. So before a run, each adapter-covered step surfaces its **material** parameters — the handful that
|
|
6
|
+
materially change the result — in a small editable set, seeded by a declared precedence:
|
|
7
|
+
|
|
8
|
+
1. **A matching preset** (:mod:`pycat.utils.analysis_presets`) — if one ``applies_to`` this step's workflow,
|
|
9
|
+
its parameters seed the values (the populate-but-never-lock contract).
|
|
10
|
+
2. **A session value** — a measured/derived value already in the context (e.g. a ``ball_radius`` the user
|
|
11
|
+
measured on their data) seeds an un-preset parameter.
|
|
12
|
+
3. **The grounded function default** — the same default the batch handler falls back to; never an invented one.
|
|
13
|
+
|
|
14
|
+
The user may edit any value; the edit is tracked so the run records **which preset (if any) seeded each step
|
|
15
|
+
and what the user changed** — the exact ``PresetApplication.record()`` shape, so a guided result states how it
|
|
16
|
+
was parameterised and a saved template can carry those params. Qt-free: this is the model the dock's editable
|
|
17
|
+
form and :func:`pycat.navigator.executor.run_plan` both read; the dock only builds widgets over it.
|
|
18
|
+
|
|
19
|
+
Phase 2 ships the model + the one shipped adapter's material set (``background_removal`` → ``ball_radius``);
|
|
20
|
+
later adapters declare their material params here as they land, each still behind a route-equivalence test."""
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import dataclasses
|
|
24
|
+
from typing import Optional
|
|
25
|
+
|
|
26
|
+
from .execution import execution_order
|
|
27
|
+
from .executor import has_adapter
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclasses.dataclass(frozen=True)
|
|
31
|
+
class StepParam:
|
|
32
|
+
"""One material parameter of a step — declared, so the review shows the same handful the science turns on
|
|
33
|
+
(not every argument the function takes). ``kind`` is ``'int'`` / ``'float'`` / ``'choice'``; ``default`` is
|
|
34
|
+
the grounded function default (what the batch handler falls back to), never an invented value."""
|
|
35
|
+
name: str
|
|
36
|
+
label: str
|
|
37
|
+
kind: str
|
|
38
|
+
default: object
|
|
39
|
+
choices: tuple = ()
|
|
40
|
+
help: str = ""
|
|
41
|
+
minimum: object = None
|
|
42
|
+
maximum: object = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
#: The material parameters per plan step — the ONLY place a step declares which of its arguments are surfaced
|
|
46
|
+
#: for review. Grows one adapter at a time (each behind its route-equivalence test), mirroring ``executor._ADAPTERS``.
|
|
47
|
+
_MATERIAL: dict = {
|
|
48
|
+
"background_removal": (
|
|
49
|
+
StepParam("ball_radius", "Rolling-ball radius (px)", "int", 50, minimum=1,
|
|
50
|
+
help="The rolling-ball structuring radius for background estimation. Larger keeps more "
|
|
51
|
+
"low-frequency structure; too small eats real signal. Default 50 px."),
|
|
52
|
+
),
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
#: Plan step → the ``analysis_presets`` workflow id whose presets seed it (preset precedence, source 1). Empty
|
|
57
|
+
#: for the shipped adapter (no preset applies to ``background_removal``); entries land with the adapters that a
|
|
58
|
+
#: preset actually configures (e.g. ``condensate_puncta_refinement``), one per phase.
|
|
59
|
+
_PRESET_WORKFLOW: dict = {}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def material_params(step_name: str) -> tuple:
|
|
63
|
+
"""The declared material parameters of ``step_name`` (empty if none/unknown)."""
|
|
64
|
+
return _MATERIAL.get(step_name, ())
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _coerce(param: StepParam, value):
|
|
68
|
+
"""Coerce a value to the parameter's kind, falling back to the default on a bad value (never raise into a
|
|
69
|
+
run) — an int param must not carry a float that changes ``ceil`` downstream."""
|
|
70
|
+
try:
|
|
71
|
+
if param.kind == "int":
|
|
72
|
+
return int(round(float(value)))
|
|
73
|
+
if param.kind == "float":
|
|
74
|
+
return float(value)
|
|
75
|
+
except (TypeError, ValueError):
|
|
76
|
+
return param.default
|
|
77
|
+
return value
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _applicable_preset(step_name: str):
|
|
81
|
+
"""The single preset that applies to this step's workflow, or ``None``. If more than one applies we return
|
|
82
|
+
``None`` (picking one silently would be dishonest — that is a preset-picker choice, not a default)."""
|
|
83
|
+
workflow = _PRESET_WORKFLOW.get(step_name)
|
|
84
|
+
if not workflow:
|
|
85
|
+
return None
|
|
86
|
+
try:
|
|
87
|
+
from pycat.utils.analysis_presets import presets_for
|
|
88
|
+
applicable = presets_for(workflow)
|
|
89
|
+
except Exception: # broad-ok: optional_probe — no preset registry → seed from defaults, not a crash
|
|
90
|
+
return None
|
|
91
|
+
return applicable[0] if len(applicable) == 1 else None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _seed_value(param: StepParam, preset, ctx):
|
|
95
|
+
"""Seed one parameter by the declared precedence: preset → session value → grounded default."""
|
|
96
|
+
if preset is not None and param.name in getattr(preset, "parameters", {}):
|
|
97
|
+
return _coerce(param, preset.parameters[param.name])
|
|
98
|
+
if ctx is not None:
|
|
99
|
+
try:
|
|
100
|
+
cv = ctx.get(param.name)
|
|
101
|
+
except Exception: # broad-ok: optional_probe — a non-mapping context just means no session value
|
|
102
|
+
cv = None
|
|
103
|
+
if cv is not None:
|
|
104
|
+
return _coerce(param, cv)
|
|
105
|
+
return param.default
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class ReviewedStep:
|
|
109
|
+
"""One step's reviewable parameters: seeded honestly, editable, tracking the deviation from the seed. The
|
|
110
|
+
populate-but-never-lock contract of :class:`PresetApplication`, generalised to also cover the no-preset
|
|
111
|
+
case (``preset_key`` is ``None`` then) — because provenance is owed whether or not a preset seeded it."""
|
|
112
|
+
|
|
113
|
+
def __init__(self, step_name: str, params, *, preset=None, ctx=None):
|
|
114
|
+
self.step_name = step_name
|
|
115
|
+
self.params = tuple(params)
|
|
116
|
+
self.preset = preset
|
|
117
|
+
self._seed = {p.name: _seed_value(p, preset, ctx) for p in self.params}
|
|
118
|
+
self.values = dict(self._seed)
|
|
119
|
+
self._modified: set = set()
|
|
120
|
+
|
|
121
|
+
def _param(self, name) -> Optional[StepParam]:
|
|
122
|
+
return next((p for p in self.params if p.name == name), None)
|
|
123
|
+
|
|
124
|
+
def set(self, name, value):
|
|
125
|
+
"""Set a value (coerced to its kind); mark it modified iff it differs from the seed. Setting it back to
|
|
126
|
+
the seeded value clears the modification — a result that matches the seed was not 'modified'."""
|
|
127
|
+
param = self._param(name)
|
|
128
|
+
if param is None:
|
|
129
|
+
return self
|
|
130
|
+
v = _coerce(param, value)
|
|
131
|
+
if self._seed.get(name) != v:
|
|
132
|
+
self._modified.add(name)
|
|
133
|
+
else:
|
|
134
|
+
self._modified.discard(name)
|
|
135
|
+
self.values[name] = v
|
|
136
|
+
return self
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def is_modified(self) -> bool:
|
|
140
|
+
return bool(self._modified)
|
|
141
|
+
|
|
142
|
+
def provenance(self) -> dict:
|
|
143
|
+
"""The recorded provenance — the exact :meth:`PresetApplication.record` shape, with ``preset_key``
|
|
144
|
+
``None`` when no preset seeded the step. Travels into the run report and a saved template."""
|
|
145
|
+
return {"preset_key": self.preset.key if self.preset is not None else None,
|
|
146
|
+
"modified_parameters": sorted(self._modified),
|
|
147
|
+
"is_modified": self.is_modified,
|
|
148
|
+
"parameters": dict(self.values)}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class ParamReview:
|
|
152
|
+
"""The reviewable parameter set for a whole plan — the adapter-covered, runnable steps that declare
|
|
153
|
+
material params, each a :class:`ReviewedStep`. The dock renders an editable form over it; the executor
|
|
154
|
+
reads :meth:`params_by_step` / :meth:`provenance_by_step`."""
|
|
155
|
+
|
|
156
|
+
def __init__(self, steps):
|
|
157
|
+
self.steps = list(steps)
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def is_empty(self) -> bool:
|
|
161
|
+
return not self.steps
|
|
162
|
+
|
|
163
|
+
def step(self, name) -> Optional[ReviewedStep]:
|
|
164
|
+
return next((s for s in self.steps if s.step_name == name), None)
|
|
165
|
+
|
|
166
|
+
def params_by_step(self) -> dict:
|
|
167
|
+
return {s.step_name: dict(s.values) for s in self.steps}
|
|
168
|
+
|
|
169
|
+
def provenance_by_step(self) -> dict:
|
|
170
|
+
return {s.step_name: s.provenance() for s in self.steps}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def build_param_review(plan, ctx=None) -> ParamReview:
|
|
174
|
+
"""Build the reviewable parameter set for ``plan``: one :class:`ReviewedStep` per adapter-covered step that
|
|
175
|
+
will actually run (``run`` / ``caveat`` in :func:`execution_order`) and declares material params, seeded by
|
|
176
|
+
the declared precedence. Blocked/skipped steps carry no review (they will not run). Never invents a
|
|
177
|
+
parameter — a step with no declared material params contributes nothing to review."""
|
|
178
|
+
reviewed = []
|
|
179
|
+
try:
|
|
180
|
+
order = execution_order(plan)
|
|
181
|
+
except Exception: # broad-ok: optional_probe — an un-orderable plan yields an empty review, not a crash
|
|
182
|
+
order = []
|
|
183
|
+
for es in order:
|
|
184
|
+
if es.status not in ("run", "caveat"):
|
|
185
|
+
continue
|
|
186
|
+
if not has_adapter(es.name):
|
|
187
|
+
continue
|
|
188
|
+
params = material_params(es.name)
|
|
189
|
+
if not params:
|
|
190
|
+
continue
|
|
191
|
+
reviewed.append(ReviewedStep(es.name, params, preset=_applicable_preset(es.name), ctx=ctx))
|
|
192
|
+
return ParamReview(reviewed)
|
|
@@ -128,17 +128,25 @@ def _render_observations(widget, body_layout):
|
|
|
128
128
|
"color: gray; font-size: 10px; margin-bottom: 4px;"))
|
|
129
129
|
|
|
130
130
|
|
|
131
|
-
def run_plan_via_central_manager(central_manager, plan):
|
|
131
|
+
def run_plan_via_central_manager(central_manager, plan, review=None):
|
|
132
132
|
"""Execute a compiled plan against the session's data through the execution-adapter layer, and report
|
|
133
133
|
per-step outcomes. Adapter-covered steps run through the batch handlers (the proven 'same computation'
|
|
134
|
-
route); a step with no adapter yet is reported as 'run from its
|
|
135
|
-
|
|
134
|
+
route) with the user-reviewed parameters (Phase 2); a step with no adapter yet is reported as 'run from its
|
|
135
|
+
panel' — never invoked with guessed args. ``review`` is the :class:`ParamReview` the dock built from its
|
|
136
|
+
editable form; when ``None`` (a programmatic run), one is built from the plan so parameters are still
|
|
137
|
+
preset/default-seeded and provenance is still recorded. Safe on an uncovered plan (nothing runs);
|
|
138
|
+
best-effort, never crashes the UI. This is the wired ``on_run``."""
|
|
136
139
|
try:
|
|
137
140
|
from pycat.navigator.executor import run_plan
|
|
138
141
|
dr = getattr(getattr(central_manager, "active_data_class", None), "data_repository", None)
|
|
139
142
|
if dr is None:
|
|
140
143
|
return
|
|
141
|
-
|
|
144
|
+
if review is None:
|
|
145
|
+
from pycat.navigator.parameters import build_param_review
|
|
146
|
+
review = build_param_review(plan, ctx=dr)
|
|
147
|
+
report = run_plan(plan, dr, ctx=dr,
|
|
148
|
+
params_by_step=review.params_by_step(),
|
|
149
|
+
provenance_by_step=review.provenance_by_step())
|
|
142
150
|
ran = [s.name for s in report.ran]
|
|
143
151
|
panel = [s.name for s in report.needs_panel]
|
|
144
152
|
blocked = [s for s in report.steps if s.outcome == "blocked"]
|
|
@@ -149,6 +157,9 @@ def run_plan_via_central_manager(central_manager, plan):
|
|
|
149
157
|
parts.append(f"Stopped at {blocked[0].name} — {blocked[0].detail}")
|
|
150
158
|
if panel:
|
|
151
159
|
parts.append("Run these from their method panels, in order: " + ", ".join(panel) + ".")
|
|
160
|
+
modified = [s.name for s in report.ran if s.provenance.get("is_modified")]
|
|
161
|
+
if modified:
|
|
162
|
+
parts.append("Parameters modified for: " + ", ".join(modified) + ".")
|
|
152
163
|
from napari.utils.notifications import show_info
|
|
153
164
|
show_info(" ".join(parts) or "Nothing to run.")
|
|
154
165
|
except Exception as exc: # broad-ok: ui_cleanup — a run attempt must never crash the guided panel
|
|
@@ -199,6 +210,68 @@ def _add_template_save(widget, body_layout):
|
|
|
199
210
|
body_layout.addWidget(btn)
|
|
200
211
|
|
|
201
212
|
|
|
213
|
+
def _param_input(param, value, on_change):
|
|
214
|
+
"""One editable control for a material parameter, seeded at ``value``; ``on_change(new_value)`` fires on
|
|
215
|
+
edit. int → spin box, float → double spin, choice → combo. Returns the widget (or ``None`` on an odd kind)."""
|
|
216
|
+
from PyQt5.QtWidgets import QSpinBox, QDoubleSpinBox, QComboBox
|
|
217
|
+
if param.kind == "int":
|
|
218
|
+
w = QSpinBox()
|
|
219
|
+
w.setMinimum(int(param.minimum) if param.minimum is not None else 0)
|
|
220
|
+
w.setMaximum(int(param.maximum) if param.maximum is not None else 100000)
|
|
221
|
+
w.setValue(int(value))
|
|
222
|
+
w.valueChanged.connect(lambda v: on_change(v))
|
|
223
|
+
return w
|
|
224
|
+
if param.kind == "float":
|
|
225
|
+
w = QDoubleSpinBox()
|
|
226
|
+
w.setDecimals(3)
|
|
227
|
+
w.setMinimum(float(param.minimum) if param.minimum is not None else 0.0)
|
|
228
|
+
w.setMaximum(float(param.maximum) if param.maximum is not None else 1e9)
|
|
229
|
+
w.setValue(float(value))
|
|
230
|
+
w.valueChanged.connect(lambda v: on_change(v))
|
|
231
|
+
return w
|
|
232
|
+
if param.kind == "choice":
|
|
233
|
+
w = QComboBox()
|
|
234
|
+
w.addItems([str(c) for c in param.choices])
|
|
235
|
+
if str(value) in [str(c) for c in param.choices]:
|
|
236
|
+
w.setCurrentText(str(value))
|
|
237
|
+
w.currentTextChanged.connect(lambda v: on_change(v))
|
|
238
|
+
return w
|
|
239
|
+
return None
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def _add_param_review(widget, body_layout, plan):
|
|
243
|
+
"""Render the editable parameter-review form (Phase 2) and stash the :class:`ParamReview` on the widget as
|
|
244
|
+
``_review`` for the run. Surfaces the handful of material parameters per adapter-covered step, seeded from a
|
|
245
|
+
preset/session value/grounded default (never invented); an edit is tracked so the run records provenance.
|
|
246
|
+
Renders nothing when no adapter-covered step has material params — the honest 'nothing to review' case."""
|
|
247
|
+
from PyQt5.QtWidgets import QFrame, QVBoxLayout, QHBoxLayout
|
|
248
|
+
from pycat.navigator.parameters import build_param_review, material_params
|
|
249
|
+
try:
|
|
250
|
+
review = build_param_review(plan, ctx=widget._session.ctx)
|
|
251
|
+
except Exception: # broad-ok: ui_cleanup — a review failure must not break the plan view
|
|
252
|
+
review = None
|
|
253
|
+
widget._review = review
|
|
254
|
+
if review is None or review.is_empty:
|
|
255
|
+
return
|
|
256
|
+
body_layout.addWidget(_label("⚙ Review parameters", "font-weight: bold; font-size: 12px; margin-top: 6px;"))
|
|
257
|
+
body_layout.addWidget(_label("Seeded from your data and grounded defaults — edit before running.",
|
|
258
|
+
"color: gray; font-size: 10px;"))
|
|
259
|
+
for step in review.steps:
|
|
260
|
+
body_layout.addWidget(_label(step.step_name, "font-weight: bold; font-size: 11px; color: #2a7ab0;"))
|
|
261
|
+
for param in material_params(step.step_name):
|
|
262
|
+
frame = QFrame()
|
|
263
|
+
row = QHBoxLayout(frame)
|
|
264
|
+
row.setContentsMargins(0, 0, 0, 0)
|
|
265
|
+
row.addWidget(_label(param.label, "font-size: 11px;"))
|
|
266
|
+
inp = _param_input(param, step.values.get(param.name, param.default),
|
|
267
|
+
lambda v, s=step, n=param.name: s.set(n, v))
|
|
268
|
+
if inp is not None:
|
|
269
|
+
if param.help:
|
|
270
|
+
inp.setToolTip(param.help)
|
|
271
|
+
row.addWidget(inp)
|
|
272
|
+
body_layout.addWidget(frame)
|
|
273
|
+
|
|
274
|
+
|
|
202
275
|
def build_navigator_widget(session, *, on_run=None, central_manager=None, parent=None):
|
|
203
276
|
"""Build (do not mount) the Navigator widget over ``session``, or return ``None`` if Qt is unavailable
|
|
204
277
|
(headless). ``on_run(plan)`` is called when the user runs the compiled plan. When ``central_manager`` is
|
|
@@ -235,6 +308,7 @@ def build_navigator_widget(session, *, on_run=None, central_manager=None, parent
|
|
|
235
308
|
widget._rows = []
|
|
236
309
|
widget._choice_buttons = []
|
|
237
310
|
widget._run_button = None
|
|
311
|
+
widget._review = None # Phase 2: the ParamReview built at plan render, passed to the run
|
|
238
312
|
widget._regate_only = False # a viewer event re-gates; answering/restart recompiles
|
|
239
313
|
widget._reeval_pending = False
|
|
240
314
|
|
|
@@ -267,6 +341,7 @@ def build_navigator_widget(session, *, on_run=None, central_manager=None, parent
|
|
|
267
341
|
body_layout.addWidget(_label(_PLAN_LEGEND, "color: gray; font-size: 10px; margin-bottom: 4px;"))
|
|
268
342
|
for row in widget._rows:
|
|
269
343
|
body_layout.addWidget(_row_frame(row))
|
|
344
|
+
_add_param_review(widget, body_layout, plan) # Phase 2: the editable, seeded material params
|
|
270
345
|
run = QPushButton("▶ Run analysis")
|
|
271
346
|
reason = widget._session.run_blocked_reason()
|
|
272
347
|
run.setEnabled(reason is None and callable(widget._on_run))
|
|
@@ -289,7 +364,11 @@ def build_navigator_widget(session, *, on_run=None, central_manager=None, parent
|
|
|
289
364
|
|
|
290
365
|
def _run():
|
|
291
366
|
if callable(widget._on_run) and widget._plan is not None:
|
|
292
|
-
|
|
367
|
+
review = getattr(widget, "_review", None)
|
|
368
|
+
try:
|
|
369
|
+
widget._on_run(widget._plan, review) # Phase 2: pass the reviewed params
|
|
370
|
+
except TypeError:
|
|
371
|
+
widget._on_run(widget._plan) # a 1-arg on_run (older callers) still works
|
|
293
372
|
|
|
294
373
|
def _restart():
|
|
295
374
|
widget._session = NavigatorSession()
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
{pycat_napari-1.6.332 → pycat_napari-1.6.333}/src/pycat/file_io/readers/stack_layer_builders.py
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|