Skip to content

Commit

Permalink
fix gui
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiasprobst committed Mar 12, 2024
1 parent b4b3916 commit df88e10
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 146 deletions.
166 changes: 93 additions & 73 deletions synpivimage/gui/core.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import matplotlib.pyplot as plt
import numpy as np
import pathlib
import sys
import warnings

import matplotlib.pyplot as plt
import numpy as np
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QHBoxLayout
Expand All @@ -10,12 +12,11 @@
from scipy import signal
from scipy.fft import rfft2, irfft2, fftshift

import synpivimage
import synpivimage as spi
from lib.corr import CorrelationPlane
from lib.plotting import gauss3ptfit
from src.main import Ui_MainWindow
from synpivimage.core import particle_intensity
from synpivimage.velocityfield import ConstantField

__this_dir__ = pathlib.Path(__file__).parent
INIT_DIR = __this_dir__
Expand Down Expand Up @@ -43,9 +44,14 @@ def get_window(window_function, shape):

def generate_correlation(imgA, imgB, window_function=None):
if window_function != 'uniform':
win = get_window(window_function, imgA.shape)
f2a = np.conj(rfft2(win * imgA))
f2b = rfft2(win * imgB)
try:
win = get_window(window_function, imgA.shape)
f2a = np.conj(rfft2(win * imgA))
f2b = rfft2(win * imgB)
except (KeyError, NotImplementedError) as e:
warnings.warn(f'Unknown window function: {window_function}')
f2a = np.conj(rfft2(imgA))
f2b = rfft2(imgB)
else:
f2a = np.conj(rfft2(imgA))
f2b = rfft2(imgB)
Expand All @@ -72,10 +78,10 @@ def __init__(self, root_dir):
self.particle_density.setMaximum(1)
self.particle_density.setValue(0.1)

self.particle_size_mean.setMinimum(0.5)
self.particle_size_mean.setValue(2.5)
self.particle_size_std.setMinimum(0.0)
self.particle_size_std.setValue(0.0)
self.particle_image_diameter.setMinimum(0.5)
self.particle_image_diameter.setMaximum(10)
self.particle_image_diameter.setValue(2.5)

self.laser_width.setMinimum(0)
self.laser_width.setValue(2)
self.laser_shape_factor.setMinimum(1)
Expand All @@ -87,10 +93,6 @@ def __init__(self, root_dir):
self.particle_count.setMaximum(2 ** 16)
self.particle_count.setValue(1000)

self.sigma.setMinimum(0.01)
self.sigma.setMaximum(100)
self.sigma.setValue(1)

self.dx.setMinimum(-100)
self.dx.setMaximum(100)

Expand Down Expand Up @@ -127,8 +129,6 @@ def __init__(self, root_dir):
self.correlations = np.empty(shape=(n_imgs, ny, nx))
self.particle_dataA = [{}] * n_imgs
self.particle_dataB = [{}] * n_imgs
self.metasA = [{}] * n_imgs
self.metasB = [{}] * n_imgs

plotting_layout1 = QHBoxLayout(self.plotwidget1)
plotting_layout2 = QHBoxLayout(self.plotwidget2)
Expand Down Expand Up @@ -203,77 +203,98 @@ def keyPressEvent(self, event):
self.curr_img_index += 1
self.update_plot()

