pycat-napari 1.6.331__tar.gz → 1.6.332__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.
Files changed (323) hide show
  1. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/CHANGELOG.md +22 -0
  2. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/PKG-INFO +1 -1
  3. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/pyproject.toml +1 -1
  4. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/central_manager.py +6 -3
  5. pycat_napari-1.6.332/src/pycat/navigator/executor.py +163 -0
  6. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/navigator_dock.py +28 -0
  7. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/.gitignore +0 -0
  8. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/CONTRIBUTING.md +0 -0
  9. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/LICENSE +0 -0
  10. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/README.md +0 -0
  11. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/THIRD_PARTY_LICENSES.txt +0 -0
  12. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/benchmarks/README.md +0 -0
  13. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/config/README.md +0 -0
  14. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/config/requirements-arm-mac.txt +0 -0
  15. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/config/requirements-base.txt +0 -0
  16. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/config/requirements-devbio-napari-arm-mac.txt +0 -0
  17. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/config/requirements-devbio-napari.txt +0 -0
  18. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/__init__.py +0 -0
  19. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/batch/__init__.py +0 -0
  20. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/batch/steps/__init__.py +0 -0
  21. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/batch/steps/_common.py +0 -0
  22. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/batch/steps/analysis_steps.py +0 -0
  23. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/batch/steps/brightfield_steps.py +0 -0
  24. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/batch/steps/invitro_steps.py +0 -0
  25. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/batch/steps/io_steps.py +0 -0
  26. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/batch/steps/preprocessing_steps.py +0 -0
  27. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/batch/steps/segmentation_steps.py +0 -0
  28. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/batch_processor.py +0 -0
  29. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/batch_step_registry.py +0 -0
  30. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/data/__init__.py +0 -0
  31. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/data/data_modules.py +0 -0
  32. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/__init__.py +0 -0
  33. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/czi_seam.py +0 -0
  34. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/dialogs.py +0 -0
  35. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/file_io.py +0 -0
  36. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/frap_io.py +0 -0
  37. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/image_reader.py +0 -0
  38. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/image_source.py +0 -0
  39. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/image_structure.py +0 -0
  40. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/lazy_guard.py +0 -0
  41. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/lazy_sources.py +0 -0
  42. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/load_channel_identity.py +0 -0
  43. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/local_cache.py +0 -0
  44. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/metadata_extract.py +0 -0
  45. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/multidim_io.py +0 -0
  46. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/naming.py +0 -0
  47. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/napari_adapter.py +0 -0
  48. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/readers/__init__.py +0 -0
  49. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/readers/czi_bioformats.py +0 -0
  50. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/readers/image_reader_2d.py +0 -0
  51. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/readers/ims_reader.py +0 -0
  52. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/readers/mask_reader.py +0 -0
  53. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/readers/stack_layer_builders.py +0 -0
  54. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/readers/stack_metadata.py +0 -0
  55. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/routing.py +0 -0
  56. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/scenes.py +0 -0
  57. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/session.py +0 -0
  58. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/session_loader.py +0 -0
  59. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/session_manifest.py +0 -0
  60. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/sidecar_discovery.py +0 -0
  61. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/stack_access.py +0 -0
  62. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/stack_load.py +0 -0
  63. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/stack_openers.py +0 -0
  64. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/storage_probe.py +0 -0
  65. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/tagging.py +0 -0
  66. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/tiff_planes.py +0 -0
  67. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/tifffile_zarr_shim.py +0 -0
  68. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/viewer_load.py +0 -0
  69. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/writers.py +0 -0
  70. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/file_io/zarr_compat.py +0 -0
  71. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/fix_tifffile.py +0 -0
  72. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/icons/pycat_logo_512.png +0 -0
  73. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/icons/pycat_mark.png +0 -0
  74. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/__init__.py +0 -0
  75. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/adapters.py +0 -0
  76. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/canonical.py +0 -0
  77. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/capabilities.py +0 -0
  78. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/context.py +0 -0
  79. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/contracts.py +0 -0
  80. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/data/PyCAT_layer_tag_hierarchy_and_module_flow.xlsx +0 -0
  81. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/data/PyCAT_module_information_contracts.xlsx +0 -0
  82. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/data/PyCAT_question_tree_and_method_mapping.xlsx +0 -0
  83. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/data/operation_catalog.json +0 -0
  84. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/execution.py +0 -0
  85. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/gates.py +0 -0
  86. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/loader.py +0 -0
  87. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/modules.py +0 -0
  88. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/op_catalog.py +0 -0
  89. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/operation_spec.py +0 -0
  90. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/planner.py +0 -0
  91. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/quality_gates.py +0 -0
  92. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/question_engine.py +0 -0
  93. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/registry.py +0 -0
  94. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/scientific_tree.py +0 -0
  95. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/session.py +0 -0
  96. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/tags.py +0 -0
  97. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/navigator/templates.py +0 -0
  98. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/run_pycat.py +0 -0
  99. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/__init__.py +0 -0
  100. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/advanced_analysis_ui.py +0 -0
  101. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/analysis_plots.py +0 -0
  102. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/batch_roi_tools.py +0 -0
  103. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/benchmark_tools.py +0 -0
  104. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/biological_qc_tools.py +0 -0
  105. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/brightfield_tools.py +0 -0
  106. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/brightfield_ui.py +0 -0
  107. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/clean_spot_detection_tools.py +0 -0
  108. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/condensate_modes.py +0 -0
  109. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/condensate_physics/__init__.py +0 -0
  110. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/condensate_physics/coarsening.py +0 -0
  111. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/condensate_physics/frame_quality.py +0 -0
  112. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/condensate_physics/intensity.py +0 -0
  113. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/condensate_physics/moduli.py +0 -0
  114. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/condensate_physics/msd.py +0 -0
  115. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/condensate_physics/photobleaching.py +0 -0
  116. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/condensate_physics/relaxation.py +0 -0
  117. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/condensate_physics/survival.py +0 -0
  118. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/condensate_physics_tools.py +0 -0
  119. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/condensate_physics_ui.py +0 -0
  120. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/contrast_cascade_tools.py +0 -0
  121. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/contrast_cascade_ui.py +0 -0
  122. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/control_validation.py +0 -0
  123. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/correlation_func_analysis_tools.py +0 -0
  124. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/data_qc_tools.py +0 -0
  125. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/data_qc_ui.py +0 -0
  126. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/data_viz_tools.py +0 -0
  127. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/drawing_layers.py +0 -0
  128. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/dynamic_spatial_tools.py +0 -0
  129. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/fd_curve_tools.py +0 -0
  130. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/fd_curve_ui.py +0 -0
  131. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/feature_analysis_tools.py +0 -0
  132. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/feature_redundancy.py +0 -0
  133. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/fft_bandpass_tools.py +0 -0
  134. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/fibril_tools.py +0 -0
  135. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/fibril_ui.py +0 -0
  136. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/frap_tools.py +0 -0
  137. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/frap_ui.py +0 -0
  138. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/fusion_tools.py +0 -0
  139. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/fusion_ui.py +0 -0
  140. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/gaussian_localization_tools.py +0 -0
  141. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/general_image_tools.py +0 -0
  142. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/gpu_utils.py +0 -0
  143. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/image_processing/__init__.py +0 -0
  144. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/image_processing/_base.py +0 -0
  145. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/image_processing/background.py +0 -0
  146. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/image_processing/deblur.py +0 -0
  147. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/image_processing/filters.py +0 -0
  148. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/image_processing/preprocessing.py +0 -0
  149. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/image_processing/size_estimation.py +0 -0
  150. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/image_processing/upscaling.py +0 -0
  151. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/image_processing_tools.py +0 -0
  152. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/intensity_profile_tools.py +0 -0
  153. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/invitro/__init__.py +0 -0
  154. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/invitro/analysis.py +0 -0
  155. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/invitro/field_summary.py +0 -0
  156. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/invitro/partition.py +0 -0
  157. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/invitro/size_distribution.py +0 -0
  158. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/invitro_bf_ui.py +0 -0
  159. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/invitro_fluor_ui.py +0 -0
  160. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/invitro_tools.py +0 -0
  161. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/kymograph_tools.py +0 -0
  162. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/label_and_mask_tools.py +0 -0
  163. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/layer_tools.py +0 -0
  164. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/measurement_stability.py +0 -0
  165. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/molecular_counting_tools.py +0 -0
  166. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/morphological_complexity_tools.py +0 -0
  167. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/nb_tools.py +0 -0
  168. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/nb_ui.py +0 -0
  169. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/numba_utils.py +0 -0
  170. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/obj_based_coloc_analysis_tools.py +0 -0
  171. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/organizational_metrics_tools.py +0 -0
  172. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/partial_volume_tools.py +0 -0
  173. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/partition_enrichment_tools.py +0 -0
  174. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/pipeline_diagnostic_tools.py +0 -0
  175. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/pipeline_snr_tools.py +0 -0
  176. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/pixel_wise_corr_analysis_tools.py +0 -0
  177. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/qc_gallery.py +0 -0
  178. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/qc_gallery_ui.py +0 -0
  179. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/ratiometric_tools.py +0 -0
  180. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/scan_qc_tools.py +0 -0
  181. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/segmentation/__init__.py +0 -0
  182. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/segmentation/_common.py +0 -0
  183. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/segmentation/cellpose.py +0 -0
  184. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/segmentation/fz.py +0 -0
  185. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/segmentation/intensity.py +0 -0
  186. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/segmentation/local_thresholding.py +0 -0
  187. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/segmentation/morphology.py +0 -0
  188. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/segmentation/puncta_refinement.py +0 -0
  189. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/segmentation/subcellular.py +0 -0
  190. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/segmentation/watershed.py +0 -0
  191. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/segmentation_scale_advisor.py +0 -0
  192. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/segmentation_tools.py +0 -0
  193. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/smlm_tools.py +0 -0
  194. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/spatial_acf_tools.py +0 -0
  195. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/spatial_metrology_tools.py +0 -0
  196. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/spatial_metrology_ui.py +0 -0
  197. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/spatial_randomness_tools.py +0 -0
  198. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/spida_tools.py +0 -0
  199. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/spida_ui.py +0 -0
  200. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/temperature_tools.py +0 -0
  201. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/temperature_ui.py +0 -0
  202. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/temporal_enhancement_tools.py +0 -0
  203. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/timeseries/__init__.py +0 -0
  204. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/timeseries/analysis.py +0 -0
  205. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/timeseries/correlation.py +0 -0
  206. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/timeseries/execution.py +0 -0
  207. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/timeseries/frame_access.py +0 -0
  208. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/timeseries/preprocessing.py +0 -0
  209. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/timeseries/ui.py +0 -0
  210. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/timeseries_condensate_tools.py +0 -0
  211. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/timeseries_invitro_fluor_ui.py +0 -0
  212. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/timeseries_invitro_tools.py +0 -0
  213. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/topology_tools.py +0 -0
  214. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/trackmate_bridge.py +0 -0
  215. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/ts_cache_manager.py +0 -0
  216. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/ts_cellpose_tools.py +0 -0
  217. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/two_channel_coloc_tools.py +0 -0
  218. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/unmixing_tools.py +0 -0
  219. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/video_export_tools.py +0 -0
  220. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt/__init__.py +0 -0
  221. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt/analysis.py +0 -0
  222. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt/detection.py +0 -0
  223. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt/drift.py +0 -0
  224. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt/host.py +0 -0
  225. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt/msd_adapter.py +0 -0
  226. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt/napari_adapter.py +0 -0
  227. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt/panels.py +0 -0
  228. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt/populations.py +0 -0
  229. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt/results_dock.py +0 -0
  230. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt/table_adapter.py +0 -0
  231. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt/viscosity.py +0 -0
  232. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt_tools.py +0 -0
  233. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/vpt_ui.py +0 -0
  234. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/zstack_segmentation_tools.py +0 -0
  235. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/toolbox/zstack_segmentation_ui.py +0 -0
  236. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/__init__.py +0 -0
  237. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/brushable_table.py +0 -0
  238. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/brushable_workspace.py +0 -0
  239. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/channel_identity_dialog.py +0 -0
  240. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/comparative_figures_ui.py +0 -0
  241. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/coordinate_readout.py +0 -0
  242. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/feature_explorer_dock.py +0 -0
  243. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/field_status.py +0 -0
  244. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/home_dock.py +0 -0
  245. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/linked_selection_dock.py +0 -0
  246. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/menu_manager.py +0 -0
  247. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/metadata_contradiction_panel.py +0 -0
  248. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/operation_gating.py +0 -0
  249. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/preferences_dialog.py +0 -0
  250. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/preset_picker.py +0 -0
  251. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/scene_switcher.py +0 -0
  252. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/ui_analysis_mixin.py +0 -0
  253. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/ui_diagnostics_mixin.py +0 -0
  254. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/ui_filtering_mixin.py +0 -0
  255. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/ui_imageops_mixin.py +0 -0
  256. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/ui_labels_mixin.py +0 -0
  257. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/ui_modules.py +0 -0
  258. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/ui_segmentation_mixin.py +0 -0
  259. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/ui_utils.py +0 -0
  260. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/ui/workflow_checklist.py +0 -0
  261. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/__init__.py +0 -0
  262. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/analysis_presets.py +0 -0
  263. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/app_mode.py +0 -0
  264. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/batch_brushing.py +0 -0
  265. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/brushing.py +0 -0
  266. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/calibration.py +0 -0
  267. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/channel_designations.py +0 -0
  268. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/channel_modality.py +0 -0
  269. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/channel_naming.py +0 -0
  270. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/cohort_targets.py +0 -0
  271. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/comparative_figures.py +0 -0
  272. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/comparative_stats.py +0 -0
  273. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/consolidated_table.py +0 -0
  274. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/dataset_identity.py +0 -0
  275. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/dock_space.py +0 -0
  276. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/entity_ref.py +0 -0
  277. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/entity_registry.py +0 -0
  278. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/environment_check.py +0 -0
  279. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/errors.py +0 -0
  280. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/feature_cards.py +0 -0
  281. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/feature_explorer.py +0 -0
  282. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/feature_families.py +0 -0
  283. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/feature_provenance.py +0 -0
  284. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/feature_registry.py +0 -0
  285. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/field_registry_hub.py +0 -0
  286. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/figure_refine.py +0 -0
  287. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/figure_spec.py +0 -0
  288. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/filter_store.py +0 -0
  289. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/fit_quality.py +0 -0
  290. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/frame_interval.py +0 -0
  291. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/general_utils.py +0 -0
  292. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/intensity_semantics.py +0 -0
  293. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/layer_bindings.json +0 -0
  294. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/layer_tag_hook.py +0 -0
  295. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/layer_tags.py +0 -0
  296. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/logging_utils.py +0 -0
  297. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/marker_logic.py +0 -0
  298. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/math_utils.py +0 -0
  299. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/measurement.py +0 -0
  300. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/measurement_ontology.py +0 -0
  301. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/metadata_contradictions.py +0 -0
  302. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/metadata_validity.py +0 -0
  303. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/notify.py +0 -0
  304. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/object_graph.py +0 -0
  305. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/object_ref.py +0 -0
  306. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/operation_runner.py +0 -0
  307. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/pixel_size.py +0 -0
  308. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/plot_backend_pyqtgraph.py +0 -0
  309. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/plot_backend_selection.py +0 -0
  310. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/plot_backends.py +0 -0
  311. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/preferences.py +0 -0
  312. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/qt_worker.py +0 -0
  313. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/quality_gate.py +0 -0
  314. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/reliability.py +0 -0
  315. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/result_models.py +0 -0
  316. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/results_store.py +0 -0
  317. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/sample_metadata.py +0 -0
  318. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/selection_overlay.py +0 -0
  319. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/selection_service.py +0 -0
  320. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/tag_registry.py +0 -0
  321. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/tag_resolver.py +0 -0
  322. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/src/pycat/utils/user_settings.py +0 -0
  323. {pycat_napari-1.6.331 → pycat_napari-1.6.332}/tests/README.md +0 -0
