Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor performance and readability changes. #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
95 changes: 54 additions & 41 deletions Calibration.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,58 @@
# Calculates the calibration parameters and returns the phi and m offsets

# imports
import numpy as np
from skimage import io


def get_calibration_parameters(filename, bin_width=0.2208, freq=80, harmonic=1, tau_ref = 4):
"""Opens the tiff image file and calculates the fft and gets the center coordinates of the g and s. Returns
the angle and distance that these values need to be translated by to place the calibration measurement
at the position expected by the user"""
im = io.imread(filename)
image = np.moveaxis(im, 0, 2)
bins = image.shape[2]
t_arr = np.linspace(bin_width / 2, bin_width * (bins - 1 / 2), bins)

integral = np.sum(image, axis=2).astype(float)
integral[integral == 0] = 0.00001
g = np.sum(image[:, ...] * np.cos(2 * np.pi * freq / 1000 * harmonic * t_arr[:]), axis=2) / integral
s = np.sum(image[:, ...] * np.sin(2 * np.pi * freq / 1000 * harmonic * t_arr[:]), axis=2) / integral

g_coor = g.flatten()
s_coor = s.flatten()

# Calculates the phi and m that needs to be applied to phasor coordinates to calibrate the software
# Known sample parameters based on tau and freq
freq = float(freq)
tau_ref = float(tau_ref)
x_ideal = 1 / (1 + np.power(2 * np.pi * freq / 1000 * tau_ref, 2))
y_ideal = 2 * np.pi * freq / 1000 * tau_ref / (1 + np.power(2 * np.pi * freq / 1000 * tau_ref, 2))

phi_ideal = np.arctan(y_ideal / x_ideal)
m_ideal = np.sqrt(x_ideal ** 2 + y_ideal ** 2)
# Our samples coordinates
coor_x = np.mean(g_coor)
coor_y = np.mean(s_coor)
phi_given = np.arctan(coor_y / coor_x)
m_given = np.sqrt(coor_x ** 2 + coor_y ** 2)
# calibration parameters
if coor_x < 0:
theta = phi_ideal - np.pi - phi_given
else:
theta = phi_ideal - phi_given
m = m_ideal / m_given
return theta, m
def get_calibration_parameters(filename, bin_width=0.2208, freq=80, harmonic=1, tau_ref=4):
"""Calculates the calibration parameters for a given image file.

Args:
filename (str): Path to the TIFF image file.
bin_width (float, optional): Width of the time bin in milliseconds. Defaults to 0.2208.
freq (int, optional): Stimulation frequency in Hz. Defaults to 80.
harmonic (int, optional): Stimulation harmonic. Defaults to 1.
tau_ref (int, optional): Refractory period in milliseconds. Defaults to 4.

Returns:
Tuple[float, float]: The phi and m offsets for the calibration parameters.
"""

# Load image data and reshape into (height, width, num_bins) array
image = np.moveaxis(io.imread(filename), 0, 2)
height, width, num_bins = image.shape

# Compute time array and integral image
t_arr = np.linspace(bin_width / 2, bin_width * (num_bins - 1 / 2), num_bins)
integral = np.sum(image, axis=2).astype(float)
integral[integral == 0] = 0.00001

# Compute g and s phasor coordinates
cos_term = np.cos(2 * np.pi * freq / 1000 * harmonic * t_arr[:])
g = np.sum(image[:, ...] * cos_term, axis=2) / integral
sin_term = np.sin(2 * np.pi * freq / 1000 * harmonic * t_arr[:])
s = np.sum(image[:, ...] * sin_term, axis=2) / integral

# Compute mean phasor coordinates of the image
g_mean = np.mean(g)
s_mean = np.mean(s)

# Compute ideal phasor coordinates based on known sample parameters
omega = 2 * np.pi * freq / 1000
x_ideal = 1 / (1 + np.power(omega * tau_ref, 2))
y_ideal = omega * tau_ref / (1 + np.power(omega * tau_ref, 2))
phi_ideal = np.arctan2(y_ideal, x_ideal)
m_ideal = np.linalg.norm([x_ideal, y_ideal])

# Compute actual phasor coordinates of the image
coor_x = g_mean
coor_y = s_mean
phi_given = np.arctan2(coor_y, coor_x)
m_given = np.linalg.norm([coor_x, coor_y])

# Compute calibration parameters
if coor_x < 0:
theta = phi_ideal - np.pi - phi_given
else:
theta = phi_ideal - phi_given
m = m_ideal / m_given

return theta, m