Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "pickmix"
version = "0.3.0"
version = "0.3.1"
description = "Multi-kind particle picking GUI for cryo-ET sub-tomogram averaging workflows."
readme = "README.md"
authors = [
Expand Down
20 changes: 14 additions & 6 deletions src/pickmix/gui/dialogs/kind_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class KindDialog(QDialog):
# __init__: build the form; name and kind are None when adding, others are the kinds besides this one (so the parent choices and the names this kind cannot take), and check returns why a name and kind cannot be saved, or None
def __init__(
self, parent: QWidget | None, name: str | None, kind: Kind | None, others: list[str],
check: Callable[[str, Kind], str | None],
check: Callable[[str, Kind], str | None], *, tomo_angpix: float | None = None,
) -> None:
super().__init__(parent)
self._check = check
Expand Down Expand Up @@ -61,7 +61,12 @@ def __init__(
self.tilt_box.setChecked(kind.tilt_prior_deg is not None)
self.tilt_spin.setEnabled(self.tilt_box.isChecked())
self.tilt_box.toggled.connect(self.tilt_spin.setEnabled)
self.angpix_spin = _spin(kind.extract_angpix, minimum=0.01)
self.angpix_spin = _spin(kind.extract_angpix, minimum=0.01, decimals=3)
self.tomo_button = QPushButton('Tomogram')
self.tomo_button.setVisible(tomo_angpix is not None)
if tomo_angpix is not None:
self.tomo_button.setToolTip(f'Use the tomogram pixel size, {tomo_angpix:g} Å/px')
self.tomo_button.clicked.connect(lambda: self.angpix_spin.setValue(tomo_angpix))
self.error = QLabel()
error_look(self.error)
self.error.setWordWrap(True)
Expand All @@ -74,6 +79,9 @@ def __init__(
colour_row = QHBoxLayout()
colour_row.addWidget(self.colour_edit)
colour_row.addWidget(choose)
angpix_row = QHBoxLayout()
angpix_row.addWidget(self.angpix_spin, 1)
angpix_row.addWidget(self.tomo_button)
tilt_row = QHBoxLayout()
tilt_row.addWidget(self.tilt_box)
tilt_row.addWidget(self.tilt_spin)
Expand All @@ -88,7 +96,7 @@ def __init__(
layout.addWidget(self._section('Estimation', [
('estimator', self.estimator_box), ('parent', self.parent_box), ('parent_tolerance_a', self.tolerance_spin),
]))
layout.addWidget(self._section('Extraction', [('tilt_prior_deg', tilt_row), ('extract_angpix', self.angpix_spin)]))
layout.addWidget(self._section('Extraction', [('tilt_prior_deg', tilt_row), ('extract_angpix', angpix_row)]))
layout.addWidget(self.error)
layout.addLayout(footer)

Expand Down Expand Up @@ -142,10 +150,10 @@ def _choose_colour(self) -> None:
if colour.isValid():
self.colour_edit.setText(colour.name())

# _spin: a float spin box with two decimals
def _spin(value: float, *, minimum: float = 0.0, maximum: float = 1_000_000.0) -> QDoubleSpinBox:
# _spin: a float spin box, two decimals unless asked for more
def _spin(value: float, *, minimum: float = 0.0, maximum: float = 1_000_000.0, decimals: int = 2) -> QDoubleSpinBox:
box = QDoubleSpinBox()
box.setRange(minimum, maximum)
box.setDecimals(2)
box.setDecimals(decimals)
box.setValue(value)
return box
2 changes: 1 addition & 1 deletion src/pickmix/gui/panes/kinds_pane.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def _edit(self, name: str | None) -> None:
if self.project is None:
return
kinds = self.project.config.kinds
dialog = KindDialog(self, name, None if name is None else kinds[name], [k for k in kinds if k != name], lambda new, kind: self._problem(new, kind, name))
dialog = KindDialog(self, name, None if name is None else kinds[name], [k for k in kinds if k != name], lambda new, kind: self._problem(new, kind, name), tomo_angpix=self.project.common_pixel_size)
result = dialog.exec()
if result == DELETED and name is not None:
self._delete(name)
Expand Down
7 changes: 7 additions & 0 deletions src/pickmix/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
'''

# Import external dependencies
from collections import Counter
from collections.abc import Sequence
from dataclasses import dataclass
from pathlib import Path
Expand All @@ -27,6 +28,12 @@ def update(self, **changes: object) -> None:
save_config(config, self.path)
self.config = config

# common_pixel_size: pixel size most tomograms share in A/px
@property
def common_pixel_size(self) -> float | None:
sizes = Counter(round(t.pixel_size, 3) for t in self.tomos.values())
return sizes.most_common(1)[0][0] if sizes else None

# display_name: the configured name, else the name of the directory holding config.toml
@property
def display_name(self) -> str:
Expand Down
11 changes: 11 additions & 0 deletions tests/gui/test_dialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ def test_defaults_when_adding(self, qtbot: QtBot) -> None:
dialog.name_edit.setText('yellow')
assert dialog.values() == ('yellow', Kind(marker_a=100, box_a=100))

# test_tomogram_pixel_size_button: button fills the extract pixel size with tomogram's, and only shows when it is known
def test_tomogram_pixel_size_button(self, qtbot: QtBot) -> None:
dialog = KindDialog(None, 'cage', Kind(marker_a=600), [], _ok, tomo_angpix=5.36)
qtbot.addWidget(dialog)
assert not dialog.tomo_button.isHidden() and dialog.values()[1].extract_angpix == 10.68
dialog.tomo_button.click()
assert dialog.values()[1].extract_angpix == 5.36
plain = KindDialog(None, 'cage', Kind(marker_a=600), [], _ok)
qtbot.addWidget(plain)
assert plain.tomo_button.isHidden()

# test_delete_only_when_editing: an existing kind can be deleted, a new one cannot
def test_delete_only_when_editing(self, qtbot: QtBot) -> None:
dialog = KindDialog(None, 'cage', Kind(marker_a=600), [], _ok)
Expand Down
7 changes: 7 additions & 0 deletions tests/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,10 @@ def test_create_with_name(self, tmp_path: Path, relion_project: Callable[[Path,
(tmp_path / 'raw').mkdir()
path, _ = create_project(tmp_path / 'proj', [('r1', tmp_path / 'p')], 'Tomograms/job006', tmp_path / 'raw', name='Cages')
assert load_config(path).name == 'Cages'

# test_common_pixel_size: the pixel size most tomograms share, None when there are none
def test_common_pixel_size(self, make_config: Callable[..., Path]) -> None:
project = open_project(make_config())
assert project.common_pixel_size == 5.36
project.tomos = {}
assert project.common_pixel_size is None
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading