Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c221ee7
Integrated COMET into Picasso render and made it the default drift co…
LREIN663 Mar 27, 2026
23c20e6
Handle COMET availability in drift correction and update menu shortcuts.
LREIN663 May 28, 2026
431b22a
Handle COMET availability in drift correction and update menu shortcuts.
LREIN663 May 28, 2026
38a4e28
Merge remote-tracking branch 'origin/master'
LREIN663 May 28, 2026
a66d513
Handle COMET availability in drift correction and update menu shortcuts.
LREIN663 May 28, 2026
a921780
Fix relative lib import after moving comet to ext folder.
LREIN663 May 28, 2026
4a08227
Merge branch 'development' into master
rafalkowalewski1 May 29, 2026
aeef7b1
Merge pull request #671 from gpufit/master
rafalkowalewski1 May 29, 2026
9e6ce80
clean up the comet integration
rafalkowalewski1 May 29, 2026
1c4f197
add more tests to comet
rafalkowalewski1 May 29, 2026
e438de6
fix comet integration to gui (qt6 update and no View.all_locs) + allo…
rafalkowalewski1 May 29, 2026
6c68f1b
remove comet temporarily
rafalkowalewski1 May 31, 2026
7a88437
Fixed "Best fitting combination" button in SPINNA (#676)
rafalkowalewski1 Jun 10, 2026
7e1d16f
Fixed 3D calibration when frame range is user-specified
rafalkowalewski1 Jun 10, 2026
e7aea51
add tests for frame-bounded calibration
rafalkowalewski1 Jun 10, 2026
7728832
fixed redoing 3D calibration when identification parameters change
rafalkowalewski1 Jun 10, 2026
e4e3777
change rotations to quaterions (#673, #674, #675)
rafalkowalewski1 Jun 11, 2026
10e93df
update 3d rotation docs
rafalkowalewski1 Jun 11, 2026
ab7aba1
All 3 angles in "Rotate by angle" in the 3D rotation window are accum…
rafalkowalewski1 Jun 11, 2026
8cf83be
Render by property fixed for large files (#677, #672 possibly too)
rafalkowalewski1 Jun 11, 2026
7c68b26
update docstrings for multichannel rendering (new LUTs)
rafalkowalewski1 Jun 11, 2026
64a2f53
update version for release
rafalkowalewski1 Jun 11, 2026
8ed1c6d
Merge pull request #678 from rafalkowalewski1/development
rafalkowalewski1 Jun 11, 2026
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
10 changes: 9 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Changelog

Last change: 28-MAY-2026 CEST
Last change: 11-JUN-2026 CEST

## 0.10.2
- Rotations use quaterions for unambiguous workflow, fixing bugs [#673](https://github.com/jungmannlab/picasso/issues/673), [#674](https://github.com/jungmannlab/picasso/issues/674) and [#675](https://github.com/jungmannlab/picasso/issues/675)
- All 3 angles in "Rotate by angle" in the 3D rotation window are accumulated into a single widget
- Render by property fixed for large files ([#677](https://github.com/jungmannlab/picasso/issues/677)), possibly related to [#672](https://github.com/jungmannlab/picasso/issues/672)
- Fixed "Best fitting combination" button in SPINNA ([#676](https://github.com/jungmannlab/picasso/issues/676))
- Fixed 3D calibration when frame range is user-specified
- Fixed redoing 3D calibration when identification parameters change

## 0.10.1

Expand Down
2 changes: 0 additions & 2 deletions docs/render.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ Note that to build animations, the user must have ``ffmpeg`` installed on their

Rotation around z-axis is available by pressing Ctrl/Command. Rotation axis can be frozen by pressing x/y/z to freeze around the corresponding axes (to freeze around the z-axis, Ctrl/Command must be pressed as well).

There are several things to keep in mind when using the rotation window. Firstly, using individual localization precision is very slow and is not recommended as a default blur method. Also, the size of the rotation window can be altered, however, if it becomes too large, rendering may start to lag.

RESI
----
.. image:: ../docs/render_resi.png
Expand Down
29 changes: 28 additions & 1 deletion picasso/gui/localize.py
Original file line number Diff line number Diff line change
Expand Up @@ -2103,6 +2103,8 @@ def _clean_up_external_ids(self) -> None:
self.last_identification_info = {
"Box Size": self.parameters_dialog.box_spinbox.value(),
"Min. Net Gradient": self.parameters_dialog.mng_slider.value(),
"ROI": self.view.roi,
"Frame bounds": self.frame_range,
}
self.ready_for_fit = True
self.draw_frame()
Expand Down Expand Up @@ -2551,6 +2553,7 @@ def on_fit_finished(
playsound(sound_path, block=False)
base, ext = os.path.splitext(self.movie_path)
if calibrate_z:
self.parameters_dialog.gpufit_checkbox.setDisabled(False)
step, ok = QtWidgets.QInputDialog.getDouble(
self,
"3D Calibration",
Expand All @@ -2572,6 +2575,7 @@ def on_fit_finished(
step,
self.parameters_dialog.magnification_factor.value(),
path=path,
frame_bounds=self.frame_range,
)
dt = time.time() - t0
if dt > lib.SOUND_NOTIFICATION_DURATION:
Expand Down Expand Up @@ -2902,11 +2906,34 @@ def localize(self, calibrate_z: bool = False) -> None:
Default is False.
"""
self.parameters_dialog.gpufit_checkbox.setDisabled(True)
if self.identifications is not None and calibrate_z is True:
if (
calibrate_z
and self.identifications is not None
and self.ready_for_fit
and not self.identifications_outdated()
):
# reuse existing identifications (e.g., loaded picks/locs)
self.fit(calibrate_z=calibrate_z)
else:
self.identify(fit_afterwards=True, calibrate_z=calibrate_z)

def identifications_outdated(self) -> bool:
"""Check whether the identification settings (box size, min. net
gradient, ROI, frame range) have changed since
``self.identifications`` was created."""
last = self.last_identification_info
if last is None:
return True
if any(
last.get(key) != value for key, value in self.parameters.items()
):
return True
if last.get("ROI") != self.view.roi:
return True
if last.get("Frame bounds") != self.frame_range:
return True
return False

def select_locs_columns(self) -> None:
"""Select only the columns that are checked in the corresponding
dialog."""
Expand Down
28 changes: 15 additions & 13 deletions picasso/gui/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
)
from .rotation import RotationWindow

# PyImarisWrite works on windows only
from ..ext.bitplane import IMSWRITER
# Optional modules with external/hardware dependencies live in ext
from ..ext.bitplane import IMSWRITER # PyImarisWrite works on Windows only

if IMSWRITER:
from ..ext.bitplane import numpy_to_imaris
Expand Down Expand Up @@ -10995,14 +10995,6 @@ def show_drift(self) -> None:
self.plot_window.plot(drift)
self.plot_window.show()

def sync_groups(self) -> None:
"""Remove localizations whose group field is not found in all
channels."""
if len(self.locs_paths) < 2:
return
self.locs = lib.sync_groups(self.locs)
self.update_scene(resample_locs=True)

def undrift_aim(self) -> None:
"""Undrift with Adaptive Intersection Maximization (AIM).

Expand Down Expand Up @@ -11252,6 +11244,14 @@ def _apply_drift(self, channel: int, drift: pd.DataFrame) -> None:
self.render_index[channel] = None
self.update_scene(resample_locs=True)

def sync_groups(self) -> None:
"""Remove localizations whose group field is not found in all
channels."""
if len(self.locs_paths) < 2:
return
self.locs = lib.sync_groups(self.locs)
self.update_scene(resample_locs=True)

def unfold_groups_square(self) -> None:
"""Shifts grouped localizations onto a square grid with a chosen
number of columns and spacing. Localizations can be grouped, for
Expand Down Expand Up @@ -11995,6 +11995,7 @@ def initUI(self, plugins_loaded: bool) -> None:

# menu bar - Postprocess
postprocess_menu = self.menu_bar.addMenu("Postprocess")

undrift_aim_action = postprocess_menu.addAction("Undrift by AIM")
undrift_aim_action.setShortcut("Ctrl+U")
undrift_aim_action.triggered.connect(self.view.undrift_aim)
Expand All @@ -12011,6 +12012,7 @@ def initUI(self, plugins_loaded: bool) -> None:
undrift_from_picked2d_action.triggered.connect(
self.view.undrift_from_picked2d
)

undrift_action = postprocess_menu.addAction("Undrift by RCC")
undrift_action.triggered.connect(self.view.undrift_rcc)
drift_action = postprocess_menu.addAction("Undo drift")
Expand Down Expand Up @@ -12829,9 +12831,9 @@ def open_rotated_locs(self) -> None:
self.tools_settings_dialog.pick_side_length.setValue(
self.view.infos[0][-1]["Pick size (nm)"]
)
self.window_rot.view_rot.angx = self.view.infos[0][-1]["angx"]
self.window_rot.view_rot.angy = self.view.infos[0][-1]["angy"]
self.window_rot.view_rot.angz = self.view.infos[0][-1]["angz"]
self.window_rot.view_rot.load_saved_rotation(
self.view.infos[0][-1]
)
self.rot_win()

def resize_view_to_fov(self, w: float, h: float) -> None:
Expand Down
Loading
Loading