fibsem 0.5.0__tar.gz → 0.5.1.dev0__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.
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/.claude/skills/linear/SKILL.md +7 -1
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/.gitignore +3 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/GETTING_STARTED.md +2 -1
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/INSTALLATION.md +81 -12
- {fibsem-0.5.0/fibsem.egg-info → fibsem-0.5.1.dev0}/PKG-INFO +3 -1
- fibsem-0.5.1.dev0/docs/design/autofocus.md +276 -0
- fibsem-0.5.1.dev0/docs/design/task-scheduling.md +88 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/slice_and_view.py +9 -3
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/acquire.py +8 -3
- fibsem-0.5.1.dev0/fibsem/alignment/__init__.py +601 -0
- fibsem-0.5.1.dev0/fibsem/alignment/methods.py +427 -0
- fibsem-0.5.1.dev0/fibsem/alignment/plotting.py +170 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/config.py +2 -3
- fibsem-0.5.1.dev0/fibsem/applications/autolamella/protocol/development/task-protocol-coincidence.yaml +290 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/structures.py +92 -21
- fibsem-0.5.1.dev0/fibsem/applications/autolamella/tools/bug_report.py +356 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/ui/AutoLamellaMainUI.py +283 -64
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/ui/AutoLamellaUI.py +634 -527
- fibsem-0.5.1.dev0/fibsem/applications/autolamella/ui/autolamella_fluorescence_acquisition_task_config_widget.py +159 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/legacy/autoliftout.py +10 -10
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/__init__.py +7 -1
- fibsem-0.5.1.dev0/fibsem/applications/autolamella/workflows/tasks/acquire_fluorescence.py +191 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/base.py +57 -3
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/fiducial.py +2 -2
- fibsem-0.5.1.dev0/fibsem/applications/autolamella/workflows/tasks/grid-task-notebook.ipynb +211 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/grid_tasks.py +91 -29
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/manager.py +76 -0
- fibsem-0.5.1.dev0/fibsem/applications/autolamella/workflows/tasks/mill_coincident.py +261 -0
- fibsem-0.5.1.dev0/fibsem/applications/autolamella/workflows/tasks/select_fluorescence_position.py +77 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/select_position.py +5 -4
- fibsem-0.5.1.dev0/fibsem/applications/autolamella/workflows/tasks/spot_burn.py +148 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/tasks.py +14 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/trench.py +4 -4
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/ui.py +5 -2
- fibsem-0.5.1.dev0/fibsem/autofunctions/__init__.py +76 -0
- fibsem-0.5.1.dev0/fibsem/autofunctions/acb.py +257 -0
- fibsem-0.5.1.dev0/fibsem/autofunctions/autofocus.py +408 -0
- fibsem-0.5.1.dev0/fibsem/autofunctions/charge_neutralisation.py +51 -0
- fibsem-0.5.0/fibsem/imaging/autogamma.py → fibsem-0.5.1.dev0/fibsem/autofunctions/gamma.py +2 -5
- fibsem-0.5.1.dev0/fibsem/autofunctions/integration.py +214 -0
- fibsem-0.5.1.dev0/fibsem/autofunctions/metrics.py +214 -0
- fibsem-0.5.1.dev0/fibsem/autofunctions/plotting.py +227 -0
- fibsem-0.5.1.dev0/fibsem/autofunctions/stacking.py +216 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/calibration.py +0 -149
- fibsem-0.5.1.dev0/fibsem/cli.py +552 -0
- fibsem-0.5.1.dev0/fibsem/config/default-sample-holder.yaml +24 -0
- fibsem-0.5.1.dev0/fibsem/config/fm/fm-configuration-default.yaml +38 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/config/sample-holder.yaml +9 -9
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/config/sim-arctis-configuration.yaml +1 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/config.py +144 -30
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/constants.py +2 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/correlation_v2.py +81 -29
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/io.py +93 -55
- fibsem-0.5.1.dev0/fibsem/correlation/refractive_index.py +187 -0
- fibsem-0.5.1.dev0/fibsem/correlation/structures.py +344 -0
- fibsem-0.5.1.dev0/fibsem/correlation/test_correlation_v2.py +104 -0
- fibsem-0.5.1.dev0/fibsem/correlation/tests/eval_lut_precision.py +104 -0
- fibsem-0.5.1.dev0/fibsem/correlation/tests/test_structures.py +184 -0
- fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets/coordinate_list_widget.py +553 -0
- fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets/correlation_input_data_widget.py +203 -0
- fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets/correlation_point_picker_widget.py +605 -0
- fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets/correlation_result_widget.py +217 -0
- fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets/correlation_tab_widget.py +1598 -0
- fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets/fm_image_display_widget.py +485 -0
- fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets/image_point_canvas.py +633 -0
- fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets/refractive_index_widget.py +231 -0
- fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets/test_correlation_point_picker_widget.py +162 -0
- fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets/test_correlation_tab_widget.py +66 -0
- fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets/test_fm_image_display_widget.py +193 -0
- fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets/test_image_point_canvas.py +247 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/util.py +432 -95
- fibsem-0.5.1.dev0/fibsem/fm/__init__.py +21 -0
- fibsem-0.5.1.dev0/fibsem/fm/acquisition.py +1562 -0
- fibsem-0.5.1.dev0/fibsem/fm/autoscript.py +669 -0
- fibsem-0.5.1.dev0/fibsem/fm/calibration/__init__.py +346 -0
- fibsem-0.5.1.dev0/fibsem/fm/fm-example-notebook.ipynb +803 -0
- fibsem-0.5.1.dev0/fibsem/fm/fm-notebook.ipynb +1222 -0
- fibsem-0.5.1.dev0/fibsem/fm/microscope.py +929 -0
- fibsem-0.5.1.dev0/fibsem/fm/odemis.py +663 -0
- fibsem-0.5.1.dev0/fibsem/fm/plot_autofocus_demo.py +80 -0
- fibsem-0.5.1.dev0/fibsem/fm/plotting.py +490 -0
- fibsem-0.5.1.dev0/fibsem/fm/structures.py +1643 -0
- fibsem-0.5.1.dev0/fibsem/fm/timing.py +413 -0
- fibsem-0.5.1.dev0/fibsem/imaging/__init__.py +5 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/imaging/drawing.py +117 -7
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/imaging/spot.py +39 -5
- fibsem-0.5.1.dev0/fibsem/imaging/tests/test_tile_order_strategies.py +37 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/imaging/tiled.py +516 -404
- fibsem-0.5.1.dev0/fibsem/imaging/transforms.py +75 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/imaging/utils.py +22 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/microscope.py +168 -53
- fibsem-0.5.1.dev0/fibsem/microscopes/_stage.py +356 -0
- fibsem-0.5.1.dev0/fibsem/microscopes/autoscript.py +419 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/microscopes/simulator.py +8 -1
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/microscopes/tescan.py +21 -6
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/core.py +2 -2
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/patterning/patterns2.py +22 -5
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/patterning/plotting.py +2 -2
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/strategy/__init__.py +1 -1
- fibsem-0.5.1.dev0/fibsem/milling/strategy/coincidence.py +733 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/strategy/overtilt.py +0 -2
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/tasks.py +12 -3
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/structures.py +236 -246
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/tools/beam_shift_alignment_test.py +1 -1
- fibsem-0.5.1.dev0/fibsem/ui/FMAcquisitionWidget.py +2198 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemImageSettingsWidget.py +27 -11
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemMinimapWidget.py +87 -123
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemMovementWidget.py +44 -226
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemSpotBurnWidget.py +81 -34
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemSystemSetupWidget.py +11 -11
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/__init__.py +50 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/acquisition_summary_dialog.py +129 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/autofocus_widget.py +393 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/autofocus_widget_demo.py +74 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/camera_widget.py +200 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/channel_list_widget.py +850 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/channel_settings_widget.py +213 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/fm/widgets/display_options_dialog.py +3 -1
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/fluorescence_plot_widget.py +449 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/fm_image_viewer_widget.py +194 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/fm_multi_channel_widget.py +168 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/histogram_widget.py +288 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/line_plot_widget.py +727 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/load_image_dialog.py +231 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/objective_control_widget.py +525 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/overview_confirmation_dialog.py +127 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/overview_parameters_widget.py +346 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/saved_positions_widget.py +309 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/sem_acquisition_widget.py +113 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/stage_position_control_widget.py +185 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/test_channel_list_widget.py +69 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/test_line_plot.py +37 -0
- fibsem-0.5.1.dev0/fibsem/ui/fm/widgets/z_parameters_widget.py +188 -0
- fibsem-0.5.1.dev0/fibsem/ui/icon.py +65 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/napari/utilities.py +4 -3
- fibsem-0.5.1.dev0/fibsem/ui/notification_service.py +50 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/stylesheets.py +77 -2
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/utils.py +32 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/autolamella_create_experiment_widget.py +49 -18
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/autolamella_lamella_protocol_editor.py +375 -176
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/autolamella_load_experiment_widget.py +310 -27
- fibsem-0.5.1.dev0/fibsem/ui/widgets/autolamella_spot_burn_coordinates_widget.py +321 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/autolamella_task_config_editor.py +121 -3
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/autolamella_task_config_widget.py +54 -13
- fibsem-0.5.1.dev0/fibsem/ui/widgets/bug_report_widget.py +284 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/contrast_gamma_control.py +175 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/custom_widgets.py +120 -45
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/dual_beam_widget.py +5 -5
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/fibsem_image_flow_widget.py +3 -2
- fibsem-0.5.1.dev0/fibsem/ui/widgets/fluorescence_coincidence_viewer_widget.py +2092 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/fluorescence_coincidence_widget.py +427 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/fluorescence_control_widget.py +1076 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/hook_config_widget.py +1 -1
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/hud_ticker.py +1 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/image_canvas.py +1432 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/image_settings_widget.py +2 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/lamella_card_widget.py +20 -9
- fibsem-0.5.1.dev0/fibsem/ui/widgets/lamella_default_config_widget.py +333 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/lamella_list_widget.py +6 -6
- fibsem-0.5.1.dev0/fibsem/ui/widgets/lamella_pose_list_widget.py +189 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/lamella_workflow_widget.py +5 -19
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/milling_task_config_widget2.py +19 -17
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/milling_task_viewer_widget.py +21 -6
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/milling_widget.py +29 -11
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/notifications.py +7 -7
- fibsem-0.5.1.dev0/fibsem/ui/widgets/overview_acquisition_settings_widget.py +298 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/pattern_settings_widget.py +8 -2
- fibsem-0.5.1.dev0/fibsem/ui/widgets/preferences_dialog.py +274 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/sample_holder_widget.py +510 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/saved_position_widget.py +371 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/selected_lamella_widget.py +158 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/strategy_settings_widget.py +15 -1
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/task_history_table_widget.py +10 -49
- fibsem-0.5.1.dev0/fibsem/ui/widgets/task_summary_formatting.py +106 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/tests/test-selected-lamella.py +133 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test-spinner-icon.py +6 -4
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_alignment_comparison.py +6 -6
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_alignment_plot_v2.py +5 -6
- fibsem-0.5.1.dev0/fibsem/ui/widgets/tests/test_image_canvas.py +198 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/tests/test_lamella_default_config_widget.py +60 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/tests/test_saved_position_widget.py +105 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/tests/test_splitter_layouts.py +167 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/tests/test_workflow_task_editor_widget.py +118 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/tiled_overview_widget.py +374 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/workflow_config_widget.py +15 -92
- fibsem-0.5.1.dev0/fibsem/ui/widgets/workflow_summary_dialog.py +279 -0
- fibsem-0.5.1.dev0/fibsem/ui/widgets/workflow_task_editor_widget.py +370 -0
- fibsem-0.5.1.dev0/fibsem/util/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/utils.py +12 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0/fibsem.egg-info}/PKG-INFO +3 -1
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem.egg-info/SOURCES.txt +128 -11
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem.egg-info/entry_points.txt +4 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem.egg-info/requires.txt +4 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/pyproject.toml +11 -14
- fibsem-0.5.1.dev0/scripts/.gitkeep +0 -0
- fibsem-0.5.1.dev0/scripts/test-autofunctions-notebook.ipynb +109 -0
- fibsem-0.5.1.dev0/scripts/test_acb.py +111 -0
- fibsem-0.5.1.dev0/scripts/test_autofocus.py +102 -0
- fibsem-0.5.1.dev0/scripts/test_tiled_overview_widget.py +166 -0
- fibsem-0.5.1.dev0/scripts/test_workflow_summary_dialog.py +51 -0
- fibsem-0.5.1.dev0/tests/__init__.py +1 -0
- fibsem-0.5.1.dev0/tests/autolamella/__init__.py +0 -0
- fibsem-0.5.1.dev0/tests/autolamella/test_bug_report.py +170 -0
- fibsem-0.5.1.dev0/tests/autolamella/test_fluorescence_pose.py +146 -0
- fibsem-0.5.1.dev0/tests/autolamella/test_milling_angle.py +56 -0
- fibsem-0.5.1.dev0/tests/autolamella/test_spot_burn.py +213 -0
- fibsem-0.5.1.dev0/tests/autolamella/test_structures.py +310 -0
- fibsem-0.5.1.dev0/tests/correlation/__init__.py +0 -0
- fibsem-0.5.1.dev0/tests/correlation/test_refractive_index.py +96 -0
- fibsem-0.5.1.dev0/tests/fm/__init__.py +1 -0
- fibsem-0.5.1.dev0/tests/fm/conftest.py +15 -0
- fibsem-0.5.1.dev0/tests/fm/test_acquisition.py +991 -0
- fibsem-0.5.1.dev0/tests/fm/test_autofocus_widget.py +163 -0
- fibsem-0.5.1.dev0/tests/fm/test_calibration.py +586 -0
- fibsem-0.5.1.dev0/tests/fm/test_fm_autofocus.py +288 -0
- fibsem-0.5.1.dev0/tests/fm/test_structures.py +2229 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/milling/test_core.py +7 -3
- fibsem-0.5.1.dev0/tests/milling/test_tasks.py +65 -0
- fibsem-0.5.1.dev0/tests/test_alignment.py +499 -0
- fibsem-0.5.1.dev0/tests/test_autofunctions.py +412 -0
- fibsem-0.5.1.dev0/tests/test_microscope.py +153 -0
- fibsem-0.5.1.dev0/tests/test_recent_experiments.py +141 -0
- fibsem-0.5.1.dev0/tests/test_sample_holder.py +329 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/test_structures.py +204 -2
- fibsem-0.5.1.dev0/tests/test_tiled.py +266 -0
- fibsem-0.5.0/fibsem/alignment.py +0 -1035
- fibsem-0.5.0/fibsem/applications/autolamella/workflows/tasks/spot_burn.py +0 -84
- fibsem-0.5.0/fibsem/correlation/app.py +0 -1594
- fibsem-0.5.0/fibsem/correlation/ui/__init__.py +0 -16
- fibsem-0.5.0/fibsem/correlation/ui/config.py +0 -140
- fibsem-0.5.0/fibsem/correlation/ui/fm_import_wizard.py +0 -293
- fibsem-0.5.0/fibsem/correlation/ui/pandas_table.py +0 -133
- fibsem-0.5.0/fibsem/correlation/ui/qt/tdct_fm_import_wizard.py +0 -115
- fibsem-0.5.0/fibsem/correlation/ui/qt/tdct_main.py +0 -351
- fibsem-0.5.0/fibsem/imaging/__init__.py +0 -5
- fibsem-0.5.0/fibsem/microscopes/_stage.py +0 -267
- fibsem-0.5.0/fibsem/ui/fm/widgets/__init__.py +0 -17
- fibsem-0.5.0/fibsem/ui/widgets/milling_stage_editor_widget.py +0 -1173
- fibsem-0.5.0/fibsem/ui/widgets/milling_task_config_widget.py +0 -547
- fibsem-0.5.0/fibsem/ui/widgets/overview_acquisition_settings_widget.py +0 -223
- fibsem-0.5.0/fibsem/ui/widgets/preferences_dialog.py +0 -155
- fibsem-0.5.0/fibsem/ui/widgets/sample_holder_widget.py +0 -433
- fibsem-0.5.0/fibsem/ui/widgets/workflow_task_editor_widget.py +0 -213
- fibsem-0.5.0/tests/autolamella/test_structures.py +0 -108
- fibsem-0.5.0/tests/test_alignment.py +0 -144
- fibsem-0.5.0/tests/test_microscope.py +0 -58
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/.claude/skills/new-widget/SKILL.md +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/.claude/skills/review-changes/SKILL.md +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/.claude/skills/review-widget/SKILL.md +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/.github/workflows/publish.yml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/.github/workflows/python-package.yml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/CHANGES.md +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/LICENSE +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/MANIFEST.in +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/README.md +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/RELEASE.md +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/docs/design/hooks.md +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/autolamella.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/example.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/example.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/example_imaging.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/example_milling.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/example_movement.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/example_notebook.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/lithography.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/profile.npy +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/protocol_autolamella.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/protocol_lithography.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/example/protocol_slice_and_view.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/external/application_files/autolamella.xml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/external/application_files/cryo_Pt_dep.xml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/compat/notebook.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/compat/odemis.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/protocol/.gitkeep +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/protocol/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/protocol/constants.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/protocol/legacy/protocol-liftout.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/protocol/legacy/protocol-on-grid.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/protocol/legacy/protocol-serial-liftout.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/protocol/legacy/protocol-trench.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/protocol/legacy/protocol-waffle.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/protocol/legacy.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/protocol/task-protocol-waffle.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/protocol/task-protocol.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/protocol/validation.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/task_manager_queue.md +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/tools/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/tools/data.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/tools/notebook.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/tools/reporting.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/tools/review.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/tools/stats.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/tools/upload_to_hf.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/ui/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/ui/run_ui.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/ui/tests/test_confirm_run_workflow_dialog.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/_default_milling_config.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/core.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/legacy/experimental.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/legacy/serial.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/basic_milling.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/hooks.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/polishing.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/queue.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/reference_image.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/rough.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/test_hooks.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/applications/autolamella/workflows/tasks/undercut.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/chat/.gitignore +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/chat/main.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/chat/requirements.txt +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/config/microscope-configuration.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/config/odemis-configuration.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/config/tescan-configuration.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/config/tescan_manipulator.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/config/tfs-aquilos2-configuration.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/config/tfs-arctis-configuration.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/config/tfs-hydra-configuration.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/configuration.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/conversions.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/README.md +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/pyto/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/pyto/affine.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/pyto/affine_2d.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/pyto/attributes.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/pyto/common.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/pyto/points.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/pyto/rigid_3d.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/pyto/test/test_affine.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/pyto/test/test_affine_2d.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/pyto/test/test_rigid_3d.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/correlation/pyto/util.py +0 -0
- {fibsem-0.5.0/fibsem/detection → fibsem-0.5.1.dev0/fibsem/correlation/tests}/__init__.py +0 -0
- {fibsem-0.5.0/fibsem/imaging/tests → fibsem-0.5.1.dev0/fibsem/correlation/ui}/__init__.py +0 -0
- {fibsem-0.5.0/fibsem/segmentation → fibsem-0.5.1.dev0/fibsem/correlation/ui/widgets}/__init__.py +0 -0
- {fibsem-0.5.0/fibsem/util → fibsem-0.5.1.dev0/fibsem/detection}/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/config-autolamella-liftout-hf-mega.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/config-autolamella-liftout.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/config-autolamella-serial-liftout-hf-mega.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/config-autolamella-serial-liftout.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/config-autolamella-waffle-v2-hf-mega.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/config-autolamella-waffle-v2.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/config-autolamella-waffle.yml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/config-autoliftout-dm-embryo.yml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/detection.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/evaluation.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/run_evaluation.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_image.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_image_2.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_images/serial/serial_liftout_mask_00.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_images/serial/serial_liftout_mask_01.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_images/serial/serial_liftout_mask_02.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_images/serial/serial_liftout_mask_03.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_images/serial/serial_liftout_mask_04.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_images/serial/serial_liftout_mask_05.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_images/serial/serial_liftout_mask_06.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_images/serial/serial_liftout_mask_07.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_images/test_needle_mask.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_images/test_needle_mask2.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/test_images/test_needle_mask3.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/detection/utils.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/gis.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/imaging/.gitkeep +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/imaging/masks.py +0 -0
- {fibsem-0.5.0/tests/autolamella → fibsem-0.5.1.dev0/fibsem/imaging/tests}/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/imaging/tests/test_drawing_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/logo.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/microscopes/notebook.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/microscopes/odemis_microscope.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/microscopes/zeiss.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/base.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/config.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/patterning/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/patterning/utils.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/properties.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/milling/strategy/standard.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/movement.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/README.md +0 -0
- /fibsem-0.5.0/fibsem/segmentation/models/.gitkeep → /fibsem-0.5.1.dev0/fibsem/segmentation/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/_nnunet.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/adaptive_model.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/augmentation.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/config-autolamella-mega-v4-xl.yml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/config-autolamella-mega-v4.yml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/config-autolamella-mega-v5.yml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/config-autolamella-waffle4.yml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/config.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/config.yml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/dataset.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/docs/example_napari.png +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/docs/imgs/combined/combined.jpg +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/docs/imgs/labelled/label.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/docs/imgs/raw/image.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/example.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/hf_segmentation_model.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/huggingface.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/inference.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/model.py +0 -0
- {fibsem-0.5.0/fibsem/ui → fibsem-0.5.1.dev0/fibsem/segmentation/models}/.gitkeep +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/nnunet_model.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/nnunet_model_v2.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/onnx_model.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/requirements.txt +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/sam_model.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/segmentation_config.yaml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/test_image.tif +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/train.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/segmentation/utils.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/server/GAPS.md +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/server/README.md +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/server/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/server/client.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/server/models.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/server/server.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/tools/_parser.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/tools/_streamlit.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/tools/run_manipulator_calibration.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/tools/run_split_dataset.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/tools/telemetry.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/transformations.py +0 -0
- {fibsem-0.5.0/scripts → fibsem-0.5.1.dev0/fibsem/ui}/.gitkeep +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemCryoDepositionWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemCryoDepositionWidget_qt.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemEmbeddedDetectionWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemFeatureLabellingUI.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemLabellingUI.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemManipulatorWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemMicroscopeConfigurationWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemMicroscopeConfigurationWidgetBase.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemModelTrainingWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemSegmentationModelWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/FibsemUI.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/__init__.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/fm/widgets/minimap_plot_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/fm/widgets/minimap_plot_widget_example.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/icons/check.svg +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/icons/chevron_down.svg +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/icons/drag_handle.svg +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/icons/minus.svg +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/icons/plus.svg +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/napari/patterns.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/napari/properties.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/FibsemCryoDepositionWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/FibsemFeatureDetectionUI.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/FibsemLabellingUI.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/FibsemManipulatorWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/FibsemMicroscopeConfigurationWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/FibsemMicroscopeConfigurationWidgetBase.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/FibsemModelTrainingWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/FibsemSegmentationModelWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/FibsemSpotBurnWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/FibsemSystemSetupWidget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/FibsemUI.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/detection_dialog.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/qtdesigner_files/image_viewer.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/angle_measure.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/annotation_pin.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/autolamella_apply_protocol_dialog.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/autolamella_experiment_task_summary_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/autolamella_generate_report_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/autolamella_global_task_editor_dialog.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/autolamella_load_task_protocol_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/autolamella_overview_image_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/autolamella_protocol_information_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/beam_settings_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/beam_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/dataframe_table_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/detector_settings_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/drag_distance.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/image_annotation_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/lamella_task_image_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/microscope_config_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/milling_alignment_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/milling_settings_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/milling_stage_list_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/milling_stages_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/milling_task_acquisition_settings_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/profile_line.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/progress_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/radial_menu.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/reference_image_parameters_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test-icon-tool-button.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test-image-settings-widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test-lamella-card.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test-lamella-list.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test-lamella-workflow.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test-progress-bar.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test-workflow-config.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_countdown_progress.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_drag_distance.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_hooks_manual.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_lamella_name_list_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_lamella_task_image_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_milling_settings_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_milling_stage_list.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_milling_stages_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_milling_task_config_widget2.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_milling_task_viewer_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_pattern_settings_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_progress_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_radial_menu.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_radial_ruler_demo.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_reference_image_parameters_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_toast.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/tests/test_workflow_timeline_animation.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/workflow_info_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/workflow_timeline_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/ui/widgets/zoom_loupe.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/util/draw_numbers.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/util/filename.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem/validation.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem.egg-info/dependency_links.txt +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/fibsem.egg-info/top_level.txt +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/mkdocs.yml +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/arctis_notebook.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/compat-notebook.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/convert_to_nnunet_dataset.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/convert_to_onnx.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/export_nnunet_checkpoint.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/generate_segmentation_objects.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/install.bat +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/install.sh +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/notebook.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/onnx_notebook.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/onnx_pred.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/run.sh +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/run_ui.bat +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/shortcut.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/stack_Arctis_Script.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/test-alignment-script.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/test_installation.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/test_microscope_config_widget.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/scripts/test_rtm_script.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/setup.cfg +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/autolamella/test_tasks.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/milling/test_base.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/milling/test_pattern_utils.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/milling/test_patterns.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/tescan-test-notebook.ipynb +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/test_acquire.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/test_acquire_image_api.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/test_example.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/test_movement.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/test_tescan.py +0 -0
- {fibsem-0.5.0 → fibsem-0.5.1.dev0}/tests/test_utils.py +0 -0
|
@@ -22,7 +22,10 @@ Get the user's approval on the plan before proceeding.
|
|
|
22
22
|
## Step 3 — Implement
|
|
23
23
|
After plan approval, implement the changes following the existing code patterns and conventions.
|
|
24
24
|
|
|
25
|
-
## Step 4 —
|
|
25
|
+
## Step 4 — Test
|
|
26
|
+
Before committing, ask the user to test the feature manually and confirm it works as expected. Wait for their confirmation before proceeding.
|
|
27
|
+
|
|
28
|
+
## Step 5 — Commit
|
|
26
29
|
Create a git commit with a message that:
|
|
27
30
|
- Starts with the type tag matching the issue type: `[fix]`, `[feat]`, `[refactor]`, `[docs]`, etc.
|
|
28
31
|
- Includes `[FIB-$ARGUMENTS]`
|
|
@@ -31,3 +34,6 @@ Create a git commit with a message that:
|
|
|
31
34
|
Example: `[fix][FIB-$ARGUMENTS] correct milling stage drag-drop reorder`
|
|
32
35
|
|
|
33
36
|
Do NOT include "Claude" or "Co-Authored-By" in the commit message (per project guidelines).
|
|
37
|
+
|
|
38
|
+
## Step 6 — Mark In Review
|
|
39
|
+
After the commit, update the Linear issue status to "In Review" using `mcp__linear-server__save_issue` with `state: "In Review"`.
|
|
@@ -52,6 +52,7 @@ fibsem/config/*.yaml
|
|
|
52
52
|
!fibsem/config/tescan-*.yaml
|
|
53
53
|
!fibsem/config/sim-*.yaml
|
|
54
54
|
!fibsem/config/sample-holder.yaml
|
|
55
|
+
!fibsem/config/default-sample-holder.yaml
|
|
55
56
|
|
|
56
57
|
**/wandb/*
|
|
57
58
|
tests/notebook.ipynb
|
|
@@ -81,3 +82,5 @@ database_migration.md
|
|
|
81
82
|
fibsem/ui/OFFLINE_ICONS.md
|
|
82
83
|
fibsem/correlation/scaling_factor_lookup_table.csv
|
|
83
84
|
fibsem/correlation/slice_scaling_factor_LUT.ipynb
|
|
85
|
+
sashimi/*
|
|
86
|
+
fibsem/applications/sashimi/log/*
|
|
@@ -10,7 +10,8 @@ This walkthrough assumes you have installed the application, and configured your
|
|
|
10
10
|
|
|
11
11
|
### Running the Application
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Run the shortcut set up in [INSTALLATION.md](INSTALLATION.md#create-a-desktop-shortcut) or open Anaconda Prompt and run:
|
|
14
|
+
|
|
14
15
|
```bash
|
|
15
16
|
conda activate fibsem
|
|
16
17
|
fibsem-autolamella-ui
|
|
@@ -8,8 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
### Python
|
|
10
10
|
Python 3.9+ is required.
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
We recommend installing Python via [Miniforge](https://conda-forge.org/download/),
|
|
12
|
+
a minimal installer that uses the community-maintained
|
|
13
|
+
[conda-forge](https://conda-forge.org/) channel by default. It provides the same
|
|
14
|
+
`conda` (and `mamba`) commands as Anaconda/Miniconda while staying lightweight and
|
|
15
|
+
avoiding the licensing terms that can apply to Anaconda's default channels for larger
|
|
16
|
+
organizations.
|
|
13
17
|
|
|
14
18
|
## Setting up your python virtual environment
|
|
15
19
|
It is also highly recommended to use virtual environments for development,
|
|
@@ -17,13 +21,16 @@ see [Managing Conda Environments](https://docs.conda.io/projects/conda/en/latest
|
|
|
17
21
|
for more information.
|
|
18
22
|
(Optionally, you could use `virtualenv` if you prefer.)
|
|
19
23
|
|
|
20
|
-
Create a new
|
|
24
|
+
Create a new virtual environment from your conda terminal (the Miniforge Prompt on
|
|
25
|
+
Windows, or any terminal on macOS/Linux):
|
|
21
26
|
```
|
|
22
27
|
cd fibsem
|
|
23
28
|
conda env create -n fibsem python=3.11 pip
|
|
24
29
|
conda activate fibsem
|
|
25
|
-
pip install -e .
|
|
30
|
+
python -m pip install -e ".[ui]"
|
|
26
31
|
```
|
|
32
|
+
The `[ui]` extra installs the GUI dependencies (recommended). To install without the
|
|
33
|
+
GUI, use `python -m pip install -e .` instead.
|
|
27
34
|
|
|
28
35
|
### Installation through Python virtualenv
|
|
29
36
|
|
|
@@ -40,8 +47,70 @@ fibsem\Scripts\activate.bat
|
|
|
40
47
|
```
|
|
41
48
|
Once activated, move to the fibsem root directory and install fibsem like so
|
|
42
49
|
```
|
|
43
|
-
pip install -e .
|
|
50
|
+
python -m pip install -e ".[ui]"
|
|
44
51
|
```
|
|
52
|
+
The `[ui]` extra installs the GUI dependencies (recommended). To install without the
|
|
53
|
+
GUI, use `python -m pip install -e .` instead.
|
|
54
|
+
|
|
55
|
+
### Installation with uv
|
|
56
|
+
|
|
57
|
+
[uv](https://docs.astral.sh/uv/) is a fast, drop-in replacement for `pip`.
|
|
58
|
+
|
|
59
|
+
First, install uv (see the [official install guide](https://docs.astral.sh/uv/getting-started/installation/)
|
|
60
|
+
for all options):
|
|
61
|
+
```
|
|
62
|
+
# macOS / Linux
|
|
63
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
64
|
+
```
|
|
65
|
+
```
|
|
66
|
+
# Windows (PowerShell)
|
|
67
|
+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
68
|
+
```
|
|
69
|
+
Alternatively, install it into an existing environment with `pip install uv`.
|
|
70
|
+
|
|
71
|
+
uv can create and manage the virtual environment itself, so you don't need conda or
|
|
72
|
+
`virtualenv`. From the fibsem root directory, create and activate an environment:
|
|
73
|
+
```
|
|
74
|
+
# macOS / Linux
|
|
75
|
+
uv venv
|
|
76
|
+
source .venv/bin/activate
|
|
77
|
+
```
|
|
78
|
+
```
|
|
79
|
+
# Windows (PowerShell)
|
|
80
|
+
uv venv
|
|
81
|
+
.venv\Scripts\activate
|
|
82
|
+
```
|
|
83
|
+
uv also works inside a conda or `virtualenv` environment created above, with nothing
|
|
84
|
+
extra to set up — just activate that environment instead.
|
|
85
|
+
|
|
86
|
+
Once your environment is active, install fibsem with the GUI dependencies (recommended):
|
|
87
|
+
```
|
|
88
|
+
uv pip install -e ".[ui]"
|
|
89
|
+
```
|
|
90
|
+
To install without the GUI dependencies:
|
|
91
|
+
```
|
|
92
|
+
uv pip install -e .
|
|
93
|
+
```
|
|
94
|
+
This resolves the same dependencies from `pyproject.toml` as `pip`, just faster.
|
|
95
|
+
No lockfile or additional configuration is required.
|
|
96
|
+
|
|
97
|
+
### Create a desktop shortcut
|
|
98
|
+
1. Create a script file:
|
|
99
|
+
Activate the environment then run the following command to create the script:
|
|
100
|
+
- **Windows**
|
|
101
|
+
|
|
102
|
+
Create AutoLamella.bat
|
|
103
|
+
```cmd
|
|
104
|
+
echo @echo off > AutoLamella.bat & where fibsem-autolamella-ui >> AutoLamella.bat
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- **Linux**
|
|
108
|
+
|
|
109
|
+
Create AutoLamella.sh
|
|
110
|
+
```bash
|
|
111
|
+
printf '#!/bin/bash\n%s' $(which fibsem-autolamella-ui) > AutoLamella.sh
|
|
112
|
+
```
|
|
113
|
+
2. Create a shortcut to your script file and place it on your desktop.
|
|
45
114
|
|
|
46
115
|
## Installing Microscope Hardware APIs
|
|
47
116
|
|
|
@@ -51,13 +120,13 @@ control of compatible FEI microscope systems.
|
|
|
51
120
|
This is a commercial product by Thermo Fisher FEI, please visit their website
|
|
52
121
|
at https://www.thermofisher.com/au/en/home/electron-microscopy.html for information on pricing and installation.
|
|
53
122
|
|
|
54
|
-
We use Autoscript version 4.
|
|
123
|
+
We use Autoscript version 4.7.+
|
|
55
124
|
|
|
56
125
|
The version numbers of the python packages Autoscript installs were:
|
|
57
126
|
* autoscript-core 5.12.0
|
|
58
|
-
* autoscript-sdb-microscope-client 4.
|
|
59
|
-
* autoscript-sdb-microscope-client-tests 4.
|
|
60
|
-
* autoscript-toolkit 4.
|
|
127
|
+
* autoscript-sdb-microscope-client 4.7.0
|
|
128
|
+
* autoscript-sdb-microscope-client-tests 4.7.0
|
|
129
|
+
* autoscript-toolkit 4.7.0
|
|
61
130
|
* thermoscientific-logging 5.12.0
|
|
62
131
|
|
|
63
132
|
#### Add the autoscript python packages to your `site-packages`
|
|
@@ -93,10 +162,10 @@ You will need to copy:
|
|
|
93
162
|
* autoscript_core-5.12.0.dist-info
|
|
94
163
|
* autoscript_sdb_microscope_client
|
|
95
164
|
* autoscript_sdb_microscope_client_tests
|
|
96
|
-
* autoscript_sdb_microscope_client_tests-4.
|
|
97
|
-
* autoscript_sdb_microscope_client-4.
|
|
165
|
+
* autoscript_sdb_microscope_client_tests-4.7.0.dist-info
|
|
166
|
+
* autoscript_sdb_microscope_client-4.7.0.dist-info
|
|
98
167
|
* autoscript_toolkit
|
|
99
|
-
* autoscript_toolkit-4.
|
|
168
|
+
* autoscript_toolkit-4.7.0.dist-info
|
|
100
169
|
* thermoscientific_logging
|
|
101
170
|
* thermoscientific_logging-5.12.1.dist-info
|
|
102
171
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fibsem
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1.dev0
|
|
4
4
|
Summary: a universal api for fibsem control
|
|
5
5
|
Author-email: Patrick Cleeve <patrick@openfibsem.org>
|
|
6
6
|
License: MIT License
|
|
@@ -42,7 +42,9 @@ Provides-Extra: ui
|
|
|
42
42
|
Requires-Dist: napari>=0.4.17; python_version < "3.9" and extra == "ui"
|
|
43
43
|
Requires-Dist: napari<=0.5.6,>=0.5.1; python_version >= "3.9" and extra == "ui"
|
|
44
44
|
Requires-Dist: pyqt5>=5.15.9; extra == "ui"
|
|
45
|
+
Requires-Dist: pyqt5-qt5==5.15.2; platform_system == "Windows" and extra == "ui"
|
|
45
46
|
Requires-Dist: matplotlib_scalebar>=0.8.1; extra == "ui"
|
|
47
|
+
Requires-Dist: qtawesome>=1.3.0; extra == "ui"
|
|
46
48
|
Provides-Extra: odemis
|
|
47
49
|
Requires-Dist: pylibtiff; extra == "odemis"
|
|
48
50
|
Requires-Dist: shapely; extra == "odemis"
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# Autofocus: Consolidation & Strategy Extension
|
|
2
|
+
|
|
3
|
+
> **Status:** Part 1 (consolidation) implemented in [PR #107](https://github.com/fibsem-os/fibsem-os/pull/107) · Part 2 (strategy extension) proposed, not yet implemented.
|
|
4
|
+
|
|
5
|
+
This document covers two related things:
|
|
6
|
+
|
|
7
|
+
1. **Consolidation** — how the duplicated FIB-SEM and FM autofocus types/methods were merged into one canonical set, and the reusable recipe for doing the same to other auto-functions.
|
|
8
|
+
2. **Strategy extension** — a simple, forward-looking design for making each focus pass pluggable (e.g. `sweep` vs `hill_climb`), which also finishes the consolidation by unifying the two remaining sweep engines.
|
|
9
|
+
|
|
10
|
+
Consolidation comes first because the strategy extension builds directly on it.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Part 1 — Consolidating FIB-SEM / FM autofocus
|
|
15
|
+
|
|
16
|
+
### What existed before
|
|
17
|
+
|
|
18
|
+
Autofocus was implemented twice, with parallel-but-incompatible types:
|
|
19
|
+
|
|
20
|
+
| Concern | FIB-SEM (`autofunctions.autofocus`) | FM (`fm.structures` / `fm.calibration`) |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| Result | `AutoFocusResult` — iteration objects, `save`/`load`, plot | `AutoFocusResult` — parallel lists (`z_positions`, `scores`, `images`), recursive `iterations`, no `save`/`load` |
|
|
23
|
+
| Settings | `AutoFocusSettings` — `passes: list[FocusSweepPass]` | `AutoFocusSettings` — fixed `coarse_*` / `fine_*` |
|
|
24
|
+
| Method enum | `str` | `FocusMethod(Enum)` |
|
|
25
|
+
| Run fn | `run_auto_focus` (multi-pass WD sweep) | `run_autofocus` + `run_coarse_fine_autofocus` (objective-z sweep) |
|
|
26
|
+
| Strategy layer | — | `fm.strategy` package (ABC + generics + pydantic) wrapping the run fns with no real polymorphism |
|
|
27
|
+
|
|
28
|
+
Two `AutoFocusResult` classes, two `AutoFocusSettings` classes, a duplicated `FocusMethod`, and a 460-line strategy package that added indirection without behaviour.
|
|
29
|
+
|
|
30
|
+
### The consolidation recipe
|
|
31
|
+
|
|
32
|
+
The pattern we applied — reusable for any duplicated FIB-SEM/FM auto-function (ACB, charge neutralisation, etc.):
|
|
33
|
+
|
|
34
|
+
1. **Pick the canonical home.** Lower-level, hardware-agnostic code lives in `fibsem.autofunctions.*`. `fibsem.fm.*` may depend on `autofunctions`, never the reverse — so canonical types go in `autofunctions`.
|
|
35
|
+
2. **Unify the data shape first.** The result/settings types must describe the *same data*, independent of hardware. Here: iterations store a raw `np.ndarray` (not `FibsemImage`), since that's all the focus metric needs; domain-only fields (`channel_name` for FM; `probe_resolution`/`probe_dwell_time`/`use_autocontrast` for FIB-SEM) coexist on one dataclass and are simply ignored by the domain that doesn't use them.
|
|
36
|
+
3. **Re-export for source compatibility.** `fm.structures` re-exports `AutoFocusResult`, `AutoFocusSettings`, `FocusMethod`, `FocusSweepPass` from `autofunctions.autofocus`, so existing `from fibsem.fm.structures import ...` call sites keep working with no edits.
|
|
37
|
+
4. **Provide a factory + legacy loader, not a shim.** `AutoFocusSettings.from_coarse_fine(...)` builds the common two-pass config; `from_dict` accepts both the new `passes` schema and the legacy `coarse_*`/`fine_*` and `n_steps` formats. This is the migration surface — old protocols on disk still load.
|
|
38
|
+
5. **Delete the abstraction that wasn't paying rent.** The `fm.strategy` package was removed; `run_autofocus` / `run_coarse_fine_autofocus` are called directly.
|
|
39
|
+
|
|
40
|
+
### Canonical types (today)
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
class FocusMethod(str, Enum): # str-Enum: serialises as its value, compares as str
|
|
44
|
+
LAPLACIAN = "laplacian"; SOBEL = "sobel"; VARIANCE = "variance"; TENENGRAD = "tenengrad"
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class FocusSweepPass:
|
|
48
|
+
search_range: float = 5e-3 # total span (positions cover ±range/2)
|
|
49
|
+
step_size: float = 0.5e-3
|
|
50
|
+
enabled: bool = True
|
|
51
|
+
@property
|
|
52
|
+
def n_steps(self) -> int: ... # derived: round(search_range / step_size)
|
|
53
|
+
|
|
54
|
+
@dataclass
|
|
55
|
+
class AutoFocusSettings:
|
|
56
|
+
method: FocusMethod = FocusMethod.TENENGRAD
|
|
57
|
+
passes: list = None # list[FocusSweepPass]; coarse → fine
|
|
58
|
+
probe_resolution: tuple = (768, 512) # FIB-SEM only
|
|
59
|
+
probe_dwell_time: float = 0.5e-6 # FIB-SEM only
|
|
60
|
+
reduced_area: FibsemRectangle = None
|
|
61
|
+
use_autocontrast: bool = True # FIB-SEM only
|
|
62
|
+
channel_name: Optional[str] = None # FM only
|
|
63
|
+
|
|
64
|
+
@dataclass
|
|
65
|
+
class AutoFocusIteration:
|
|
66
|
+
working_distance: float; focus_score: float; pass_index: int; image: np.ndarray
|
|
67
|
+
|
|
68
|
+
@dataclass
|
|
69
|
+
class AutoFocusResult:
|
|
70
|
+
image: np.ndarray; working_distance: float; initial_working_distance: float
|
|
71
|
+
focus_score: float; iterations: list[AutoFocusIteration]
|
|
72
|
+
settings: AutoFocusSettings = None; method: Optional[str] = None
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### What still isn't consolidated
|
|
76
|
+
|
|
77
|
+
The **two sweep executors remain duplicated**:
|
|
78
|
+
|
|
79
|
+
- FIB-SEM `_run_sweep` moves *working distance* (`microscope.set_working_distance`), acquires via `microscope.acquire_image`, scores `probe.filtered_data`.
|
|
80
|
+
- FM `run_autofocus` / `run_coarse_fine_autofocus` move the *objective* (`objective.move_absolute`), acquire via `fm.acquire_image`, crop to ROI, score via `calculate_focus_quality`.
|
|
81
|
+
|
|
82
|
+
The control flow (sweep positions, argmax, move-to-best, pass tagging, cancellation) is the same in both; only the move + acquire + score primitives differ. Part 2 closes this gap.
|
|
83
|
+
|
|
84
|
+
One piece of that duplication is already factored out: converting a `FocusSweepPass`
|
|
85
|
+
into a relative sweep is centralised in **`ZParameters.from_focus_pass(pass)`**
|
|
86
|
+
(used by both `run_coarse_fine_autofocus` and the tileset autofocus in
|
|
87
|
+
`fm/acquisition.py`). It lives on `ZParameters` because the conversion targets an
|
|
88
|
+
fm-level type — `autofunctions` can't import it. Note that once the Part 2 driver
|
|
89
|
+
lands, the per-pass path stops going through `ZParameters` at all (the driver
|
|
90
|
+
visits positions directly via `move`); `from_focus_pass` is the interim dedup and
|
|
91
|
+
remains useful for callers that still want a `ZParameters` (e.g. building a z-stack
|
|
92
|
+
from a pass).
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Part 2 — Per-pass focus strategy
|
|
97
|
+
|
|
98
|
+
### Goal
|
|
99
|
+
|
|
100
|
+
Let each pass choose *how* it searches, not just its range/step. Default stays a full grid sweep; opt into alternatives like an iterative hill-climb:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
FocusSweepPass(search_range=100e-6, step_size=10e-6, strategy=FocusStrategy.HILL_CLIMB)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
This must **not** reintroduce the deleted strategy-class layer. A strategy is only the question *"which position do I visit next?"* — independent of how a position is measured.
|
|
107
|
+
|
|
108
|
+
### Design
|
|
109
|
+
|
|
110
|
+
Add a per-pass enum (serialises and maps onto existing params):
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
class FocusStrategy(str, Enum):
|
|
114
|
+
SWEEP = "sweep"
|
|
115
|
+
HILL_CLIMB = "hill_climb"
|
|
116
|
+
|
|
117
|
+
@dataclass
|
|
118
|
+
class FocusSweepPass:
|
|
119
|
+
search_range: float = 5e-3
|
|
120
|
+
step_size: float = 0.5e-3
|
|
121
|
+
enabled: bool = True
|
|
122
|
+
strategy: FocusStrategy = FocusStrategy.SWEEP # NEW
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Pull the hardware mechanics into **two callbacks** each executor supplies, and make the strategy a tiny function driving them:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
def _run_pass(p, center, move, measure):
|
|
129
|
+
"""move(pos): position the WD / objective.
|
|
130
|
+
measure(pos) -> AutoFocusIteration at pos (records into the shared list, returns it).
|
|
131
|
+
Returns the best iteration; leaves the hardware parked at it."""
|
|
132
|
+
def evaluate(pos):
|
|
133
|
+
move(pos)
|
|
134
|
+
return measure(pos)
|
|
135
|
+
|
|
136
|
+
climb = _hill_climb if p.strategy is FocusStrategy.HILL_CLIMB else _sweep
|
|
137
|
+
best = climb(p, center, evaluate)
|
|
138
|
+
move(best.working_distance) # driver guarantees the final park position
|
|
139
|
+
return best
|
|
140
|
+
|
|
141
|
+
def _sweep(p, center, evaluate):
|
|
142
|
+
half = p.search_range / 2
|
|
143
|
+
its = [evaluate(z) for z in np.linspace(center - half, center + half, p.n_steps + 1)]
|
|
144
|
+
return max(its, key=lambda it: it.focus_score)
|
|
145
|
+
|
|
146
|
+
def _hill_climb(p, center, evaluate):
|
|
147
|
+
half, step = p.search_range / 2, p.step_size
|
|
148
|
+
best = evaluate(center)
|
|
149
|
+
direction = max((+1, -1), key=lambda d: evaluate(center + d * step).focus_score)
|
|
150
|
+
pos = center + direction * step
|
|
151
|
+
while abs(pos - center) <= half: # bounded by search_range
|
|
152
|
+
it = evaluate(pos)
|
|
153
|
+
if it.focus_score <= best.focus_score:
|
|
154
|
+
break # greedy stop on first non-improvement
|
|
155
|
+
best, pos = it, pos + direction * step
|
|
156
|
+
return best
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`move` is the primitive that differs between domains — and it's the *only* hardware difference, so factoring it out is what lets one driver serve both:
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
# FIB-SEM
|
|
163
|
+
move = lambda wd: microscope.set_working_distance(wd, beam_type)
|
|
164
|
+
def measure(wd):
|
|
165
|
+
probe = microscope.acquire_image(image_settings=probe_settings)
|
|
166
|
+
score = float(np.mean(focus_fn(probe.filtered_data.astype(np.float32))))
|
|
167
|
+
it = AutoFocusIteration(working_distance=wd, focus_score=score,
|
|
168
|
+
pass_index=pass_index, image=probe.data)
|
|
169
|
+
iterations.append(it)
|
|
170
|
+
return it
|
|
171
|
+
|
|
172
|
+
# FM — same shape, two lines differ:
|
|
173
|
+
move = lambda z: microscope.objective.move_absolute(z)
|
|
174
|
+
def measure(z):
|
|
175
|
+
img = microscope.acquire_image()
|
|
176
|
+
data = img.crop(roi) if roi is not None else img.data
|
|
177
|
+
score = calculate_focus_quality(data, method=method)
|
|
178
|
+
it = AutoFocusIteration(working_distance=z, focus_score=score,
|
|
179
|
+
pass_index=pass_index, image=data)
|
|
180
|
+
iterations.append(it)
|
|
181
|
+
return it
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Cancellation
|
|
185
|
+
|
|
186
|
+
Both run functions today poll `stop_event` before each position and restore the
|
|
187
|
+
initial position on cancel. The driver keeps that behaviour without threading a
|
|
188
|
+
flag through every strategy: **`measure` owns the check and raises**, the driver
|
|
189
|
+
lets it propagate, and the run function catches it once.
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
class AutofocusCancelled(Exception):
|
|
193
|
+
pass
|
|
194
|
+
|
|
195
|
+
def measure(pos): # inside each executor's closure
|
|
196
|
+
if stop_event is not None and stop_event.is_set():
|
|
197
|
+
raise AutofocusCancelled
|
|
198
|
+
... # acquire + score + record
|
|
199
|
+
|
|
200
|
+
# run_auto_focus / run_coarse_fine_autofocus:
|
|
201
|
+
initial = read_current_position()
|
|
202
|
+
try:
|
|
203
|
+
best = _run_pass(p, center, move, measure)
|
|
204
|
+
except AutofocusCancelled:
|
|
205
|
+
move(initial) # restore, then return None / partial result
|
|
206
|
+
return None
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
This keeps strategies oblivious to cancellation (they just call `evaluate`),
|
|
210
|
+
puts the one check at the single I/O point, and centralises restore-on-cancel in
|
|
211
|
+
the run function — which also fixes the current duplication where each path
|
|
212
|
+
re-implements the poll + restore.
|
|
213
|
+
|
|
214
|
+
### Why this is the sweet spot
|
|
215
|
+
|
|
216
|
+
- **Finishes the consolidation.** Both `_run_sweep` (FIB-SEM) and the per-pass body of `run_coarse_fine_autofocus` (FM) collapse to "build `move`/`measure`, call `_run_pass`". The extension *removes* the duplication from Part 1 rather than adding code.
|
|
217
|
+
- **No class hierarchy.** Strategies are pure functions over an `evaluate` callback; adding one is a function plus an enum value.
|
|
218
|
+
- **Driver owns the final move-to-best**, so callers can't forget it (both current paths do this manually — easy to get wrong).
|
|
219
|
+
- **No wasted acquisition** — `measure` runs once per visited position; the end-of-pass park is a pure `move`.
|
|
220
|
+
- **`measure(pos)` takes the commanded position** so the recorded `working_distance` is the requested value, not a re-read of (possibly drifted) hardware state.
|
|
221
|
+
|
|
222
|
+
### Caveats (bake into defaults)
|
|
223
|
+
|
|
224
|
+
- **Hill-climb assumes a unimodal curve.** Noise or a local dip triggers the greedy stop early. Natural config: **coarse = `SWEEP` (global), fine = `HILL_CLIMB` (fast local refinement)** — exactly the two-pass shape we already have.
|
|
225
|
+
- **Eval count is bounded** by `search_range / step_size` either way, so hill-climb never costs more than a sweep and usually far less.
|
|
226
|
+
- Always evaluating `center` first guarantees the result is no worse than "stay put."
|
|
227
|
+
|
|
228
|
+
### Testing
|
|
229
|
+
|
|
230
|
+
Strategies never touch hardware, so they unit-test against a synthetic score curve with fake `move`/`measure` closures (e.g. a Gaussian peaked at a known WD) — no microscope, no Qt. Assert hill-climb converges within `step_size` of the peak and visits ≤ `n_steps + 1` positions.
|
|
231
|
+
|
|
232
|
+
### UI (optional, later)
|
|
233
|
+
|
|
234
|
+
A small `QComboBox` as an extra control in each `_PassRowWidget` (the row infra already exists). Until then, default `SWEEP` keeps current behaviour and the field is editable only via the protocol/dict.
|
|
235
|
+
|
|
236
|
+
### Serialisation
|
|
237
|
+
|
|
238
|
+
`strategy` is a `(str, Enum)` field on `FocusSweepPass`, so `dataclasses.asdict` serialises it directly; `_sweep_pass_from_dict` reads it with a `SWEEP` default for backward compatibility.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Alternatives considered
|
|
243
|
+
|
|
244
|
+
| Decision | Chosen | Rejected | Why |
|
|
245
|
+
|---|---|---|---|
|
|
246
|
+
| Strategy granularity | **Per-pass** (`FocusSweepPass.strategy`) | Per-run (`AutoFocusSettings.strategy`) | Per-pass lets coarse stay a global sweep while fine refines via hill-climb — the common case. A per-run flag couldn't express that mix. |
|
|
247
|
+
| Strategy mechanism | **Plain functions over an `evaluate` callback** | Reinstate a strategy class hierarchy (the deleted `fm.strategy` ABC + generics + pydantic) | That layer added 460 lines and indirection with no real polymorphism. A function + enum value is the whole cost of a new strategy. |
|
|
248
|
+
| Iteration image type | **`np.ndarray`** | `FibsemImage` | The focus metric only needs the pixel array; carrying full metadata coupled the canonical type to FIB-SEM imaging and bloated `save`. |
|
|
249
|
+
| FM source compatibility | **Re-export canonical types from `fm.structures`** | Edit every `from fibsem.fm.structures import ...` call site | Re-export is a one-line change per type and keeps the migration reviewable; call sites stay untouched. |
|
|
250
|
+
| Cancellation plumbing | **`measure` raises; run fn catches** | Thread a `stop_event` / return-sentinel through every strategy | Keeps strategies pure and puts the single check at the single I/O point. |
|
|
251
|
+
|
|
252
|
+
## Known gaps / open questions
|
|
253
|
+
|
|
254
|
+
- **Tileset acquisition ignores the coarse pass.** `fm/acquisition.py` builds one `ZParameters` from the *last enabled pass* and reuses it for **all** modes (`ONCE`, `EACH_ROW`, `EACH_TILE`), so a configured coarse pass never runs during tiling — contradicting the code's own "coarse only initially" comment. Intended follow-up: `ONCE` → `run_coarse_fine_autofocus` (full passes); per-row/per-tile → fine pass only. Deferred deliberately (behaviour change).
|
|
255
|
+
- **`AutofocusWidget` channel sync.** `set_autofocus_settings` / `update_channels` emit `settings_changed` inconsistently and don't reconcile a `channel_name` that is `None` or no longer in the channel list (combo and model can disagree). Low impact; needs a channel to be removed/renamed mid-session.
|
|
256
|
+
- **Two focus-quality entry points.** FIB-SEM scores via `get_focus_measure_function(...)` on `filtered_data`; FM via `calculate_focus_quality(...)`. The driver unifies the *sweep*, but the scoring call still differs per domain — fine for now, but a candidate for a single `score(image, method)` once the driver lands.
|
|
257
|
+
- **Future strategies the framework enables** (each is one function + enum value): golden-section search, parabolic-fit refinement around the running best, adaptive step (halve `step_size` near the peak).
|
|
258
|
+
|
|
259
|
+
## Non-goals
|
|
260
|
+
|
|
261
|
+
- New focus *metrics* (the `FocusMethod` set is unchanged).
|
|
262
|
+
- Changing acquisition cadence or the autofocus *scheduling* modes (`AutoFocusMode`).
|
|
263
|
+
- A general optimiser framework — strategies are deliberately small, 1-D, bounded searches over working distance.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Scope summary
|
|
268
|
+
|
|
269
|
+
| Change | Files | Effort |
|
|
270
|
+
|---|---|---|
|
|
271
|
+
| `FocusStrategy` enum + `FocusSweepPass.strategy` + serialisation | `autofunctions/autofocus.py` | Small |
|
|
272
|
+
| `_run_pass` + `_sweep`/`_hill_climb` driver | `autofunctions/autofocus.py` | Small |
|
|
273
|
+
| FIB-SEM `run_auto_focus` → use driver | `autofunctions/autofocus.py` | Small |
|
|
274
|
+
| FM `run_coarse_fine_autofocus` → use driver | `fm/calibration/__init__.py` | Small |
|
|
275
|
+
| Strategy unit tests | `tests/...` | Small |
|
|
276
|
+
| Per-pass strategy combo (optional) | `ui/fm/widgets/autofocus_widget.py` | Medium |
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Task Scheduling for AutoLamella Workflows
|
|
2
|
+
|
|
3
|
+
## What Exists Today
|
|
4
|
+
|
|
5
|
+
Tasks can be scheduled to start at a specific date/time rather than running
|
|
6
|
+
immediately.
|
|
7
|
+
|
|
8
|
+
- **Data model** — `AutoLamellaTaskDescription.scheduled_at: Optional[datetime]`
|
|
9
|
+
(`fibsem/applications/autolamella/structures.py`), serialized as ISO strings in
|
|
10
|
+
`to_dict`/`from_dict`. `AutoLamellaWorkflowConfig.get_scheduled_at(task_name)`
|
|
11
|
+
looks it up by name.
|
|
12
|
+
- **Editor UI** — the task editor dialog (`WorkflowTaskEditorWidget`,
|
|
13
|
+
`fibsem/ui/widgets/workflow_task_editor_widget.py`) has a *Properties* panel with a
|
|
14
|
+
"Schedule start time" checkbox + a `QDateTimeEdit` (12-hour AM/PM, up/down step
|
|
15
|
+
arrows, no calendar popup). The picker is bounded to **now → now + 2 days**
|
|
16
|
+
(`_MAX_SCHEDULE_DAYS_AHEAD`); a live hint shows how far ahead the time is
|
|
17
|
+
("Starts 8h 30m from now …") and warns when a step is blocked by a bound.
|
|
18
|
+
- **Run-time wait** — `TaskManager._wait_until_scheduled(...)`
|
|
19
|
+
(`fibsem/applications/autolamella/workflows/tasks/manager.py`) blocks before the
|
|
20
|
+
task's `InProgress` status is emitted, in an interruptible loop
|
|
21
|
+
(`while not self.is_stopped`). It emits a ~15s countdown to the **bottom status bar**
|
|
22
|
+
via `update_status_ui(..., status_bar=msg)` → `workflow_update_signal` →
|
|
23
|
+
`AutoLamellaMainUI._on_workflow_update`.
|
|
24
|
+
- **Cancel during wait** — the Stop button is shown as soon as the workflow starts
|
|
25
|
+
(`set_workflow_running()` in `_on_run_workflow_clicked`), so a scheduled-but-not-yet-
|
|
26
|
+
started run is cancellable. Stop sets the manager's `_stop_event`, which the wait loop
|
|
27
|
+
checks.
|
|
28
|
+
|
|
29
|
+
## Deferred: "Resume Workflow Now" button
|
|
30
|
+
|
|
31
|
+
A status-bar button to skip the scheduled wait and start the task immediately, **without**
|
|
32
|
+
cancelling the run and **without** changing the saved `scheduled_at`. Discussed and
|
|
33
|
+
intentionally deferred — the need is real but infrequent, and the workaround (Stop → edit
|
|
34
|
+
task → uncheck schedule → Apply → Run) exists. Add it when an operator actually wants it.
|
|
35
|
+
|
|
36
|
+
### Why a new event (not reuse Stop)
|
|
37
|
+
|
|
38
|
+
`_stop_event` cancels the run (the outer `while not self.is_stopped` loop exits, no task
|
|
39
|
+
runs). "Resume Now" must end the wait *and then run the task*, so it needs its own
|
|
40
|
+
event — on skip, `is_stopped` stays False and `_run_queue` falls through to run the task.
|
|
41
|
+
|
|
42
|
+
### Implementation sketch (~25 lines, no new threads)
|
|
43
|
+
|
|
44
|
+
1. **`manager.py` — `TaskManager`**
|
|
45
|
+
- Add `self._skip_wait_event = threading.Event()` in `__init__`; add `skip_wait()` →
|
|
46
|
+
`self._skip_wait_event.set()` (mirrors `stop()`).
|
|
47
|
+
- In `_wait_until_scheduled`: clear the event on entry; change the loop guard to
|
|
48
|
+
`while not self.is_stopped and not self._skip_wait_event.is_set():`. The existing
|
|
49
|
+
`if self.is_stopped: break` in `_run_queue` is unchanged — on skip it falls through
|
|
50
|
+
and runs the task. Clearing on entry scopes the skip to the *current* wait, so a
|
|
51
|
+
later scheduled task still waits (see decision 1).
|
|
52
|
+
2. **`workflows/ui.py`** — add a `waiting: bool = False` flag to `update_status_ui`,
|
|
53
|
+
included in the emitted dict; the manager passes `waiting=True` on its countdown emits.
|
|
54
|
+
3. **`AutoLamellaUI.py`** — add `skip_scheduled_wait()` mirroring `stop_task_workflow`:
|
|
55
|
+
guard on `is_workflow_running` / `_task_manager is not None`, then
|
|
56
|
+
`self._task_manager.skip_wait()`.
|
|
57
|
+
4. **`AutoLamellaMainUI.py`**
|
|
58
|
+
- In `_create_status_bar`: create `self.resume_now_btn = QPushButton("Resume Workflow Now")`,
|
|
59
|
+
hidden by default, `addPermanentWidget` next to `stop_workflow_btn`, connect to a
|
|
60
|
+
handler that calls `self.autolamella_ui.skip_scheduled_wait()`.
|
|
61
|
+
- In `_on_workflow_update`: `self.resume_now_btn.setVisible(bool(info.get("waiting")))`;
|
|
62
|
+
hide it once a real task `status` dict arrives (task started).
|
|
63
|
+
- Hide it in `hide_workflow_running()` and `_on_workflow_finished()`. Do NOT show it in
|
|
64
|
+
`set_workflow_running()` (that fires at run start, before any wait).
|
|
65
|
+
|
|
66
|
+
Alternative to the `waiting` flag: a dedicated `scheduled_wait_signal(bool)` on
|
|
67
|
+
`AutoLamellaUI` — cleaner separation, slightly more plumbing. The flag-on-existing-signal
|
|
68
|
+
matches how the countdown message is already routed.
|
|
69
|
+
|
|
70
|
+
### Decisions to settle before building
|
|
71
|
+
|
|
72
|
+
1. **Scope** — skip only the current wait (recommended; clear the event each wait) vs. skip
|
|
73
|
+
all remaining scheduled waits this run (don't clear).
|
|
74
|
+
2. **Confirmation** — Stop has a Yes/No dialog; Resume Now is non-destructive, so likely one
|
|
75
|
+
click, no dialog.
|
|
76
|
+
3. **Persistence** — must NOT clear `task.scheduled_at`; the schedule stays in the protocol
|
|
77
|
+
for next time.
|
|
78
|
+
4. **Styling/label** — `SECONDARY_BUTTON_STYLESHEET` vs `PRIMARY`; "Resume Workflow Now" vs
|
|
79
|
+
"Start Now".
|
|
80
|
+
|
|
81
|
+
### Testing
|
|
82
|
+
|
|
83
|
+
- **Unit (manager, headless)** — start a wait far in the future on a worker thread, call
|
|
84
|
+
`skip_wait()` from the main thread, assert the wait returns promptly and `is_stopped` is
|
|
85
|
+
False (task proceeds). Assert a fresh wait re-arms (current-wait scope).
|
|
86
|
+
- **Manual UI** — schedule a task ~10 min out, Run → "Resume Workflow Now" appears beside
|
|
87
|
+
Stop with the countdown → click it → task starts immediately, button disappears, run
|
|
88
|
+
continues. Confirm Stop still cancels during the wait and `scheduled_at` is unchanged.
|
|
@@ -6,6 +6,7 @@ from pprint import pprint
|
|
|
6
6
|
|
|
7
7
|
import fibsem
|
|
8
8
|
from fibsem import acquire, milling, utils, alignment
|
|
9
|
+
from fibsem.alignment import AlignmentSubsystem
|
|
9
10
|
from fibsem.structures import BeamType, ImageSettings, FibsemRectangleSettings
|
|
10
11
|
import numpy as np
|
|
11
12
|
|
|
@@ -57,10 +58,15 @@ def main():
|
|
|
57
58
|
eb_image = acquire.new_image(microscope, settings.image)
|
|
58
59
|
|
|
59
60
|
|
|
60
|
-
# align
|
|
61
|
+
# align to the previous slice (stage movement)
|
|
61
62
|
if ref_eb is not None:
|
|
62
|
-
alignment.
|
|
63
|
-
|
|
63
|
+
alignment.multi_step_alignment_v2(
|
|
64
|
+
microscope=microscope,
|
|
65
|
+
ref_image=ref_eb,
|
|
66
|
+
steps=3,
|
|
67
|
+
subsystem=AlignmentSubsystem.STAGE,
|
|
68
|
+
)
|
|
69
|
+
ref_eb = eb_image
|
|
64
70
|
|
|
65
71
|
|
|
66
72
|
# update patterns
|
|
@@ -4,7 +4,8 @@ import copy
|
|
|
4
4
|
import os
|
|
5
5
|
from typing import Optional, Tuple
|
|
6
6
|
|
|
7
|
-
from fibsem.
|
|
7
|
+
from fibsem.autofunctions import gamma as autogamma
|
|
8
|
+
from fibsem.autofunctions.acb import run_auto_contrast_brightness
|
|
8
9
|
from fibsem.microscope import FibsemMicroscope
|
|
9
10
|
from fibsem.structures import (
|
|
10
11
|
BeamType,
|
|
@@ -39,8 +40,9 @@ def new_image(
|
|
|
39
40
|
# run autocontrast
|
|
40
41
|
if settings.autocontrast:
|
|
41
42
|
microscope.autocontrast(
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
beam_type=settings.beam_type,
|
|
44
|
+
reduced_area=settings.reduced_area
|
|
45
|
+
)
|
|
44
46
|
|
|
45
47
|
# acquire the image
|
|
46
48
|
image = microscope.acquire_image(
|
|
@@ -291,6 +293,9 @@ def acquire_focus_stacked_image(
|
|
|
291
293
|
image = acquire_image(microscope, image_settings)
|
|
292
294
|
images.append(image)
|
|
293
295
|
|
|
296
|
+
# restore full-frame scanning mode
|
|
297
|
+
microscope.set_full_frame_scanning_mode(image_settings.beam_type)
|
|
298
|
+
|
|
294
299
|
# stack images vertically
|
|
295
300
|
arr = np.vstack([img.data for img in images])
|
|
296
301
|
|