@@ -1,3 +1,25 @@
1
+ ## [1.6.332] - 2026-07-24
2
+ ### Added — **Navigator execution-adapter layer, Phase 1: "Run analysis" computes a plan through the batch handlers, gate-respecting (guided == batch == manual).**
3
+ `selection_scale` Part 2 established there is no uniform "run this op" — but the batch `_STEP_MAP` handlers ARE
4
+ the proven "same computation" route (uniform `(state, image_path, params, output_dir)`; `test_route_equivalence`
5
+ asserts batch == manual). This ships the executor that drives them:
6
+ - New Qt-free **`navigator/executor.py`**: `run_plan(plan, state, …)` executes a compiled plan by driving the
7
+ batch handlers in the gate-respecting order (`execution.execution_order`), threading each step's output
8
+ through a shared `state` as a batch replay does. An `ExecAdapter` maps a plan step to a batch handler and
9
+ derives its params; **a step with no adapter is reported ('needs_panel'), never invoked with guessed
10
+ arguments** — the whole point of an adapter layer over a generic `fn(image)` (which would produce wrong
11
+ science silently). Gate semantics are READ from `execution_order`: a blocker halts the run (state untouched),
12
+ a caveat runs with its reason, probes first.
13
+ - **One proven adapter (`background_removal`)** — the shortest chain `test_route_equivalence` covers — so the
14
+ acceptance gate is pinned: `tests/navigator/test_navigator_executor.py` (`base`, 5) asserts **guided == batch
15
+ == manual, bit for bit**, plus a blocker halts + leaves state untouched, a caveat runs, and an uncovered step
16
+ is reported not invoked.
17
+ - **The Run button is wired** (`run_plan_via_central_manager`, passed as `on_run` from `central_manager`):
18
+ adapter-covered steps run through the batch handlers; uncovered steps are reported "run these from their
19
+ method panels, in order". Safe on an uncovered plan (nothing runs); best-effort.
20
+ - **Later phases** (per the `navigator_execution_adapters` spec): a parameter-review panel, more adapters one
21
+ workflow at a time (each behind its own route-equivalence test), and dock progress/cancel.
22
+
1
23
  ## [1.6.331] - 2026-07-24
