diff --git a/src/blik/napari.yaml b/src/blik/napari.yaml index 275d7ef..b187bd7 100644 --- a/src/blik/napari.yaml +++ b/src/blik/napari.yaml @@ -49,6 +49,9 @@ contributions: - id: blik.filament_picking python_name: blik.widgets.picking:FilamentWidget title: "Open blik filament picking widget" + - id: blik.rotate_particles + python_name: blik.widgets.picking:rotate_particles + title: "Open blik rotate particles widget" - id: blik.file_reader_widget python_name: blik.widgets.file_reader:file_reader title: "Open blik file reader widget" @@ -72,6 +75,7 @@ contributions: - command: blik.surface_picking - command: blik.sphere_picking - command: blik.filament_picking + - command: blik.rotate_particles napari/layers/filter: - command: blik.bandpass_filter - command: blik.gaussian_filter @@ -136,6 +140,8 @@ contributions: display_name: "Sphere picking" - command: blik.filament_picking display_name: "Filament picking" + - command: blik.rotate_particles + display_name: "Rotate selected particles" - command: blik.file_reader_widget display_name: "File reader" - command: blik.bandpass_filter diff --git a/src/blik/widgets/picking.py b/src/blik/widgets/picking.py index 788b249..b1dfa19 100644 --- a/src/blik/widgets/picking.py +++ b/src/blik/widgets/picking.py @@ -2,7 +2,7 @@ import numpy as np import pandas as pd from dask.array import compute -from magicgui import magicgui +from magicgui import magic_factory, magicgui from magicgui.widgets import Container from morphosamplers.helical_filament import HelicalFilament from morphosamplers.models import Sphere @@ -515,3 +515,23 @@ def __init__(self, *args, **kwargs): self.append(sphere) self.append(sphere_particles) + + +@magic_factory( + auto_call=True, + rot={"widget_type": "Slider", "min": 0, "max": 360}, + tilt={"widget_type": "Slider", "min": 0, "max": 360}, + psi={"widget_type": "Slider", "min": 0, "max": 360}, +) +def rotate_particles( + particles: napari.layers.Points, + rot: int = 0, + tilt: int = 0, + psi: int = 0, +) -> None: + """Quick and dirty rotation setter based on RELION convention.""" + if particles.metadata.get("experiment_id", None) is None: + raise ValueError("The selected layer is not a blik Particles layer.") + ori = Rotation.from_euler("ZYZ", (rot, tilt, psi), degrees=True) + particles.features.loc[list(particles.selected_data), "orientation"] = ori + particles.events.features()