driftlessmap 1.5.0__tar.gz → 1.6.1__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.
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/CITATION.cff +2 -2
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/MANUAL.md +73 -10
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/PKG-INFO +7 -5
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/README.md +5 -4
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/UpdateLog.md +10 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/WhatsNew.md +74 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/app.py +203 -4
- driftlessmap-1.6.1/driftlessmap/atlas_matching.py +558 -0
- driftlessmap-1.6.1/driftlessmap/auto_registration.py +348 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/main_window.ui +19 -0
- driftlessmap-1.6.1/driftlessmap/section_suggestion_dialog.py +177 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/slice_stacks.py +3 -1
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/version.py +1 -1
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap.egg-info/PKG-INFO +7 -5
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap.egg-info/SOURCES.txt +5 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap.egg-info/requires.txt +1 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/pyproject.toml +3 -0
- driftlessmap-1.6.1/tests/test_atlas_matching.py +246 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_atlas_view.py +9 -0
- driftlessmap-1.6.1/tests/test_auto_registration.py +185 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_packaging_metadata.py +1 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_project_persistence.py +80 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_version.py +1 -1
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/AUTHOR.txt +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/CONTRIBUTING.md +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/CONTRIBUTORS.md +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/LICENSE.txt +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/MANIFEST.in +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/ORIGINS.md +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/THANKS.txt +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/__init__.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/__main__.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/about.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/allen_downloader.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/atlas_downloader.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/atlas_loader.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/atlas_processor.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/atlas_transform.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/atlas_view.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/background.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/cell_detection.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/coordinate_validation.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/czi_reader.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/data/atlas_labels.pkl +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/data/query.csv +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/download_utils.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/app/driftlessmap.icns +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/app/driftlessmap.ico +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/app/driftlessmap.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/backward.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/dot.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/down-arrow.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/fast_backward.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/fast_forward.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/forward.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/layers/add.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/layers/ai.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/layers/eye_off.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/layers/eye_on.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/layers/eye_white.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/layers/hi.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/layers/trash.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/object.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/add.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/atlascontrol.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/atlascontrol.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/bnd.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/c_section.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/c_section2.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/cell.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/check.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/compare.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/contour.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/h_section.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/info.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/layers.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/layers.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/line.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/link.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/link_off.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/merge.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/object.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/probe.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/probe.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/rotation_horizontal.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/rotation_vertical.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/s_section.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/tool.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/tool.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/trash.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/tree_checked.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/treeview.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/treeview.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/treeview2.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/sidebar/virus.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/tdown.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/accept.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/accept2.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/aim.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/aim_not.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/anchor.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/anticlockwise_rotation.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/atlas_icon.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/boundary_register.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/cancel.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/cell_select.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/cell_select_not.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/check.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/clockwise_rotation.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/closed_path.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/closed_path2 copy.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/closed_path2.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/eraser.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/eraser.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/eye.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/eye_closed.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/fill.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/gps.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/h_flip.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/handle.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/image_icon.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/image_icon.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/info.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/inpart.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/inpart.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/lasso.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/lasso.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/left90.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/line.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/line_sites.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/linear_silicon.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/linear_silicon.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/list.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/location.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/magic-wand.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/magic_white.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/mask.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/match.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/matchbnd.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/matching.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/merge.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/move_down.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/move_left.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/move_right.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/move_up.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/moving.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/multi-probe.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/multi_pencil.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/multi_probe.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/object.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/open_path.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/outpart.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/outpart.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/pencil.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/pencil.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/plasso.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/probe.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/radar.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/rotation.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/rotation_clockwise.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/rotation_counter_clockwise.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/ruler.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/separate_sites.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/single_pencil.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/toa.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/toa_delete.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/toaa.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/toh.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/toh_delete.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/tohh.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/trans.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/trans.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/triangulation.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/two_window.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/unmerge.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/v_flip.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/virus.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/virus_register.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/vis2d.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/window2.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/window3.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/toolbar/window4.png +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/tree_close.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/tree_open.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/icons/up-arrow.svg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/image_curves.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/image_reader.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/image_stacks.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/image_view.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/label_tree.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/landmarks.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/layer_geometry.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/layer_validation.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/layers_control.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/movable_points.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/obj_items.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/object_control.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/persistence.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/probe_csv.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/probe_reconstruction.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/probe_utiles.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/project_io.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/provenance.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/atlas_view_group_box.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/box_label.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/channel_selector.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/color_combo.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/decor_label.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/dialogs.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/hidden_line_edit.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/label_tree.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/main_window.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/menu_bar.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/multi_handle_slider.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/obj_ctrl_bottom_button.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/object_text_button.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/page_control.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/rotation_button.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/side_bar.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/spinbox.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/tabs.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/qss/tool_bar.qss +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/resources.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/roi_analysis.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/run_driftlessmap.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/slice_validation.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/toolbox.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/triangulation.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/user_settings.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/utils.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/widgets_utils.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap/wtiles.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap.egg-info/dependency_links.txt +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap.egg-info/entry_points.txt +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/driftlessmap.egg-info/top_level.txt +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/setup.cfg +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/setup.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/atlas_fixture.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/run_test_suite.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_allen_downloader.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_atlas_cache_integrity.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_atlas_loader.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_atlas_transform.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_atlas_workers.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_background.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_cell_detection.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_coordinate_validation.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_czi_reader.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_download_utils.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_editing_tools.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_histogram_data.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_image_geometry.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_image_reader.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_label_tree.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_landmarks.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_layer_transforms.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_layer_validation.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_layers_control.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_mesh_cache.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_object_control.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_persistence.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_probe_csv.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_probe_dialogs.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_probe_mapping.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_probe_reconstruction.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_project_io.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_provenance.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_roi_analysis.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_runtime_paths.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_slice_validation.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_triangulation.py +0 -0
- {driftlessmap-1.5.0 → driftlessmap-1.6.1}/tests/test_widgets.py +0 -0
|
@@ -4,8 +4,8 @@ message: >-
|
|
|
4
4
|
HERBS paper listed under references.
|
|
5
5
|
title: DriftlessMap
|
|
6
6
|
type: software
|
|
7
|
-
version: 1.
|
|
8
|
-
date-released: 2026-09-
|
|
7
|
+
version: 1.6.1
|
|
8
|
+
date-released: 2026-09-28
|
|
9
9
|
authors:
|
|
10
10
|
- name: Mohebi & Associates
|
|
11
11
|
website: https://www.mohebi-associates.org/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# DriftlessMap User Manual
|
|
2
2
|
|
|
3
|
-
This manual applies to **DriftlessMap 1.
|
|
3
|
+
This manual applies to **DriftlessMap 1.6.1**.
|
|
4
4
|
|
|
5
5
|
DriftlessMap - Histological E-data Registration in Brain Space - is a desktop
|
|
6
6
|
application for aligning rodent histology with a reference atlas, reconstructing
|
|
@@ -107,7 +107,7 @@ purposes. See [Saving, loading, and exporting](#18-saving-loading-and-exporting)
|
|
|
107
107
|
|
|
108
108
|
### 2.1 Requirements
|
|
109
109
|
|
|
110
|
-
DriftlessMap 1.
|
|
110
|
+
DriftlessMap 1.6.1 requires:
|
|
111
111
|
|
|
112
112
|
- A 64-bit operating system and 64-bit Python 3.10 or newer.
|
|
113
113
|
- Python 3.10-3.14 for the core application.
|
|
@@ -126,7 +126,7 @@ page. The macOS DMG (`-macOS-arm64.dmg`) is built for Apple Silicon; on an Intel
|
|
|
126
126
|
Mac, use the developer installation below.
|
|
127
127
|
The desktop builds include Python and all runtime dependencies. Windows users
|
|
128
128
|
extract the entire ZIP and run `DriftlessMap.exe`; macOS users open the DMG and
|
|
129
|
-
drag `DriftlessMap.app` to Applications. The 1.
|
|
129
|
+
drag `DriftlessMap.app` to Applications. The 1.6.1 release is unsigned, so the
|
|
130
130
|
first launch may require Windows SmartScreen confirmation or Control-clicking
|
|
131
131
|
the macOS app and choosing **Open**.
|
|
132
132
|
|
|
@@ -174,7 +174,7 @@ python -m pip --version
|
|
|
174
174
|
python -c "import driftlessmap; print(driftlessmap.__version__)"
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
-
The final command should print `1.
|
|
177
|
+
The final command should print `1.6.1`.
|
|
178
178
|
|
|
179
179
|
### 2.5 Launching DriftlessMap
|
|
180
180
|
|
|
@@ -714,7 +714,68 @@ probe, virus, cell, contour, and drawing transfer.
|
|
|
714
714
|
4. Show **Volume + Histology** or **Slice + Histology**.
|
|
715
715
|
5. Avoid resizing or rotating the source image after placing landmarks.
|
|
716
716
|
|
|
717
|
-
### 8.2
|
|
717
|
+
### 8.2 Suggest the section and landmarks automatically
|
|
718
|
+
|
|
719
|
+
DriftlessMap can propose a starting point for registration with a volume
|
|
720
|
+
atlas. Both steps are suggestions: always review the result before
|
|
721
|
+
transferring anything.
|
|
722
|
+
|
|
723
|
+
**Atlas > Suggest Atlas Section...** compares the loaded histology with the
|
|
724
|
+
atlas and ranks candidate sections:
|
|
725
|
+
|
|
726
|
+
1. Load the volume atlas and the histology section. A single, whole section
|
|
727
|
+
on a plain background works best; the tissue outline is found by
|
|
728
|
+
thresholding.
|
|
729
|
+
2. Choose **Atlas > Suggest Atlas Section...**. The comparison runs in the
|
|
730
|
+
background and usually takes a few seconds.
|
|
731
|
+
3. The dialog reports the most likely plane (coronal, sagittal or horizontal)
|
|
732
|
+
and how clearly it was preferred (**clear**, **uncertain** or
|
|
733
|
+
**ambiguous**), the orientation the section needs, and up to six candidate
|
|
734
|
+
sections. Each shows your section on the left and the atlas on the right,
|
|
735
|
+
with its depth and cutting-angle tilt.
|
|
736
|
+
4. Pick the candidate that looks best. Brain outlines are left-right
|
|
737
|
+
symmetric, so the hemisphere cannot be detected: choose **Other
|
|
738
|
+
hemisphere** if the section comes from the other side.
|
|
739
|
+
5. Leave **Apply the suggested cutting-angle tilt** on to use the tilt, and
|
|
740
|
+
**Rotate/flip the histology to match** on to orient the image. Rotating
|
|
741
|
+
the histology resets its landmarks.
|
|
742
|
+
6. Press **Apply**. DriftlessMap switches to the plane, shows the section and
|
|
743
|
+
sets the tilt. For coronal and horizontal sections the sagittal pivot is
|
|
744
|
+
moved to the midline.
|
|
745
|
+
|
|
746
|
+
The plane is found from the outline, the depth mainly from internal anatomy,
|
|
747
|
+
and the tilt from a small search of about ±6°. Damaged or partial sections,
|
|
748
|
+
sections with more than one piece of tissue, and strongly uneven staining make
|
|
749
|
+
suggestions less reliable.
|
|
750
|
+
|
|
751
|
+
**Atlas > Propose Landmarks** then fits the displayed atlas slice to the
|
|
752
|
+
section and fills the Triangulation tool with paired landmarks:
|
|
753
|
+
|
|
754
|
+
1. Show the matching atlas slice and orient the histology to it, for example
|
|
755
|
+
with **Suggest Atlas Section...**. Remove any transform overlay first.
|
|
756
|
+
2. Choose **Atlas > Propose Landmarks**. If landmarks already exist, you are
|
|
757
|
+
asked before they are replaced.
|
|
758
|
+
3. DriftlessMap fits the outlines, then refines the fit on the image
|
|
759
|
+
intensities where that improves the match. It suggests up to 10 landmarks:
|
|
760
|
+
up to 5 at the sharpest tips and notches of the outline, snapped onto the
|
|
761
|
+
section outline, and the rest on strong internal edges that both images
|
|
762
|
+
show, such as the corpus callosum. It moves the boundary anchors with the
|
|
763
|
+
same fit. The landmarks are suggestions to confirm and edit.
|
|
764
|
+
4. The status bar reports how many pairs are on the outline and how many are
|
|
765
|
+
on internal edges, and the outline overlap. The
|
|
766
|
+
Triangulation tool opens so you can check the mesh. Drag any landmark that
|
|
767
|
+
is off, add more where the anatomy needs them, and check mesh quality
|
|
768
|
+
(Section 8.5) before transferring.
|
|
769
|
+
|
|
770
|
+
The fit follows the outline and the overall shape well, but internal
|
|
771
|
+
boundaries can still be several voxels off. Treat the proposal as a first
|
|
772
|
+
draft of the manual landmarks, not as a finished registration.
|
|
773
|
+
|
|
774
|
+
The tutorial [Automatic Section Matching and Landmark Proposal](Tutorial/Registration_Related/automatic_section_and_landmarks.md)
|
|
775
|
+
walks through both steps on a real section, with screenshots, and explains
|
|
776
|
+
how each stage works.
|
|
777
|
+
|
|
778
|
+
### 8.3 Place paired landmarks
|
|
718
779
|
|
|
719
780
|
1. Activate Triangulation.
|
|
720
781
|
2. Choose a point color visible in both windows.
|
|
@@ -741,7 +802,7 @@ Landmarks can be dragged. With Eraser active, clicking a numbered landmark
|
|
|
741
802
|
deletes the corresponding point in both windows and renumbers the remaining
|
|
742
803
|
pairs.
|
|
743
804
|
|
|
744
|
-
### 8.
|
|
805
|
+
### 8.4 Match boundary rectangles
|
|
745
806
|
|
|
746
807
|
The automatically generated outer points define the warp domain. After
|
|
747
808
|
interior points are placed, use **Match Boundaries** when the atlas and
|
|
@@ -751,7 +812,7 @@ anchors while retaining the paired interior anatomy.
|
|
|
751
812
|
For a volume atlas, boundary matching can derive the atlas extent from the
|
|
752
813
|
nonzero label area. A slice atlas requires interior landmarks in both images.
|
|
753
814
|
|
|
754
|
-
### 8.
|
|
815
|
+
### 8.5 Evaluate mesh quality
|
|
755
816
|
|
|
756
817
|
The Triangulation controls report:
|
|
757
818
|
|
|
@@ -773,7 +834,7 @@ To repair a mesh:
|
|
|
773
834
|
- Confirm that pair order has not been confused.
|
|
774
835
|
- Recheck the atlas slice and tilt.
|
|
775
836
|
|
|
776
|
-
### 8.
|
|
837
|
+
### 8.6 Create and refine an overlay
|
|
777
838
|
|
|
778
839
|
To overlay histology onto the atlas:
|
|
779
840
|
|
|
@@ -793,7 +854,7 @@ repeatedly warping an already transformed preview, preventing accumulated blur.
|
|
|
793
854
|
Atlas labels and masks use nearest-neighbor mapping where discrete values must
|
|
794
855
|
be preserved; histology display uses smooth interpolation.
|
|
795
856
|
|
|
796
|
-
### 8.
|
|
857
|
+
### 8.7 Transfer annotations
|
|
797
858
|
|
|
798
859
|
Once the registration is accepted:
|
|
799
860
|
|
|
@@ -812,7 +873,7 @@ Points outside the registration mesh cannot be assigned a valid atlas
|
|
|
812
873
|
coordinate. DriftlessMap preserves or rejects them according to the data type and
|
|
813
874
|
reports the count; do not silently treat them as registered.
|
|
814
875
|
|
|
815
|
-
### 8.
|
|
876
|
+
### 8.8 Save registration landmarks
|
|
816
877
|
|
|
817
878
|
Use:
|
|
818
879
|
|
|
@@ -1488,6 +1549,8 @@ still read when a DriftlessMap setting has not been created.
|
|
|
1488
1549
|
| Download Waxholm Rat Atlas | Download/process standard rat atlas. |
|
|
1489
1550
|
| Download Allen Mice Atlas | Download/process Allen 10, 25, or 50 um atlas. |
|
|
1490
1551
|
| Atlas Processor | Process a custom volume atlas. |
|
|
1552
|
+
| Suggest Atlas Section... | Rank atlas plane, section, tilt and orientation for the loaded histology. |
|
|
1553
|
+
| Propose Landmarks | Fit the shown atlas slice to the histology and fill in registration landmarks. |
|
|
1491
1554
|
| Save/Load Triangulation Points | Write/read `.dmaptri`. |
|
|
1492
1555
|
| Load Slice | Load a raw or processed 2D atlas plate. |
|
|
1493
1556
|
| Register Slice Info | Set plane, dimensions, and Bregma distance. |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: driftlessmap
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.6.1
|
|
4
4
|
Summary: Interactive histology registration and brain-atlas mapping
|
|
5
5
|
Author: Pearl Saldanha, Jacopo Paglia, Jonathan R. Whitlock, Mohebi & Associates, Ali Mohebi
|
|
6
6
|
Author-email: Jingyi Guo Fuglstad <jingyi.g.fuglstad@gmail.com>
|
|
@@ -44,6 +44,7 @@ Requires-Dist: tifffile>=2024.7
|
|
|
44
44
|
Requires-Dist: pandas<4,>=2.2
|
|
45
45
|
Requires-Dist: natsort<9,>=8.4
|
|
46
46
|
Requires-Dist: imagecodecs>=2024.6
|
|
47
|
+
Requires-Dist: SimpleITK<3,>=2.3
|
|
47
48
|
Provides-Extra: czi
|
|
48
49
|
Requires-Dist: aicspylibczi>=3.3.1; python_version < "3.14" and extra == "czi"
|
|
49
50
|
Provides-Extra: test
|
|
@@ -95,6 +96,7 @@ See [CITATION.cff](CITATION.cff) for machine-readable citation metadata.
|
|
|
95
96
|
|
|
96
97
|
- 2D and 3D visualization of volumetric brain atlases and arbitrary slices.
|
|
97
98
|
- Interactive histology-to-atlas registration with local elastic deformation.
|
|
99
|
+
- Automatic suggestions for the matching atlas section and starting landmarks.
|
|
98
100
|
- Probe planning, reconstruction, contact mapping, and CSV export.
|
|
99
101
|
- Drawing, cell, virus-expression, and user-defined object workflows.
|
|
100
102
|
- Safe, versioned project and object archives.
|
|
@@ -102,7 +104,7 @@ See [CITATION.cff](CITATION.cff) for machine-readable citation metadata.
|
|
|
102
104
|
|
|
103
105
|
## Installation
|
|
104
106
|
|
|
105
|
-
DriftlessMap 1.
|
|
107
|
+
DriftlessMap 1.6.1 is available as a desktop application for end users and as
|
|
106
108
|
a Python package for developers.
|
|
107
109
|
|
|
108
110
|
### Mode 1: desktop application for end users
|
|
@@ -110,10 +112,10 @@ a Python package for developers.
|
|
|
110
112
|
No Python or Conda installation is required. Download the asset for your
|
|
111
113
|
computer from [GitHub Releases](https://github.com/mohebi-n-associates/DriftlessMap/releases):
|
|
112
114
|
|
|
113
|
-
- **Windows 64-bit:** download `DriftlessMap-1.
|
|
115
|
+
- **Windows 64-bit:** download `DriftlessMap-1.6.1-Windows-x64.zip`, extract
|
|
114
116
|
the complete folder, and double-click `DriftlessMap.exe`. Do not move the
|
|
115
117
|
executable out of its extracted folder.
|
|
116
|
-
- **macOS (Apple Silicon):** download `DriftlessMap-1.
|
|
118
|
+
- **macOS (Apple Silicon):** download `DriftlessMap-1.6.1-macOS-arm64.dmg`,
|
|
117
119
|
open it, and drag `DriftlessMap.app` to Applications. The application bundle
|
|
118
120
|
includes the DriftlessMap icon and all Python dependencies. Intel Macs are
|
|
119
121
|
not covered by the desktop build; use the Conda/pip installation below.
|
|
@@ -137,7 +139,7 @@ malware:
|
|
|
137
139
|
required only for the first launch.
|
|
138
140
|
|
|
139
141
|
Only use **Open Anyway** for a copy downloaded from the
|
|
140
|
-
[official DriftlessMap 1.
|
|
142
|
+
[official DriftlessMap 1.6.1 release](https://github.com/mohebi-n-associates/DriftlessMap/releases/tag/v1.6.1).
|
|
141
143
|
The official macOS DMG has this SHA-256 digest:
|
|
142
144
|
|
|
143
145
|
```text
|
|
@@ -38,6 +38,7 @@ See [CITATION.cff](CITATION.cff) for machine-readable citation metadata.
|
|
|
38
38
|
|
|
39
39
|
- 2D and 3D visualization of volumetric brain atlases and arbitrary slices.
|
|
40
40
|
- Interactive histology-to-atlas registration with local elastic deformation.
|
|
41
|
+
- Automatic suggestions for the matching atlas section and starting landmarks.
|
|
41
42
|
- Probe planning, reconstruction, contact mapping, and CSV export.
|
|
42
43
|
- Drawing, cell, virus-expression, and user-defined object workflows.
|
|
43
44
|
- Safe, versioned project and object archives.
|
|
@@ -45,7 +46,7 @@ See [CITATION.cff](CITATION.cff) for machine-readable citation metadata.
|
|
|
45
46
|
|
|
46
47
|
## Installation
|
|
47
48
|
|
|
48
|
-
DriftlessMap 1.
|
|
49
|
+
DriftlessMap 1.6.1 is available as a desktop application for end users and as
|
|
49
50
|
a Python package for developers.
|
|
50
51
|
|
|
51
52
|
### Mode 1: desktop application for end users
|
|
@@ -53,10 +54,10 @@ a Python package for developers.
|
|
|
53
54
|
No Python or Conda installation is required. Download the asset for your
|
|
54
55
|
computer from [GitHub Releases](https://github.com/mohebi-n-associates/DriftlessMap/releases):
|
|
55
56
|
|
|
56
|
-
- **Windows 64-bit:** download `DriftlessMap-1.
|
|
57
|
+
- **Windows 64-bit:** download `DriftlessMap-1.6.1-Windows-x64.zip`, extract
|
|
57
58
|
the complete folder, and double-click `DriftlessMap.exe`. Do not move the
|
|
58
59
|
executable out of its extracted folder.
|
|
59
|
-
- **macOS (Apple Silicon):** download `DriftlessMap-1.
|
|
60
|
+
- **macOS (Apple Silicon):** download `DriftlessMap-1.6.1-macOS-arm64.dmg`,
|
|
60
61
|
open it, and drag `DriftlessMap.app` to Applications. The application bundle
|
|
61
62
|
includes the DriftlessMap icon and all Python dependencies. Intel Macs are
|
|
62
63
|
not covered by the desktop build; use the Conda/pip installation below.
|
|
@@ -80,7 +81,7 @@ malware:
|
|
|
80
81
|
required only for the first launch.
|
|
81
82
|
|
|
82
83
|
Only use **Open Anyway** for a copy downloaded from the
|
|
83
|
-
[official DriftlessMap 1.
|
|
84
|
+
[official DriftlessMap 1.6.1 release](https://github.com/mohebi-n-associates/DriftlessMap/releases/tag/v1.6.1).
|
|
84
85
|
The official macOS DMG has this SHA-256 digest:
|
|
85
86
|
|
|
86
87
|
```text
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Update Log
|
|
2
2
|
|
|
3
|
+
### 28th September 2026
|
|
4
|
+
##### DriftlessMap 1.6.1
|
|
5
|
+
|
|
6
|
+
Fixes **Show Boundary**, which drew atlas region boundaries almost black and therefore invisibly. **Propose Landmarks** now suggests up to 10 landmarks on features both images show (outline tips and notches, shared internal edges) instead of about 36. Adds a tutorial for the automatic section and landmark suggestions.
|
|
7
|
+
|
|
8
|
+
### 27th September 2026
|
|
9
|
+
##### DriftlessMap 1.6.0
|
|
10
|
+
|
|
11
|
+
Adds **Atlas > Suggest Atlas Section...**, which suggests the atlas plane, section, tilt and histology orientation for a loaded section. Also adds **Atlas > Propose Landmarks**, which fits the shown atlas slice to the histology and fills in registration landmarks for review. SimpleITK is now a required dependency.
|
|
12
|
+
|
|
3
13
|
### 27th September 2026
|
|
4
14
|
##### DriftlessMap 1.5.0
|
|
5
15
|
|
|
@@ -3,6 +3,80 @@
|
|
|
3
3
|
This cumulative release history is maintained as a single document. New
|
|
4
4
|
releases are added at the top; earlier release notes remain below them.
|
|
5
5
|
|
|
6
|
+
## DriftlessMap 1.6.1
|
|
7
|
+
|
|
8
|
+
Release date: 28 September 2026
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Show Boundary** now draws atlas region boundaries in white. Since the
|
|
13
|
+
boundary images were stored as one byte per pixel, they had been drawn
|
|
14
|
+
almost black, so the button appeared to do nothing.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **Propose Landmarks** now suggests up to 10 landmarks instead of about 36,
|
|
19
|
+
each on a feature you can see and check in both images:
|
|
20
|
+
- up to 5 at the sharpest tips and notches of the brain outline, snapped
|
|
21
|
+
onto the section outline;
|
|
22
|
+
- the rest on strong internal edges that both images show, such as the
|
|
23
|
+
corpus callosum and the ventricles.
|
|
24
|
+
|
|
25
|
+
An edge seen in only one image is never chosen: an atlas region border in
|
|
26
|
+
uniform-looking tissue, or a dye track in the section. The status bar says
|
|
27
|
+
how many points are on the outline and how many are internal. Confirm or
|
|
28
|
+
drag each point, and add more by hand where the anatomy needs them.
|
|
29
|
+
|
|
30
|
+
### Documentation
|
|
31
|
+
|
|
32
|
+
- A new tutorial, [Automatic Section Matching and Landmark Proposal](Tutorial/Registration_Related/automatic_section_and_landmarks.md),
|
|
33
|
+
walks through **Suggest Atlas Section...** and **Propose Landmarks** on a
|
|
34
|
+
real sagittal section and explains how each stage works.
|
|
35
|
+
|
|
36
|
+
## DriftlessMap 1.6.0
|
|
37
|
+
|
|
38
|
+
Release date: 27 September 2026
|
|
39
|
+
|
|
40
|
+
This release adds two assistants for volume-atlas registration. They suggest
|
|
41
|
+
where a section sits in the atlas and propose starting landmarks. You review
|
|
42
|
+
and confirm every suggestion; nothing is transferred automatically. Files
|
|
43
|
+
saved by 1.5.0 open unchanged, and nothing needs to be re-exported.
|
|
44
|
+
|
|
45
|
+
### Suggest Atlas Section
|
|
46
|
+
|
|
47
|
+
**Atlas > Suggest Atlas Section...** compares the loaded histology with the
|
|
48
|
+
volume atlas and suggests the section it came from:
|
|
49
|
+
|
|
50
|
+
- the plane (coronal, sagittal or horizontal), found from the tissue outline,
|
|
51
|
+
with a note on how clearly it was preferred;
|
|
52
|
+
- the orientation the histology needs (rotation and flip);
|
|
53
|
+
- the depth, ranked mainly by internal anatomy;
|
|
54
|
+
- a small cutting-angle tilt, searched within about ±6°.
|
|
55
|
+
|
|
56
|
+
A dialog shows up to six candidates as side-by-side thumbnails. Choose one and
|
|
57
|
+
press **Apply**: DriftlessMap switches the plane, shows the section and sets
|
|
58
|
+
the tilt, and can also rotate or flip the histology to match. Because brain
|
|
59
|
+
outlines are left-right symmetric, you choose the hemisphere yourself.
|
|
60
|
+
|
|
61
|
+
### Propose Landmarks
|
|
62
|
+
|
|
63
|
+
**Atlas > Propose Landmarks** fits the displayed atlas slice to the section.
|
|
64
|
+
It first fits the outlines, then refines the fit on image intensities where
|
|
65
|
+
that improves the match. It then fills the Triangulation tool with about 36
|
|
66
|
+
paired landmarks and moves the boundary anchors with the same fit. Drag,
|
|
67
|
+
add or delete landmarks as usual before transferring. Existing landmarks are
|
|
68
|
+
replaced only after you confirm.
|
|
69
|
+
|
|
70
|
+
The fit follows the outline and overall shape well. Internal boundaries can
|
|
71
|
+
still be several voxels off, so treat the proposal as a first draft.
|
|
72
|
+
|
|
73
|
+
### Other changes
|
|
74
|
+
|
|
75
|
+
- DriftlessMap now requires SimpleITK, which the desktop builds and a normal
|
|
76
|
+
`pip install` include.
|
|
77
|
+
- The Registering chapter of the manual gains Section 8.2, which describes
|
|
78
|
+
both assistants. Later sections in that chapter are renumbered.
|
|
79
|
+
|
|
6
80
|
## DriftlessMap 1.5.0
|
|
7
81
|
|
|
8
82
|
Release date: 27 September 2026
|
|
@@ -141,7 +141,10 @@ from .probe_reconstruction import (
|
|
|
141
141
|
source_vox_to_herbs_vox,
|
|
142
142
|
)
|
|
143
143
|
from .roi_analysis import build_drawing_roi_info
|
|
144
|
+
from .atlas_matching import suggest_sections
|
|
145
|
+
from .auto_registration import propose_landmarks
|
|
144
146
|
from .background import run_in_background
|
|
147
|
+
from .section_suggestion_dialog import SectionSuggestionDialog
|
|
145
148
|
from .landmarks import LANDMARK_FIELDS, LandmarkModel, triangulation_payload_error
|
|
146
149
|
from .project_io import (
|
|
147
150
|
default_working_atlas_data,
|
|
@@ -525,6 +528,8 @@ class DriftlessMap(QMainWindow, FORM_Main):
|
|
|
525
528
|
self.actionRegister_Slice_Info.triggered.connect(self.register_slice_info)
|
|
526
529
|
self.actionSave_Slice.triggered.connect(self.save_processed_slice)
|
|
527
530
|
self.actionSwitch_Atlas.triggered.connect(self.switch_atlas)
|
|
531
|
+
self.actionSuggest_Atlas_Section.triggered.connect(self.suggest_atlas_section)
|
|
532
|
+
self.actionPropose_Landmarks.triggered.connect(self.propose_registration_landmarks)
|
|
528
533
|
self.actionBregma_Picker.setCheckable(True)
|
|
529
534
|
self.actionBregma_Picker.triggered.connect(self.pick_bregma)
|
|
530
535
|
self.actionCreate_Slice_Layer.triggered.connect(self.process_slice)
|
|
@@ -1756,6 +1761,200 @@ class DriftlessMap(QMainWindow, FORM_Main):
|
|
|
1756
1761
|
"Current Slice is saved successfully.", self.normal_color
|
|
1757
1762
|
)
|
|
1758
1763
|
|
|
1764
|
+
def suggest_atlas_section(self):
|
|
1765
|
+
"""Suggest and apply the atlas plane, slice and tilt for the section."""
|
|
1766
|
+
if (
|
|
1767
|
+
self.current_atlas != "volume"
|
|
1768
|
+
or self.atlas_view.atlas_data is None
|
|
1769
|
+
or self.atlas_view.atlas_label is None
|
|
1770
|
+
):
|
|
1771
|
+
self.print_message(
|
|
1772
|
+
"Load a volume atlas before suggesting an atlas section.",
|
|
1773
|
+
self.error_message_color,
|
|
1774
|
+
)
|
|
1775
|
+
return
|
|
1776
|
+
if self.image_view.current_img is None:
|
|
1777
|
+
self.print_message(
|
|
1778
|
+
"Load a histology section before suggesting an atlas section.",
|
|
1779
|
+
self.error_message_color,
|
|
1780
|
+
)
|
|
1781
|
+
return
|
|
1782
|
+
view = self.atlas_view
|
|
1783
|
+
section = np.asarray(self.image_view.current_img)
|
|
1784
|
+
midline = int(view.origin_3d[0])
|
|
1785
|
+
# Tilts for coronal/horizontal pivot on the midline (see above); the
|
|
1786
|
+
# sagittal pivot is its own page, so its value here does not matter.
|
|
1787
|
+
pivot = (int(view.current_coronal_index), midline,
|
|
1788
|
+
int(view.current_horizontal_index))
|
|
1789
|
+
try:
|
|
1790
|
+
report = run_in_background(
|
|
1791
|
+
self,
|
|
1792
|
+
"Comparing the section with the atlas...",
|
|
1793
|
+
suggest_sections,
|
|
1794
|
+
section,
|
|
1795
|
+
view.atlas_label,
|
|
1796
|
+
view.atlas_data,
|
|
1797
|
+
midline,
|
|
1798
|
+
pivot,
|
|
1799
|
+
)
|
|
1800
|
+
except ValueError as exc:
|
|
1801
|
+
self.print_message(
|
|
1802
|
+
"No atlas section could be suggested: {}".format(exc),
|
|
1803
|
+
self.error_message_color,
|
|
1804
|
+
)
|
|
1805
|
+
return
|
|
1806
|
+
if not report.suggestions:
|
|
1807
|
+
self.print_message(
|
|
1808
|
+
"No atlas section could be suggested for this image.",
|
|
1809
|
+
self.error_message_color,
|
|
1810
|
+
)
|
|
1811
|
+
return
|
|
1812
|
+
dialog = SectionSuggestionDialog(
|
|
1813
|
+
report, section, view.atlas_data, pivot, view.vox_size_um, self
|
|
1814
|
+
)
|
|
1815
|
+
if dialog.exec() != QDialog.DialogCode.Accepted:
|
|
1816
|
+
return
|
|
1817
|
+
choice = dialog.choice()
|
|
1818
|
+
if choice is not None:
|
|
1819
|
+
self.apply_section_suggestion(*choice)
|
|
1820
|
+
|
|
1821
|
+
def apply_section_suggestion(self, plane, index, orientation, tilt, rotate_histology):
|
|
1822
|
+
"""Show ``plane``/``index`` at ``tilt`` and orient the histology."""
|
|
1823
|
+
view = self.atlas_view
|
|
1824
|
+
if rotate_histology:
|
|
1825
|
+
for _ in range(orientation.quarter_turns % 4):
|
|
1826
|
+
self.image_view.image_90_counter_rotate()
|
|
1827
|
+
if orientation.mirrored:
|
|
1828
|
+
self.image_view.image_horizon_flip()
|
|
1829
|
+
buttons = {"coronal": view.section_rabnt1, "sagittal": view.section_rabnt2,
|
|
1830
|
+
"horizontal": view.section_rabnt3}
|
|
1831
|
+
pages = {"coronal": view.cpage_ctrl, "sagittal": view.spage_ctrl,
|
|
1832
|
+
"horizontal": view.hpage_ctrl}
|
|
1833
|
+
rotations = {"coronal": view.crotation_ctrl, "sagittal": view.srotation_ctrl,
|
|
1834
|
+
"horizontal": view.hrotation_ctrl}
|
|
1835
|
+
buttons[plane].setChecked(True)
|
|
1836
|
+
if plane in ("coronal", "horizontal"):
|
|
1837
|
+
view.spage_ctrl.set_val(int(view.origin_3d[0]))
|
|
1838
|
+
pages[plane].set_val(int(index))
|
|
1839
|
+
rotation = rotations[plane]
|
|
1840
|
+
rotation.h_spinbox.setValue(float(tilt[0]))
|
|
1841
|
+
rotation.v_spinbox.setValue(float(tilt[1]))
|
|
1842
|
+
self.print_message(
|
|
1843
|
+
"Showing the suggested {} slice {} at tilt ({:+.1f}°, {:+.1f}°). "
|
|
1844
|
+
"Check the match before placing landmarks.".format(
|
|
1845
|
+
plane, index, tilt[0], tilt[1]
|
|
1846
|
+
),
|
|
1847
|
+
self.normal_color,
|
|
1848
|
+
)
|
|
1849
|
+
|
|
1850
|
+
def propose_registration_landmarks(self):
|
|
1851
|
+
"""Register the section to the displayed atlas slice and propose
|
|
1852
|
+
paired landmarks, which the user reviews with the triangulation tool."""
|
|
1853
|
+
if (
|
|
1854
|
+
self.current_atlas != "volume"
|
|
1855
|
+
or self.atlas_view.atlas_data is None
|
|
1856
|
+
or self.atlas_view.working_atlas.label_data is None
|
|
1857
|
+
):
|
|
1858
|
+
self.print_message(
|
|
1859
|
+
"Show a volume atlas slice before proposing landmarks.",
|
|
1860
|
+
self.error_message_color,
|
|
1861
|
+
)
|
|
1862
|
+
return
|
|
1863
|
+
if self.image_view.current_img is None:
|
|
1864
|
+
self.print_message(
|
|
1865
|
+
"Load a histology section before proposing landmarks.",
|
|
1866
|
+
self.error_message_color,
|
|
1867
|
+
)
|
|
1868
|
+
return
|
|
1869
|
+
if self.a2h_transferred or self.h2a_transferred:
|
|
1870
|
+
self.print_message(
|
|
1871
|
+
"Remove the current transform overlay before proposing landmarks.",
|
|
1872
|
+
self.error_message_color,
|
|
1873
|
+
)
|
|
1874
|
+
return
|
|
1875
|
+
if self.atlas_tri_inside_data or self.histo_tri_inside_data:
|
|
1876
|
+
reply = QMessageBox.question(
|
|
1877
|
+
self,
|
|
1878
|
+
"Propose Landmarks",
|
|
1879
|
+
"Replace the current registration landmarks with proposed ones?",
|
|
1880
|
+
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
|
1881
|
+
QMessageBox.StandardButton.No,
|
|
1882
|
+
)
|
|
1883
|
+
if reply != QMessageBox.StandardButton.Yes:
|
|
1884
|
+
return
|
|
1885
|
+
stack = self.atlas_view.working_atlas
|
|
1886
|
+
try:
|
|
1887
|
+
proposal = run_in_background(
|
|
1888
|
+
self,
|
|
1889
|
+
"Registering the section to the atlas slice...",
|
|
1890
|
+
propose_landmarks,
|
|
1891
|
+
np.asarray(stack.img.image),
|
|
1892
|
+
np.asarray(stack.label_data),
|
|
1893
|
+
np.asarray(self.image_view.current_img),
|
|
1894
|
+
boundary_points=np.asarray(self.atlas_tri_onside_data, dtype=float),
|
|
1895
|
+
)
|
|
1896
|
+
except (ValueError, RuntimeError) as exc:
|
|
1897
|
+
self.print_message(
|
|
1898
|
+
"Landmarks could not be proposed: {}".format(exc),
|
|
1899
|
+
self.error_message_color,
|
|
1900
|
+
)
|
|
1901
|
+
return
|
|
1902
|
+
if len(proposal.atlas_points) < 3:
|
|
1903
|
+
self.print_message(
|
|
1904
|
+
"Too few landmarks could be proposed; place them by hand.",
|
|
1905
|
+
self.error_message_color,
|
|
1906
|
+
)
|
|
1907
|
+
return
|
|
1908
|
+
self.apply_landmark_proposal(proposal)
|
|
1909
|
+
|
|
1910
|
+
def apply_landmark_proposal(self, proposal):
|
|
1911
|
+
"""Replace interior landmarks with a proposal and show them."""
|
|
1912
|
+
self._invalidate_triangulation(clear_topology=True)
|
|
1913
|
+
self.atlas_tri_inside_data = [
|
|
1914
|
+
[round(float(x), 2), round(float(y), 2)] for x, y in proposal.atlas_points
|
|
1915
|
+
]
|
|
1916
|
+
self.histo_tri_inside_data = [
|
|
1917
|
+
[round(float(x), 2), round(float(y), 2)] for x, y in proposal.histology_points
|
|
1918
|
+
]
|
|
1919
|
+
if len(proposal.boundary_points) == len(self.atlas_tri_onside_data):
|
|
1920
|
+
# Carry the mesh frame through the fit too, so the fixed frame
|
|
1921
|
+
# points do not contradict the interior landmarks.
|
|
1922
|
+
self.histo_tri_onside_data = [
|
|
1923
|
+
[round(float(x), 2), round(float(y), 2)]
|
|
1924
|
+
for x, y in proposal.boundary_points
|
|
1925
|
+
]
|
|
1926
|
+
self.atlas_tri_data = self.atlas_tri_onside_data + self.atlas_tri_inside_data
|
|
1927
|
+
self.histo_tri_data = self.histo_tri_onside_data + self.histo_tri_inside_data
|
|
1928
|
+
self.atlas_view.working_atlas.image_dict["tri_pnts"].setData(
|
|
1929
|
+
pos=np.asarray(self.atlas_tri_data)
|
|
1930
|
+
)
|
|
1931
|
+
self.image_view.img_stacks.image_dict["tri_pnts"].setData(
|
|
1932
|
+
pos=np.asarray(self.histo_tri_data)
|
|
1933
|
+
)
|
|
1934
|
+
self._refresh_triangulation_text("atlas")
|
|
1935
|
+
self._refresh_triangulation_text("image")
|
|
1936
|
+
# Show the proposal in the triangulation tool, ready for editing.
|
|
1937
|
+
button = self.tool_box.checkable_btn_dict["triang_btn"]
|
|
1938
|
+
if not button.isChecked():
|
|
1939
|
+
button.setChecked(True)
|
|
1940
|
+
self.triang_btn_clicked()
|
|
1941
|
+
if self.tool_box.triang_vis_btn.isChecked():
|
|
1942
|
+
self.update_atlas_tri_lines()
|
|
1943
|
+
self.update_histo_tri_lines()
|
|
1944
|
+
else:
|
|
1945
|
+
self._build_triangulation_registration(strict=False, show_error=False)
|
|
1946
|
+
stage = "outline and intensity" if proposal.deformable_used else "outline"
|
|
1947
|
+
on_outline = sum(kind == "outline" for kind in proposal.kinds)
|
|
1948
|
+
self.print_message(
|
|
1949
|
+
"Suggested {} landmark pairs ({} on the outline, {} on internal edges) "
|
|
1950
|
+
"from the {} fit (outline overlap {:.2f}). Confirm or drag each one "
|
|
1951
|
+
"before transferring.".format(
|
|
1952
|
+
len(proposal.atlas_points), on_outline,
|
|
1953
|
+
len(proposal.atlas_points) - on_outline, stage, proposal.overlap_final
|
|
1954
|
+
),
|
|
1955
|
+
self.normal_color,
|
|
1956
|
+
)
|
|
1957
|
+
|
|
1759
1958
|
def switch_atlas(self):
|
|
1760
1959
|
if (
|
|
1761
1960
|
self.atlas_view.atlas_data is None
|
|
@@ -2929,7 +3128,7 @@ class DriftlessMap(QMainWindow, FORM_Main):
|
|
|
2929
3128
|
True
|
|
2930
3129
|
)
|
|
2931
3130
|
if (
|
|
2932
|
-
self.
|
|
3131
|
+
self.working_atlas_text
|
|
2933
3132
|
and not self.working_atlas_text[0].isVisible()
|
|
2934
3133
|
):
|
|
2935
3134
|
for i in range(len(self.working_atlas_text)):
|
|
@@ -2938,7 +3137,7 @@ class DriftlessMap(QMainWindow, FORM_Main):
|
|
|
2938
3137
|
if not self.image_view.img_stacks.image_dict["tri_pnts"].isVisible():
|
|
2939
3138
|
self.image_view.img_stacks.image_dict["tri_pnts"].setVisible(True)
|
|
2940
3139
|
if (
|
|
2941
|
-
self.
|
|
3140
|
+
self.working_img_text
|
|
2942
3141
|
and not self.working_img_text[0].isVisible()
|
|
2943
3142
|
):
|
|
2944
3143
|
for i in range(len(self.working_img_text)):
|
|
@@ -2950,7 +3149,7 @@ class DriftlessMap(QMainWindow, FORM_Main):
|
|
|
2950
3149
|
False
|
|
2951
3150
|
)
|
|
2952
3151
|
if (
|
|
2953
|
-
self.
|
|
3152
|
+
self.working_atlas_text
|
|
2954
3153
|
and self.working_atlas_text[0].isVisible()
|
|
2955
3154
|
):
|
|
2956
3155
|
for i in range(len(self.working_atlas_text)):
|
|
@@ -2958,7 +3157,7 @@ class DriftlessMap(QMainWindow, FORM_Main):
|
|
|
2958
3157
|
if self.histo_tri_data:
|
|
2959
3158
|
if self.image_view.img_stacks.image_dict["tri_pnts"].isVisible():
|
|
2960
3159
|
self.image_view.img_stacks.image_dict["tri_pnts"].setVisible(False)
|
|
2961
|
-
if self.
|
|
3160
|
+
if self.working_img_text and self.working_img_text[0].isVisible():
|
|
2962
3161
|
for i in range(len(self.working_img_text)):
|
|
2963
3162
|
self.working_img_text[i].setVisible(False)
|
|
2964
3163
|
|