def get_config(self):
self.current_config = spi.config.SynPivConfig(
ny=self.ny.value(),
def get_camera(self):
cam = synpivimage.Camera(
nx=self.nx.value(),
ny=self.ny.value(),
bit_depth=self.bit_depth.value(),
dark_noise=self.darknoise.value(),
image_particle_peak_count=self.particle_count.value(),
laser_shape_factor=self.laser_shape_factor.value(),
laser_width=self.laser_width.value(),
noise_baseline=self.baseline.value(),
particle_number=int(self.particle_density.value() * self.ny.value() * self.nx.value()),
particle_position_file=None,
particle_size_illumination_dependency=True,
particle_size_mean=self.particle_size_mean.value(),
particle_size_std=self.particle_size_std.value(),
sigmax=self.sigma.value(),
sigmay=self.sigma.value(),
baseline_noise=self.baseline.value(),
shot_noise=self.shotnoise.isChecked(),
fill_ratio_x=1.0,
fill_ratio_y=1.0,
qe=1.,
particle_image_diameter=self.particle_image_diameter.value(),
qe=1,
sensitivity=1.,
shot_noise=self.shotnoise.isChecked(),
)
return self.current_config
return cam

def get_laser(self):
laser = synpivimage.Laser(
shape_factor=self.laser_shape_factor.value(),
width=self.laser_width.value()
)
return laser

def generate_images(self, take_existing_particles=False):
cfg = self.get_config()
assert cfg.nx == self.nx.value()
assert cfg.ny == self.ny.value()
cam = self.get_camera()
laser = self.get_laser()

n_imgs = self.n_imgs.value()
imgs_shape = (n_imgs, cfg.ny, cfg.nx)
imgs_shape = (n_imgs, cam.ny, cam.nx)
if self.imgsA.shape != imgs_shape:
print('reallocate image arrays')
self.imgsA = np.empty(shape=imgs_shape)
self.imgsB = np.empty(shape=imgs_shape)
self.correlations = np.empty(shape=imgs_shape)
self.particle_dataA = [{}] * n_imgs
self.particle_dataB = [{}] * n_imgs
self.metasA = [{}] * n_imgs
self.metasB = [{}] * n_imgs

dx = self.dx.value()
dy = self.dy.value()
dz = self.dz.value()

if dx > 0:
dx_max = [0, dx]
else:
dx_max = [dx, 0]

if dy > 0:
dy_max = [0, dy]
else:
dy_max = [dy, 0]

if dz > 0:
dz_max = [0, dz]
else:
dz_max = [dz, 0]

for i in range(n_imgs):
if take_existing_particles:
particle_dataA = self.particle_dataA[i]
else:
particle_dataA = None

imgA, self.metaA, partA = spi.generate_image(
cfg,
particle_data=particle_dataA
particle_dataA = synpivimage.particles.Particles.generate(
dx_max=dx_max, dy_max=dy_max, dz_max=dz_max,
camera=cam,
laser=laser,
ppp=self.particle_density.value(),
)

imgA, partA = synpivimage.take_image(
camera=cam,
laser=laser,
particles=particle_dataA,
particle_peak_count=self.particle_count.value(),
)

cfield = ConstantField(dx=self.dx.value(), dy=self.dy.value(), dz=self.dz.value())
if take_existing_particles:
particle_dataB = self.particle_dataA[i]
else:
particle_dataB = cfield.displace(cfg, partA)
particle_dataB = particle_dataA.displace(dx=self.dx.value(), dy=self.dy.value(), dz=self.dz.value())

imgB, self.metaB, partB = spi.generate_image(
cfg,
particle_data=particle_dataB
imgB, partB = synpivimage.take_image(
camera=cam,
laser=laser,
particles=particle_dataB,
particle_peak_count=self.particle_count.value(),
)

self.imgsA[i, ...] = imgA
self.imgsB[i, ...] = imgB

self.particle_dataA[i] = partA
self.particle_dataB[i] = partB

self.metasA[i] = self.metaA
self.metasB[i] = self.metaB

def update_with_existing_images(self):
# compute correlations:
# if the particle size definition has changed, the images need to be regenerated
Expand Down Expand Up @@ -304,7 +325,6 @@ def update(self):
self.update_plot()

def update_plot(self):
self.sigma.setValue(self.metasA[self.curr_img_index]['sigmax'])
self._plot_imgA()
self._plot_imgB()
self._plot_correlation()
Expand Down Expand Up @@ -334,7 +354,6 @@ def _plot_imgB(self):
self.canvas[1].draw()

def _plot_correlation(self):

self.axes[5].cla()
self.axes[2].cla()
im = self.axes[2].imshow(normalize(self.correlations[self.curr_img_index]), cmap='gray')
Expand Down Expand Up @@ -440,24 +459,25 @@ def _plot_correlation(self):
# self.axes[4].vlines(self.dy.value() - self.ny.value() / 2, ylims[0], ylims[1], color='k', linestyle='--')
# self.canvas[3].draw()
# self.canvas[4].draw()
z = np.linspace(-2 * self.laser_width.value(), 2 * self.laser_width.value(), 1000)
laser_intensity = particle_intensity(z=z,
beam_width=self.laser_width.value(), # laser beam width
s=self.laser_shape_factor.value(), # shape factor
)
self.axes[3][0].plot(z, laser_intensity)
# self.axes[4][0].plot(z, laser_intensity)

self.axes[3][1].scatter(self.particle_dataA[self.curr_img_index].z, self.particle_dataA[self.curr_img_index].y,
color='b', alpha=0.5, s=10, marker='o')
# draw vlines for laser
self.axes[3][1].vlines(-self.laser_width.value() / 2, 0, self.nx.value(), color='k', linestyle='--')
self.axes[3][1].vlines(self.laser_width.value() / 2, 0, self.nx.value(), color='k', linestyle='--')

self.axes[3][1].scatter(self.particle_dataB[self.curr_img_index].z, self.particle_dataB[self.curr_img_index].y,
color='r', alpha=0.5, s=10, marker='o')
self.axes[3][1].vlines(-self.laser_width.value() / 2, 0, self.nx.value(), color='k', linestyle='--')
self.axes[3][1].vlines(self.laser_width.value() / 2, 0, self.nx.value(), color='k', linestyle='--')
if False:
z = np.linspace(-2 * self.laser_width.value(), 2 * self.laser_width.value(), 1000)
laser_intensity = particle_intensity(z=z,
beam_width=self.laser_width.value(), # laser beam width
s=self.laser_shape_factor.value(), # shape factor
)
self.axes[3][0].plot(z, laser_intensity)
# self.axes[4][0].plot(z, laser_intensity)

self.axes[3][1].scatter(self.particle_dataA[self.curr_img_index].z, self.particle_dataA[self.curr_img_index].y,
color='b', alpha=0.5, s=10, marker='o')
# draw vlines for laser
self.axes[3][1].vlines(-self.laser_width.value() / 2, 0, self.nx.value(), color='k', linestyle='--')
self.axes[3][1].vlines(self.laser_width.value() / 2, 0, self.nx.value(), color='k', linestyle='--')

self.axes[3][1].scatter(self.particle_dataB[self.curr_img_index].z, self.particle_dataB[self.curr_img_index].y,
color='r', alpha=0.5, s=10, marker='o')
self.axes[3][1].vlines(-self.laser_width.value() / 2, 0, self.nx.value(), color='k', linestyle='--')
self.axes[3][1].vlines(self.laser_width.value() / 2, 0, self.nx.value(), color='k', linestyle='--')

self.canvas[2].draw()
self.canvas[3].draw()
Expand Down
54 changes: 20 additions & 34 deletions synpivimage/gui/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def setupUi(self, MainWindow):
self.label_18.setObjectName("label_18")
self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_18)
self.formLayoutWidget = QtWidgets.QWidget(self.groupBox)
self.formLayoutWidget.setGeometry(QtCore.QRect(10, 20, 214, 357))
self.formLayoutWidget.setGeometry(QtCore.QRect(10, 20, 233, 357))
self.formLayoutWidget.setObjectName("formLayoutWidget")
self.formLayout = QtWidgets.QFormLayout(self.formLayoutWidget)
self.formLayout.setContentsMargins(0, 0, 0, 0)
Expand All @@ -122,58 +122,46 @@ def setupUi(self, MainWindow):
self.particle_density.setDecimals(4)
self.particle_density.setObjectName("particle_density")
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.particle_density)
self.label_4 = QtWidgets.QLabel(self.formLayoutWidget)
self.label_4.setObjectName("label_4")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_4)
self.particle_size_mean = QtWidgets.QDoubleSpinBox(self.formLayoutWidget)
self.particle_size_mean.setObjectName("particle_size_mean")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.particle_size_mean)
self.label_5 = QtWidgets.QLabel(self.formLayoutWidget)
self.label_5.setObjectName("label_5")
self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_5)
self.particle_size_std = QtWidgets.QDoubleSpinBox(self.formLayoutWidget)
self.particle_size_std.setObjectName("particle_size_std")
self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.particle_size_std)
self.particle_image_diameter_label = QtWidgets.QLabel(self.formLayoutWidget)
self.particle_image_diameter_label.setObjectName("particle_image_diameter_label")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.particle_image_diameter_label)
self.particle_image_diameter = QtWidgets.QDoubleSpinBox(self.formLayoutWidget)
self.particle_image_diameter.setEnabled(True)
self.particle_image_diameter.setObjectName("particle_image_diameter")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.particle_image_diameter)
self.label_6 = QtWidgets.QLabel(self.formLayoutWidget)
self.label_6.setObjectName("label_6")
self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_6)
self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_6)
self.laser_width = QtWidgets.QDoubleSpinBox(self.formLayoutWidget)
self.laser_width.setObjectName("laser_width")
self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.laser_width)
self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.laser_width)
self.label_7 = QtWidgets.QLabel(self.formLayoutWidget)
self.label_7.setObjectName("label_7")
self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_7)
self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_7)
self.laser_shape_factor = QtWidgets.QSpinBox(self.formLayoutWidget)
self.laser_shape_factor.setObjectName("laser_shape_factor")
self.formLayout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.laser_shape_factor)
self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.laser_shape_factor)
self.label_12 = QtWidgets.QLabel(self.formLayoutWidget)
self.label_12.setObjectName("label_12")
self.formLayout.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.label_12)
self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_12)
self.peak_find = QtWidgets.QComboBox(self.formLayoutWidget)
self.peak_find.setObjectName("peak_find")
self.peak_find.addItem("")
self.peak_find.addItem("")
self.peak_find.addItem("")
self.formLayout.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.peak_find)
self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.peak_find)
self.label_13 = QtWidgets.QLabel(self.formLayoutWidget)
self.label_13.setObjectName("label_13")
self.formLayout.setWidget(10, QtWidgets.QFormLayout.LabelRole, self.label_13)
self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_13)
self.bit_depth = QtWidgets.QSpinBox(self.formLayoutWidget)
self.bit_depth.setObjectName("bit_depth")
self.formLayout.setWidget(10, QtWidgets.QFormLayout.FieldRole, self.bit_depth)
self.formLayout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.bit_depth)
self.label_16 = QtWidgets.QLabel(self.formLayoutWidget)
self.label_16.setObjectName("label_16")
self.formLayout.setWidget(11, QtWidgets.QFormLayout.LabelRole, self.label_16)
self.formLayout.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.label_16)
self.particle_count = QtWidgets.QSpinBox(self.formLayoutWidget)
self.particle_count.setObjectName("particle_count")
self.formLayout.setWidget(11, QtWidgets.QFormLayout.FieldRole, self.particle_count)
self.label_17 = QtWidgets.QLabel(self.formLayoutWidget)
self.label_17.setObjectName("label_17")
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_17)
self.sigma = QtWidgets.QDoubleSpinBox(self.formLayoutWidget)
self.sigma.setEnabled(True)
self.sigma.setObjectName("sigma")
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.sigma)
self.formLayout.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.particle_count)
self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox_2.setGeometry(QtCore.QRect(250, 10, 1061, 671))
self.groupBox_2.setObjectName("groupBox_2")
Expand Down Expand Up @@ -215,8 +203,8 @@ def retranslateUi(self, MainWindow):
self.label.setText(_translate("MainWindow", "nx"))
self.label_2.setText(_translate("MainWindow", "ny"))
self.label_3.setText(_translate("MainWindow", "particle_density"))
self.label_4.setText(_translate("MainWindow", "dp mean"))
self.label_5.setText(_translate("MainWindow", "dp std"))
self.particle_image_diameter_label.setToolTip(_translate("MainWindow", "<html><head/><body><p>Standard deviation of gaussian distribution used for particle image intensity.</p></body></html>"))
self.particle_image_diameter_label.setText(_translate("MainWindow", "iparticle img. diam."))
self.label_6.setText(_translate("MainWindow", "laser width"))
self.label_7.setText(_translate("MainWindow", "laser shape"))
self.label_12.setText(_translate("MainWindow", "peak find"))
Expand All @@ -225,8 +213,6 @@ def retranslateUi(self, MainWindow):
self.peak_find.setItemText(2, _translate("MainWindow", "centroid"))
self.label_13.setText(_translate("MainWindow", "bit depth"))
self.label_16.setText(_translate("MainWindow", "particle intenstiy"))
self.label_17.setToolTip(_translate("MainWindow", "<html><head/><body><p>Standard deviation of gaussian distribution used for particle image intensity.</p></body></html>"))
self.label_17.setText(_translate("MainWindow", "pattern_mean"))
self.groupBox_2.setTitle(_translate("MainWindow", "Plots"))


Expand Down
Loading

0 comments on commit df88e10

Please sign in to comment.