2
24
  ### Added — **Save an answered guided plan as a reusable method template (selection_scale Part 3).**
3
25
  The navigator's payoff: a plan the user likes should be reusable on other data without re-answering. A guided
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycat-napari
3
- Version: 1.6.331
3
+ Version: 1.6.332
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.331"
7
+ version = "1.6.332"
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).
@@ -119,9 +119,12 @@ class CentralManager:
119
119
  getattr(self.menu_manager, 'file_menu', None),
120
120
  getattr(getattr(self.viewer, 'window', None), '_qt_window', None))
121
121
  # Navigator: guided-analysis dock (question flow -> quality-gated, editable plan). Entry point here,
122
- # not the line-capped menu god-file. on_run is left None until the plan-execution bridge lands.
123
- from pycat.ui.navigator_dock import install_navigator_action
124
- self._navigator_action = install_navigator_action(self.viewer, central_manager=self)
122
+ # not the line-capped menu god-file. Run analysis is wired through the execution-adapter layer (Phase
123
+ # 1): adapter-covered steps run via the batch handlers, the rest are reported "run from your panel".
124
+ from pycat.ui.navigator_dock import install_navigator_action, run_plan_via_central_manager
125
+ self._navigator_action = install_navigator_action(
126
+ self.viewer, central_manager=self,
127
+ on_run=lambda plan: run_plan_via_central_manager(self, plan))
125
128
  # Populate the feature registry so any consumer (the beginner home dock, a capability query) sees
