Skip to content

Commit

Permalink
Add features count label
Browse files Browse the repository at this point in the history
Add label that shows the numbers of features found as
the mass slider moves.
  • Loading branch information
alexbolfa committed Nov 29, 2023
1 parent 7ed3faa commit 03dbb92
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 10 deletions.
6 changes: 3 additions & 3 deletions src/napari_psf_extractor/extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import psf_extractor as psfe
import trackpy

from napari_psf_extractor.utils import crop_to_bbox
from napari_psf_extractor.plotting import plot_mass_range
from napari_psf_extractor.utils import crop_to_bbox


def get_features_plot_data(plot_widget, mip, dx, dy, mass):
Expand Down Expand Up @@ -37,7 +37,7 @@ def get_features_plot_data(plot_widget, mip, dx, dy, mass):
# Plot features
features_init = trackpy.locate(mip, diameter=[dy, dx]).reset_index(drop=True)

plot_mass_range(mip=mip, ax=ax, mass=mass, features=features_init)
feature_count = plot_mass_range(mip=mip, ax=ax, mass=mass, features=features_init)
plot_widget.canvas.draw()

# Fetch plot matplotlib data from buffer
Expand All @@ -57,7 +57,7 @@ def get_features_plot_data(plot_widget, mip, dx, dy, mass):

data = cv2.resize(data, dsize=(mip.shape[1], mip.shape[0]), interpolation=cv2.INTER_NEAREST)

return data, features_init
return data, features_init, feature_count


def extract_psf(min_mass, max_mass, stack, features, wx, wy, wz):
Expand Down
12 changes: 8 additions & 4 deletions src/napari_psf_extractor/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from napari._qt.qthreading import thread_worker
from napari.utils.notifications import show_error
from psf_extractor.plotting import fire
from qtpy.QtWidgets import QLabel

from napari_psf_extractor.extractor import get_features_plot_data

Expand All @@ -16,8 +17,10 @@ def __init__(self, widget):
self.lock = threading.Lock()

self.data = None
self.count = None
self.features_init = None
self.features_layer = None
self.layer = None
self.label = QLabel(f"Features found: {self.count}")

@thread_worker
def update_factory(self):
Expand All @@ -29,7 +32,7 @@ def update_factory(self):
pass

if self.widget.mip is not None and isinstance(self.widget.mip, np.ndarray):
self.data, self.features_init = get_features_plot_data(
self.data, self.features_init, self.count = get_features_plot_data(
self.widget.plot_fig,
self.widget.mip,
self.widget.dx, self.widget.dy,
Expand Down Expand Up @@ -66,10 +69,11 @@ def callback(self, curr_range):
# Create features layer if it doesn't exist
if not self.layer_exists("Features"):
cmap = napari.utils.Colormap(fire.colors, display_name=fire.name)
self.features_layer = self.widget.viewer.add_image(data=self.data, colormap=cmap, name='Features')
self.layer = self.widget.viewer.add_image(data=self.data, colormap=cmap, name='Features')

# Update features layer
self.features_layer.data = self.data
self.layer.data = self.data
self.label.setText(f"Features found: {self.count}")
self.widget.status.stop_animation()
self.lock.release()

Expand Down
22 changes: 22 additions & 0 deletions src/napari_psf_extractor/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@


def plot_mass_range(ax, mip, mass, features):
"""
Plot the features in the mass range [mass[0], mass[1]].
Parameters
----------
ax : matplotlib.axes.Axes
The axes to plot on.
mip : numpy.ndarray
The maximum intensity projection of the image stack.
mass : tuple
The mass range to plot.
features : pandas.DataFrame
The features to plot.
Returns
-------
int
The number of features found.
"""

# Enhance contrast in MIP (by taking the log)
s = 1 / mip[mip != 0].min() # scaling factor (such that log(min) = 0
mip_log = np.log(s * mip,
Expand All @@ -25,3 +45,5 @@ def plot_mass_range(ax, mip, mass, features):
ax.imshow(background, cmap=fire)
ax.plot(df['x'], df['y'], ls='', color='#00ff00',
marker='o', ms=7, mfc='none', mew=1)

return len(df)
10 changes: 7 additions & 3 deletions src/napari_psf_extractor/widget.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
from typing import TYPE_CHECKING

import numpy as np
from matplotlib import pyplot as plt
import psf_extractor as psfe
from magicgui import magicgui
from matplotlib import pyplot as plt
from napari.utils.notifications import show_error
import psf_extractor as psfe
from qtpy.QtWidgets import QWidget, QVBoxLayout, QPushButton, QFileDialog

from napari_psf_extractor.components.sliders import RangeSlider
from napari_psf_extractor.components.statusbar import StatusMessage
from napari_psf_extractor.extractor import extract_psf
from napari_psf_extractor.features import Features
from napari_psf_extractor.components.statusbar import StatusMessage
from napari_psf_extractor.utils import normalize

# Hide napari imports from type support and autocompletion
Expand Down Expand Up @@ -93,6 +93,8 @@ def param_setter(

self.layout().addWidget(param_setter.native)
self.layout().addWidget(self.mass_slider)
self.layout().addWidget(self.features.label)
self.layout().addStretch(1)
self.layout().addWidget(self.save_button)

# ---------------
Expand Down Expand Up @@ -135,13 +137,15 @@ def reset(self):

self.mass_slider.hide()
self.save_button.hide()
self.features.label.hide()

def refresh(self):
"""
Refresh the widget and move to the next state.
"""
if self.state == 0:
self.mass_slider.reset()
self.features.label.show()
self.mass_slider.show()
self.save_button.show()

Expand Down

0 comments on commit 03dbb92

Please sign in to comment.