126
129
  # every surfaced-but-otherwise-hidden feature (navigator inc 4). Guarded: a registration hiccup must
127
130
  # never break startup, and the cards' openers import Qt/toolbox lazily so this stays cheap.
@@ -0,0 +1,163 @@
1
+ """**Execute a compiled navigator plan by driving the BATCH step handlers** (execution-adapter layer, Phase 1).
2
+
3
+ `selection_scale` Part 2 established there is no uniform "run this op" — PyCAT operations have bespoke,
4
+ panel-collected signatures. But the **batch `_STEP_MAP` handlers** are the proven "same computation" route:
5
+ they share one signature — ``(state, image_path, params, output_dir)`` — and `test_route_equivalence` already
6
+ asserts they compute byte-identically to the manual GUI route. So the executor drives *those* handlers, in the
7
+ gate-respecting order (`execution.execution_order`), threading each step's output through a shared ``state``
8
+ dict exactly as a batch replay does.
9
+
10
+ The narrow bridge is per-step: an :class:`ExecAdapter` maps a plan step to a batch handler and derives that
11
+ handler's ``params`` from the answers. A plan step with **no adapter is reported** ("run it from its method
12
+ panel"), never invoked with guessed arguments — a `fn(image)` fallback would pass wrong args and produce wrong
13
+ science silently, which is the whole reason this is an adapter layer and not a loop over ``resolve_operation``.
14
+
15
+ Phase 1 ships the executor + registry + ONE proven adapter (``background_removal`` — the shortest chain
16
+ `test_route_equivalence` already covers), so `guided == batch == manual` is pinned; later phases add adapters
17
+ one workflow at a time, each earning its place with a route-equivalence test. Qt-free; a runner is optional
18
+ (off-thread when given, synchronous otherwise)."""
19
+ from __future__ import annotations
20
+
21
+ import dataclasses
22
+ import pathlib
23
+ import tempfile
24
+ from typing import Callable, Optional
25
+
26
+ from .execution import execution_order
27
+
28
+
29
+ @dataclasses.dataclass(frozen=True)
30
+ class ExecAdapter:
31
+ """Bridges ONE plan step to the batch handler that computes it. ``params_from(intent, ctx, state)`` derives
32
+ the handler's ``params`` from the answers (Phase 1: grounded defaults; a preset seed lands in Phase 2)."""
33
+ plan_step: str
34
+ batch_step: str
35
+ params_from: Callable
36
+
37
+
38
+ def _background_removal_params(intent, ctx, state):
39
+ radius = None
40
+ try:
41
+ radius = ctx.get("ball_radius") if ctx is not None else None
42
+ except Exception: # broad-ok: optional_probe — a context miss falls back to the grounded default
43
+ radius = None
44
+ return {"ball_radius": int(radius) if radius else 50, "active_layer": "segmentation image"}
45
+
46
+
47
+ #: The declared adapters. The ONLY place a plan step is tied to a computation — a step absent here is reported
48
+ #: as "run from its panel", never guessed at. Grows one workflow per phase (each behind a route-equivalence test).
49
+ _ADAPTERS: dict = {
50
+ "background_removal": ExecAdapter("background_removal", "background_removal", _background_removal_params),
51
+ }
52
+
53
+
54
+ def has_adapter(step_name: str) -> bool:
55
+ return step_name in _ADAPTERS
56
+
57
+
58
+ @dataclasses.dataclass(frozen=True)
59
+ class StepOutcome:
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'``."""
62
+ name: str
63
+ outcome: str
64
+ detail: str = ""
65
+
66
+
67
+ @dataclasses.dataclass
68
+ class ExecReport:
69
+ steps: list = dataclasses.field(default_factory=list)
70
+
71
+ @property
72
+ def ran(self) -> list:
73
+ return [s for s in self.steps if s.outcome.startswith("ran")]
74
+
75
+ @property
76
+ def stopped(self) -> bool:
77
+ return any(s.outcome in ("blocked", "error") for s in self.steps)
78
+
79
+ @property
80
+ def needs_panel(self) -> list:
81
+ return [s for s in self.steps if s.outcome == "needs_panel"]
82
+
83
+
84
+ def _build_step_registry() -> dict:
85
+ """The production batch step registry (name → replay handler), built the way `BatchProcessor` does. Only
86
+ the import-clean `batch_step_registry` is touched (no Qt)."""
87
+ registry: dict = {}
88
+
89
+ class _Recorder:
90
+ def register_step(self, name, fn):
91
+ registry[name] = fn
92
+
93
+ from pycat.batch_step_registry import register_all_steps
94
+ register_all_steps(_Recorder())
95
+ return registry
96
+
97
+
98
+ def run_plan(plan, state, *, intent=None, ctx=None, image_path=None, output_dir=None, runner=None,
99
+ on_step: Optional[Callable] = None) -> ExecReport:
100
+ """Execute ``plan``'s steps in gate order by driving the batch handlers, threading ``state`` (a dict the
101
+ handlers read/write, exactly as a batch replay). Returns an :class:`ExecReport`.
102
+
103
+ Gate semantics are READ from :func:`execution.execution_order`, never re-decided: a **blocker** stops the
104
+ run at that step (nothing after it runs); a **caveat** runs with the caveat recorded; **probes** run first.
105
+ A step with no :class:`ExecAdapter` is reported ``'needs_panel'`` — never invoked with guessed arguments.
106
+ 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)."""
108
+ intent = intent if intent is not None else getattr(plan, "intent", None)
109
+ registry = _build_step_registry()
110
+ report = ExecReport()
111
+
112
+ tmp = None
113
+ if output_dir is None:
114
+ tmp = tempfile.TemporaryDirectory()
115
+ output_dir = pathlib.Path(tmp.name)
116
+ if image_path is None:
117
+ image_path = pathlib.Path(output_dir) / "sample.tif"
118
+
119
+ try:
120
+ halted = False
121
+ for es in execution_order(plan):
122
+ if halted or es.status == "skipped":
123
+ report.steps.append(StepOutcome(es.name, "skipped", es.reason))
124
+ continue
125
+ if es.status == "blocked":
126
+ report.steps.append(StepOutcome(es.name, "blocked", es.reason))
127
+ halted = True
128
+ continue
129
+
130
+ adapter = _ADAPTERS.get(es.name)
131
+ if adapter is None:
132
+ report.steps.append(StepOutcome(
133
+ es.name, "needs_panel", "no execution adapter yet — run this step from its method panel"))
134
+ if on_step:
135
+ on_step(report.steps[-1])
136
+ continue
137
+
138
+ fn = registry.get(adapter.batch_step)
139
+ if fn is None:
140
+ report.steps.append(StepOutcome(es.name, "error",
141
+ f"batch step {adapter.batch_step!r} is not registered"))
142
+ halted = True
143
+ continue
144
+
145
+ params = adapter.params_from(intent, ctx, state)
146
+ try:
147
+ if runner is not None:
148
+ runner.execute(fn, state, image_path, params, output_dir)
149
+ else:
150
+ fn(state, image_path, params, output_dir)
151
+ except Exception as exc: # broad-ok: scientific_result — a failed step halts; report it, never silently continue on stale state
152
+ report.steps.append(StepOutcome(es.name, "error", f"{type(exc).__name__}: {exc}"))
153
+ halted = True
154
+ continue
155
+
156
+ report.steps.append(StepOutcome(
157
+ es.name, "ran_with_caveat" if es.status == "caveat" else "ran", es.reason))
158
+ if on_step:
159
+ on_step(report.steps[-1])
160
+ finally:
161
+ if tmp is not None:
162
+ tmp.cleanup()
163
+ return report
@@ -128,6 +128,34 @@ 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):
132
+ """Execute a compiled plan against the session's data through the execution-adapter layer, and report
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 panel' — never invoked with guessed args.
135
+ Safe on an uncovered plan (nothing runs); best-effort, never crashes the UI. This is the wired ``on_run``."""
136
+ try:
137
+ from pycat.navigator.executor import run_plan
138
+ dr = getattr(getattr(central_manager, "active_data_class", None), "data_repository", None)
139
+ if dr is None:
140
+ return
141
+ report = run_plan(plan, dr, ctx=dr)
142
+ ran = [s.name for s in report.ran]
143
+ panel = [s.name for s in report.needs_panel]
144
+ blocked = [s for s in report.steps if s.outcome == "blocked"]
145
+ parts = []
146
+ if ran:
147
+ parts.append("Ran: " + ", ".join(ran) + ".")
148
+ if blocked:
149
+ parts.append(f"Stopped at {blocked[0].name} — {blocked[0].detail}")
150
+ if panel:
151
+ parts.append("Run these from their method panels, in order: " + ", ".join(panel) + ".")
152
+ from napari.utils.notifications import show_info
153
+ show_info(" ".join(parts) or "Nothing to run.")
154
+ except Exception as exc: # broad-ok: ui_cleanup — a run attempt must never crash the guided panel
155
+ from pycat.utils.general_utils import debug_log
156
+ debug_log("navigator: run_plan_via_central_manager failed", exc)
157
+
158
+
131
159
  def _guided_run_note(plan):
132
160
  """The honest guided-run message, made ACTIONABLE with the gate-respecting run ORDER. Auto-running the
133
161
  whole plan needs a per-operation execution adapter (PyCAT ops have bespoke, panel-collected signatures —
File without changes
File without changes