separate FIcurve class, change fitter results structure

This commit is contained in:
a.ott 2020-05-12 14:14:55 +02:00
parent c1db288f97
commit 1f82f06209
7 changed files with 429 additions and 303 deletions

View File

@ -1,5 +1,5 @@
from FiCurve import FICurve
from FiCurve import FICurve, get_fi_curve_class
from CellData import CellData
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
@ -13,7 +13,7 @@ class Adaption:
def __init__(self, cell_data: CellData, fi_curve: FICurve = None):
self.cell_data = cell_data
if fi_curve is None:
self.fi_curve = FICurve(cell_data)
self.fi_curve = get_fi_curve_class(cell_data, cell_data.get_fi_contrasts())
else:
self.fi_curve = fi_curve
@ -51,7 +51,7 @@ class Adaption:
# start the actual fit:
try:
p0 = (self.fi_curve.f_zeros[i], tau, self.fi_curve.f_infinities[i])
p0 = (self.fi_curve.f_zero_frequencies[i], tau, self.fi_curve.f_inf_frequencies[i])
popt, pcov = curve_fit(fu.exponential_function, x_values, y_values,
p0=p0, maxfev=10000, bounds=([-np.inf, 0, -np.inf], [np.inf, np.inf, np.inf]))
except RuntimeError:
@ -67,10 +67,10 @@ class Adaption:
self.exponential_fit_vars.append(popt)
def __approximate_tau_for_exponential_fit(self, x_values, y_values, mean_freq_idx):
if self.fi_curve.f_infinities[mean_freq_idx] < self.fi_curve.f_baselines[mean_freq_idx] * 0.95:
test_val = [y > 0.65 * self.fi_curve.f_infinities[mean_freq_idx] for y in y_values]
if self.fi_curve.f_inf_frequencies[mean_freq_idx] < self.fi_curve.f_baseline_frequencies[mean_freq_idx] * 0.95:
test_val = [y > 0.65 * self.fi_curve.f_inf_frequencies[mean_freq_idx] for y in y_values]
else:
test_val = [y < 0.65 * self.fi_curve.f_zeros[mean_freq_idx] for y in y_values]
test_val = [y < 0.65 * self.fi_curve.f_zero_frequencies[mean_freq_idx] for y in y_values]
try:
idx = test_val.index(True)
@ -85,13 +85,13 @@ class Adaption:
def __find_start_idx_for_exponential_fit(self, mean_freq_idx):
time_axes = self.cell_data.get_time_axes_mean_frequencies()[mean_freq_idx]
stimulus_start_idx = int((self.cell_data.get_stimulus_start() + time_axes[0]) / self.cell_data.get_sampling_interval())
if self.fi_curve.f_infinities[mean_freq_idx] > self.fi_curve.f_baselines[mean_freq_idx] * 1.1:
if self.fi_curve.f_inf_frequencies[mean_freq_idx] > self.fi_curve.f_baseline_frequencies[mean_freq_idx] * 1.1:
# start setting starting variables for the fit
# search for the start_index by searching for the max
j = 0
while True:
try:
if self.cell_data.get_mean_isi_frequencies()[mean_freq_idx][stimulus_start_idx + j] == self.fi_curve.f_zeros[mean_freq_idx]:
if self.cell_data.get_mean_isi_frequencies()[mean_freq_idx][stimulus_start_idx + j] == self.fi_curve.f_zero_frequencies[mean_freq_idx]:
start_idx = stimulus_start_idx + j
break
except IndexError as e:
@ -99,7 +99,7 @@ class Adaption:
j += 1
elif self.fi_curve.f_infinities[mean_freq_idx] < self.fi_curve.f_baselines[mean_freq_idx] * 0.9:
elif self.fi_curve.f_inf_frequencies[mean_freq_idx] < self.fi_curve.f_baseline_frequencies[mean_freq_idx] * 0.9:
# start setting starting variables for the fit
# search for start by finding the end of the minimum
found_min = False
@ -107,10 +107,10 @@ class Adaption:
nothing_to_fit = False
while True:
if not found_min:
if self.cell_data.get_mean_isi_frequencies()[mean_freq_idx][stimulus_start_idx + j] == self.fi_curve.f_zeros[mean_freq_idx]:
if self.cell_data.get_mean_isi_frequencies()[mean_freq_idx][stimulus_start_idx + j] == self.fi_curve.f_zero_frequencies[mean_freq_idx]:
found_min = True
else:
if self.cell_data.get_mean_isi_frequencies()[mean_freq_idx][stimulus_start_idx + j + 1] > self.fi_curve.f_zeros[mean_freq_idx]:
if self.cell_data.get_mean_isi_frequencies()[mean_freq_idx][stimulus_start_idx + j + 1] > self.fi_curve.f_zero_frequencies[mean_freq_idx]:
start_idx = stimulus_start_idx + j
break
if j > 0.1 / self.cell_data.get_sampling_interval():
@ -133,7 +133,7 @@ class Adaption:
continue
tau_effs.append(self.exponential_fit_vars[i][1])
f_infinity_slope = self.fi_curve.get_f_infinity_slope()
f_infinity_slope = self.fi_curve.get_f_inf_slope()
# --- old way to calculate with the fi slope at middle of the fi curve
# fi_curve_slope = self.fi_curve.get_fi_curve_slope_of_straight()
# self.tau_real = np.median(tau_effs) * (fi_curve_slope / f_infinity_slope)
@ -174,7 +174,7 @@ class Adaption:
vars = self.exponential_fit_vars[i]
fit_x = np.arange(0, 0.4, self.cell_data.get_sampling_interval())
plt.plot(fit_x, [fu.exponential_function(x, vars[0], vars[1], vars[2]) for x in fit_x])
plt.ylim([0, max(self.fi_curve.f_zeros[i], self.fi_curve.f_baselines[i])*1.1])
plt.ylim([0, max(self.fi_curve.f_zero_frequencies[i], self.fi_curve.f_baseline_frequencies[i])*1.1])
plt.xlabel("Time [s]")
plt.ylabel("Frequency [Hz]")

View File

@ -31,15 +31,50 @@ class Baseline:
def get_interspike_intervals(self):
raise NotImplementedError("NOT YET OVERRIDDEN FROM ABSTRACT CLASS")
def plot_baseline(self, save_path=None):
def plot_baseline(self, save_path=None, time_length=0.2):
raise NotImplementedError("NOT YET OVERRIDDEN FROM ABSTRACT CLASS")
@staticmethod
def plot_baseline_given_data(time, eod, v1, spiketimes, sampling_interval, save_path=None, time_length=0.2):
"""
plots the stimulus / eod, together with the v1, spiketimes and frequency
:return:
"""
raise NotImplementedError("NOT YET OVERRIDDEN FROM ABSTRACT CLASS")
length_data_points = int(time_length / sampling_interval)
start_idx = int(len(time) * 0.5 - length_data_points * 0.5)
start_idx = start_idx if start_idx >= 0 else 0
end_idx = int(len(time) * 0.5 + length_data_points * 0.5) + 1
end_idx = end_idx if end_idx <= len(time) else len(time)
spiketimes = np.array(spiketimes)
spiketimes_part = spiketimes[(spiketimes >= time[start_idx]) & (spiketimes < time[end_idx])]
def plot_inter_spike_interval_histogram(self, save_path=None):
isi = self.get_interspike_intervals() * 1000 # change unit to milliseconds
fig, axes = plt.subplots(3, 1, sharex="col", figsize=(12, 8))
fig.suptitle("Baseline middle part ({:.2f} seconds)".format(time_length))
axes[0].plot(time[start_idx:end_idx], eod[start_idx:end_idx])
axes[0].set_ylabel("Stimulus [mV]")
max_v1 = max(v1[start_idx:end_idx])
axes[1].plot(time[start_idx:end_idx], v1[start_idx:end_idx])
axes[1].plot(spiketimes_part, [max_v1 for _ in range(len(spiketimes_part))],
'o', color='orange')
axes[1].set_ylabel("V1-Trace [mV]")
t, f = hF.calculate_time_and_frequency_trace(spiketimes_part, sampling_interval)
axes[2].plot(t, f)
axes[2].set_ylabel("ISI-Frequency [Hz]")
axes[2].set_xlabel("Time [s]")
if save_path is not None:
plt.savefig(save_path + "baseline.png")
else:
plt.show()
plt.close()
def plot_interspike_interval_histogram(self, save_path=None):
isi = np.array(self.get_interspike_intervals()) * 1000 # change unit to milliseconds
maximum = max(isi)
bins = np.arange(0, maximum * 1.01, 0.1)
@ -49,7 +84,7 @@ class Baseline:
plt.hist(isi, bins=bins)
if save_path is not None:
plt.savefig(save_path)
plt.savefig(save_path + "isi-histogram.png")
else:
plt.show()
@ -60,10 +95,10 @@ class Baseline:
plt.xlabel("Lag")
plt.ylabel("Correlation")
plt.ylim((-1, 1))
plt.plot(np.arange(1,max_lag+1, 1), self.get_serial_correlation(max_lag))
plt.plot(np.arange(1, max_lag+1, 1), self.get_serial_correlation(max_lag))
if save_path is not None:
plt.savefig(save_path)
plt.savefig(save_path + "serial_correlation.png")
else:
plt.show()
@ -83,7 +118,7 @@ class BaselineCellData(Baseline):
delay = self.data.get_delay()
sampling_interval = self.data.get_sampling_interval()
if delay < 0.1:
warn("FICurve:__calculate_f_baseline__(): Quite short delay at the start.")
warn("BaselineCellData:get_baseline_Frequency(): Quite short delay at the start.")
idx_start = int(0.025 / sampling_interval)
idx_end = int((delay - 0.025) / sampling_interval)
@ -136,30 +171,16 @@ class BaselineCellData(Baseline):
return isis
def plot_baseline(self, save_path=None):
def plot_baseline(self, save_path=None, time_length=0.2):
# eod, v1, spiketimes, frequency
times = self.data.get_base_traces(self.data.TIME)
eods = self.data.get_base_traces(self.data.EOD)
v1_traces = self.data.get_base_traces(self.data.V1)
spiketimes = self.data.get_base_spikes()
fig, axes = plt.subplots(4, 1, sharex='col')
time = self.data.get_base_traces(self.data.TIME)[0]
eod = self.data.get_base_traces(self.data.EOD)[0]
v1_trace = self.data.get_base_traces(self.data.V1)[0]
spiketimes = self.data.get_base_spikes()[0]
for i in range(len(times)):
axes[0].plot(times[i], eods[i])
axes[1].plot(times[i], v1_traces[i])
axes[2].plot(spiketimes[i], [1 for i in range(len(spiketimes[i]))], 'o')
t, f = hF.calculate_time_and_frequency_trace(spiketimes[i], self.data.get_sampling_interval())
axes[3].plot(t, f)
if save_path is not None:
plt.savefig(save_path)
else:
plt.show()
plt.close()
self.plot_baseline_given_data(time, eod, v1_trace, spiketimes,
self.data.get_sampling_interval(), save_path, time_length)
class BaselineModel(Baseline):
@ -200,24 +221,9 @@ class BaselineModel(Baseline):
def get_interspike_intervals(self):
return np.diff(self.spiketimes)
def plot_baseline(self, save_path=None):
# eod, v1, spiketimes, frequency
fig, axes = plt.subplots(4, 1, sharex="col")
axes[0].plot(self.time, self.eod)
axes[1].plot(self.time, self.v1)
axes[2].plot(self.spiketimes, [1 for i in range(len(self.spiketimes))], 'o')
t, f = hF.calculate_time_and_frequency_trace(self.spiketimes, self.model.get_sampling_interval())
axes[3].plot(t, f)
if save_path is not None:
plt.savefig(save_path)
else:
plt.show()
plt.close()
def plot_baseline(self, save_path=None, time_length=0.2):
self.plot_baseline_given_data(self.time, self.eod, self.v1, self.spiketimes,
self.model.get_sampling_interval(), save_path, time_length)
def get_baseline_class(data, eod_freq=None) -> Baseline:

View File

@ -3,6 +3,7 @@ from os.path import isdir, exists
from warnings import warn
import pyrelacs.DataLoader as Dl
from models.AbstractModel import AbstractModel
import numpy as np
UNKNOWN = -1
DAT_FORMAT = 0
@ -82,11 +83,12 @@ class DatParser(AbstractParser):
return self.__get_traces__("BaselineActivity")
def get_baseline_spiketimes(self):
# TODO change: reading from file -> detect from v1 trace
spiketimes = []
warn("Spiketimes don't fit time-wise to the baseline traces. Causes different vector strength angle per recording.")
for metadata, key, data in Dl.iload(self.baseline_file):
spikes = data[:, 0]
spikes = np.array(data[:, 0]) / 1000 # timestamps are saved in ms -> conversion to seconds
spiketimes.append(spikes)
return spiketimes

View File

@ -1,5 +1,7 @@
from CellData import CellData
from models.LIFACnoise import LifacNoiseModel
from stimuli.SinusoidalStepStimulus import SinusoidalStepStimulus
import numpy as np
import matplotlib.pyplot as plt
from warnings import warn
@ -9,91 +11,66 @@ import helperFunctions as hF
class FICurve:
def __init__(self, cell_data: CellData, contrast: bool = True):
self.cell_data = cell_data
self.using_contrast = contrast
if contrast:
self.stimulus_value = cell_data.get_fi_contrasts()
else:
self.stimulus_value = cell_data.get_fi_intensities()
def __init__(self, stimulus_values):
self.stimulus_values = stimulus_values
self.f_zeros = []
self.f_infinities = []
self.f_baselines = []
self.f_baseline_frequencies = []
self.f_inf_frequencies = []
self.f_zero_frequencies = []
# f_max, f_min, k, x_zero
self.boltzmann_fit_vars = []
# increase, offset
self.f_infinity_fit = []
self.f_inf_fit = []
# f_max, f_min, k, x_zero
self.f_zero_fit = []
self.all_calculate_frequency_points()
self.f_infinity_fit = hF.fit_clipped_line(self.stimulus_value, self.f_infinities)
self.boltzmann_fit_vars = hF.fit_boltzmann(self.stimulus_value, self.f_zeros)
self.initialize()
def all_calculate_frequency_points(self):
mean_frequencies = self.cell_data.get_mean_isi_frequencies()
time_axes = self.cell_data.get_time_axes_mean_frequencies()
stimulus_start = self.cell_data.get_stimulus_start()
stimulus_duration = self.cell_data.get_stimulus_duration()
sampling_interval = self.cell_data.get_sampling_interval()
def initialize(self):
self.calculate_all_frequency_points()
self.f_inf_fit = hF.fit_clipped_line(self.stimulus_values, self.f_inf_frequencies)
self.f_zero_fit = hF.fit_boltzmann(self.stimulus_values, self.f_zero_frequencies)
if len(mean_frequencies) == 0:
warn("FICurve:all_calculate_frequency_points(): mean_frequencies is empty.\n"
"Was all_calculate_mean_isi_frequencies already called?")
def calculate_all_frequency_points(self):
raise NotImplementedError("NOT YET OVERRIDDEN FROM ABSTRACT CLASS")
for i in range(len(mean_frequencies)):
def get_f_baseline_frequencies(self):
return self.f_baseline_frequencies
if time_axes[i][0] > self.cell_data.get_stimulus_start():
warn("TODO: Deal with to strongly cut frequency traces in cell data! ")
self.f_zeros.append(-1)
self.f_baselines.append(-1)
self.f_infinities.append(-1)
continue
def get_f_inf_frequencies(self):
return self.f_inf_frequencies
f_zero = hF.detect_f_zero_in_frequency_trace(time_axes[i], mean_frequencies[i],
stimulus_start, sampling_interval)
self.f_zeros.append(f_zero)
f_baseline = hF.detect_f_baseline_in_freq_trace(time_axes[i], mean_frequencies[i],
stimulus_start, sampling_interval)
self.f_baselines.append(f_baseline)
f_infinity = hF.detect_f_infinity_in_freq_trace(time_axes[i], mean_frequencies[i],
stimulus_start, stimulus_duration, sampling_interval)
self.f_infinities.append(f_infinity)
def get_f_zero_frequencies(self):
return self.f_zero_frequencies
def get_f_zero_inverse_at_frequency(self, frequency):
b_vars = self.boltzmann_fit_vars
return fu.inverse_full_boltzmann(frequency, b_vars[0], b_vars[1], b_vars[2], b_vars[3])
def get_f_infinity_frequency_at_stimulus_value(self, stimulus_value):
infty_vars = self.f_infinity_fit
return fu.clipped_line(stimulus_value, infty_vars[0], infty_vars[1])
def get_f_inf_slope(self):
if len(self.f_inf_fit) > 0:
return self.f_inf_fit[0]
def get_f_infinity_slope(self):
return self.f_infinity_fit[0]
def get_f_zero_fit_slope_at_straight(self):
fit_vars = self.f_zero_fit
return fu.full_boltzmann_straight_slope(fit_vars[0], fit_vars[1], fit_vars[2], fit_vars[3])
def get_fi_curve_slope_at(self, stimulus_value):
fit_vars = self.boltzmann_fit_vars
def get_f_zero_fit_slope_at_stimulus_value(self, stimulus_value):
fit_vars = self.f_zero_fit
return fu.derivative_full_boltzmann(stimulus_value, fit_vars[0], fit_vars[1], fit_vars[2], fit_vars[3])
def get_fi_curve_slope_of_straight(self):
fit_vars = self.boltzmann_fit_vars
return fu.full_boltzmann_straight_slope(fit_vars[0], fit_vars[1], fit_vars[2], fit_vars[3])
def get_f_inf_frequency_at_stimulus_value(self, stimulus_value):
return fu.clipped_line(stimulus_value, self.f_inf_fit[0], self.f_inf_fit[1])
def get_f_zero_and_f_inf_intersection(self):
x_values = np.arange(min(self.stimulus_value), max(self.stimulus_value), 0.0001)
fit_vars = self.boltzmann_fit_vars
x_values = np.arange(min(self.stimulus_values), max(self.stimulus_values), 0.0001)
fit_vars = self.f_zero_fit
f_zero = fu.full_boltzmann(x_values, fit_vars[0], fit_vars[1], fit_vars[2], fit_vars[3])
f_inf = fu.clipped_line(x_values, self.f_infinity_fit[0], self.f_infinity_fit[1])
f_inf = fu.clipped_line(x_values, self.f_inf_fit[0], self.f_inf_fit[1])
intersection_indicies = np.argwhere(np.diff(np.sign(f_zero - f_inf))).flatten()
# print("fi-curve calc intersection:", intersection_indicies, x_values[intersection_indicies])
if len(intersection_indicies) > 1:
f_baseline = np.median(self.f_baselines)
f_baseline = np.median(self.f_baseline_frequencies)
best_dist = np.inf
best_idx = -1
for idx in intersection_indicies:
dist = abs(fu.clipped_line(x_values[idx], self.f_infinity_fit[0], self.f_infinity_fit[1]) - f_baseline)
dist = abs(fu.clipped_line(x_values[idx], self.f_inf_fit[0], self.f_inf_fit[1]) - f_baseline)
if dist < best_dist:
best_dist = dist
best_idx = idx
@ -107,57 +84,291 @@ class FICurve:
def get_fi_curve_slope_at_f_zero_intersection(self):
x = self.get_f_zero_and_f_inf_intersection()
fit_vars = self.boltzmann_fit_vars
fit_vars = self.f_zero_fit
return fu.derivative_full_boltzmann(x, fit_vars[0], fit_vars[1], fit_vars[2], fit_vars[3])
def plot_fi_curve(self, savepath: str = None, comp_f_baselines=None, comp_f_zeros=None, comp_f_infs=None):
min_x = min(self.stimulus_value)
max_x = max(self.stimulus_value)
def plot_fi_curve(self, save_path=None):
min_x = min(self.stimulus_values)
max_x = max(self.stimulus_values)
step = (max_x - min_x) / 5000
x_values = np.arange(min_x, max_x, step)
plt.plot(self.stimulus_value, self.f_baselines, color='blue', label='f_base')
if comp_f_baselines is not None:
plt.plot(self.stimulus_value, comp_f_baselines, 'o', color='skyblue', label='comp_values base')
plt.plot(self.stimulus_values, self.f_baseline_frequencies, color='blue', label='f_base')
plt.plot(self.stimulus_value, self.f_infinities, 'o', color='green', label='f_inf')
plt.plot(x_values, [fu.clipped_line(x, self.f_infinity_fit[0], self.f_infinity_fit[1]) for x in x_values],
plt.plot(self.stimulus_values, self.f_inf_frequencies, 'o', color='green', label='f_inf')
plt.plot(x_values, [fu.clipped_line(x, self.f_inf_fit[0], self.f_inf_fit[1]) for x in x_values],
color='darkgreen', label='f_inf_fit')
if comp_f_infs is not None:
plt.plot(self.stimulus_value, comp_f_infs, 'o', color='lime', label='comp values f_inf')
plt.plot(self.stimulus_value, self.f_zeros, 'o', color='orange', label='f_zero')
popt = self.boltzmann_fit_vars
plt.plot(self.stimulus_values, self.f_zero_frequencies, 'o', color='orange', label='f_zero')
popt = self.f_zero_fit
plt.plot(x_values, [fu.full_boltzmann(x, popt[0], popt[1], popt[2], popt[3]) for x in x_values],
color='red', label='f_0_fit')
if comp_f_zeros is not None:
plt.plot(self.stimulus_value, comp_f_zeros, 'o', color='wheat', label='comp_values f_zero')
plt.legend()
plt.ylabel("Frequency [Hz]")
if self.using_contrast:
plt.xlabel("Stimulus contrast")
plt.xlabel("Stimulus value")
if save_path is None:
plt.show()
else:
plt.xlabel("Stimulus intensity [mv]")
if savepath is None:
print("save")
plt.savefig(save_path + "fi_curve.png")
plt.close()
@staticmethod
def plot_fi_curve_comparision(data_fi_curve, model_fi_curve, save_path=None):
min_x = min(min(data_fi_curve.stimulus_values), min(model_fi_curve.stimulus_values))
max_x = max(max(data_fi_curve.stimulus_values), max(model_fi_curve.stimulus_values))
step = (max_x - min_x) / 5000
x_values = np.arange(min_x, max_x+step, step)
fig, axes = plt.subplots(1, 3, sharex="all", sharey='all', figsize=(15, 6))
# plot baseline
data_origin = (data_fi_curve, model_fi_curve)
f_base_color = ("blue", "deepskyblue")
f_inf_color = ("green", "limegreen")
f_zero_color = ("red", "orange")
for i in range(2):
axes[i].plot(data_origin[i].stimulus_values, data_origin[i].get_f_baseline_frequencies(),
color=f_base_color[i], label='f_base')
axes[i].plot(data_origin[i].stimulus_values, data_origin[i].get_f_inf_frequencies(),
'o', color=f_inf_color[i], label='f_inf')
y_values = [fu.clipped_line(x, data_origin[i].f_inf_fit[0], data_origin[i].f_inf_fit[1]) for x in x_values]
axes[i].plot(x_values, y_values, color=f_inf_color[i], label='f_inf_fit')
axes[i].plot(data_origin[i].stimulus_values, data_origin[i].get_f_zero_frequencies(),
'o', color=f_zero_color[i], label='f_zero')
popt = data_origin[i].f_zero_fit
axes[i].plot(x_values, [fu.full_boltzmann(x, popt[0], popt[1], popt[2], popt[3]) for x in x_values],
color=f_zero_color[i], label='f_0_fit')
axes[i].set_xlabel("Stimulus value - contrast")
axes[i].legend()
axes[0].set_title("cell")
axes[0].set_ylabel("Frequency [Hz]")
axes[1].set_title("model")
median_baseline = np.median(data_fi_curve.get_f_baseline_frequencies())
axes[2].plot((min_x, max_x), (median_baseline, median_baseline), color=f_base_color[0], label="cell med base")
axes[2].plot(model_fi_curve.stimulus_values, model_fi_curve.get_f_baseline_frequencies(),
'o', color=f_base_color[1], label='model base')
y_values = [fu.clipped_line(x, data_fi_curve.f_inf_fit[0], data_fi_curve.f_inf_fit[1]) for x in x_values]
axes[2].plot(x_values, y_values, color=f_inf_color[0], label='f_inf_fit cell')
axes[2].plot(model_fi_curve.stimulus_values, model_fi_curve.get_f_inf_frequencies(),
'o', color=f_inf_color[1], label='f_inf model')
popt = data_fi_curve.f_zero_fit
axes[2].plot(x_values, [fu.full_boltzmann(x, popt[0], popt[1], popt[2], popt[3]) for x in x_values],
color=f_zero_color[0], label='f_0_fit cell')
axes[2].plot(model_fi_curve.stimulus_values, model_fi_curve.get_f_zero_frequencies(),
'o', color=f_zero_color[1], label='f_zero model')
axes[2].set_title("cell model comparision")
axes[2].set_xlabel("Stimulus value - contrast")
axes[2].legend()
if save_path is None:
plt.show()
else:
print("save")
plt.savefig(savepath + "fi_curve.png")
plt.savefig(save_path + "fi_curve_comparision.png")
plt.close()
def plot_f_point_detections(self):
def plot_f_point_detections(self, save_path=None):
raise NotImplementedError("NOT YET OVERRIDDEN FROM ABSTRACT CLASS")
class FICurveCellData(FICurve):
def __init__(self, cell_data: CellData, stimulus_values):
self.cell_data = cell_data
super().__init__(stimulus_values)
def calculate_all_frequency_points(self):
mean_frequencies = self.cell_data.get_mean_isi_frequencies()
time_axes = self.cell_data.get_time_axes_mean_frequencies()
stimulus_start = self.cell_data.get_stimulus_start()
stimulus_duration = self.cell_data.get_stimulus_duration()
sampling_interval = self.cell_data.get_sampling_interval()
if len(mean_frequencies) == 0:
warn("FICurve:all_calculate_frequency_points(): mean_frequencies is empty.\n"
"Was all_calculate_mean_isi_frequencies already called?")
for i in range(len(mean_frequencies)):
if time_axes[i][0] > self.cell_data.get_stimulus_start():
raise ValueError("TODO: Deal with to strongly cut frequency traces in cell data! ")
# self.f_zero_frequencies.append(-1)
# self.f_baseline_frequencies.append(-1)
# self.f_inf_frequencies.append(-1)
# continue
f_zero = hF.detect_f_zero_in_frequency_trace(time_axes[i], mean_frequencies[i],
stimulus_start, sampling_interval)
self.f_zero_frequencies.append(f_zero)
f_baseline = hF.detect_f_baseline_in_freq_trace(time_axes[i], mean_frequencies[i],
stimulus_start, sampling_interval)
self.f_baseline_frequencies.append(f_baseline)
f_infinity = hF.detect_f_infinity_in_freq_trace(time_axes[i], mean_frequencies[i],
stimulus_start, stimulus_duration, sampling_interval)
self.f_inf_frequencies.append(f_infinity)
def get_f_zero_inverse_at_frequency(self, frequency):
# UNUSED
b_vars = self.f_zero_fit
return fu.inverse_full_boltzmann(frequency, b_vars[0], b_vars[1], b_vars[2], b_vars[3])
def get_f_infinity_frequency_at_stimulus_value(self, stimulus_value):
# UNUSED
infty_vars = self.f_inf_fit
return fu.clipped_line(stimulus_value, infty_vars[0], infty_vars[1])
# def get_fi_curve_slope_at(self, stimulus_value):
# fit_vars = self.f_zero_fit
# return fu.derivative_full_boltzmann(stimulus_value, fit_vars[0], fit_vars[1], fit_vars[2], fit_vars[3])
#
# def get_fi_curve_slope_of_straight(self):
# fit_vars = self.f_zero_fit
# return fu.full_boltzmann_straight_slope(fit_vars[0], fit_vars[1], fit_vars[2], fit_vars[3])
# def get_f_zero_and_f_inf_intersection(self):
# x_values = np.arange(min(self.stimulus_values), max(self.stimulus_values), 0.0001)
# fit_vars = self.f_zero_fit
# f_zero = fu.full_boltzmann(x_values, fit_vars[0], fit_vars[1], fit_vars[2], fit_vars[3])
# f_inf = fu.clipped_line(x_values, self.f_inf_fit[0], self.f_inf_fit[1])
#
# intersection_indicies = np.argwhere(np.diff(np.sign(f_zero - f_inf))).flatten()
# # print("fi-curve calc intersection:", intersection_indicies, x_values[intersection_indicies])
# if len(intersection_indicies) > 1:
# f_baseline = np.median(self.f_baseline_frequencies)
# best_dist = np.inf
# best_idx = -1
# for idx in intersection_indicies:
# dist = abs(fu.clipped_line(x_values[idx], self.f_inf_fit[0], self.f_inf_fit[1]) - f_baseline)
# if dist < best_dist:
# best_dist = dist
# best_idx = idx
#
# return x_values[best_idx]
#
# elif len(intersection_indicies) == 0:
# raise ValueError("No intersection found!")
# else:
# return x_values[intersection_indicies[0]]
# def get_fi_curve_slope_at_f_zero_intersection(self):
# x = self.get_f_zero_and_f_inf_intersection()
# fit_vars = self.f_zero_fit
# return fu.derivative_full_boltzmann(x, fit_vars[0], fit_vars[1], fit_vars[2], fit_vars[3])
# def plot_fi_curve(self, savepath: str = None, comp_f_baselines=None, comp_f_zeros=None, comp_f_infs=None):
# min_x = min(self.stimulus_values)
# max_x = max(self.stimulus_values)
# step = (max_x - min_x) / 5000
# x_values = np.arange(min_x, max_x, step)
#
# plt.plot(self.stimulus_values, self.f_baseline_frequencies, color='blue', label='f_base')
# if comp_f_baselines is not None:
# plt.plot(self.stimulus_values, comp_f_baselines, 'o', color='skyblue', label='comp_values base')
#
# plt.plot(self.stimulus_values, self.f_inf_frequencies, 'o', color='green', label='f_inf')
# plt.plot(x_values, [fu.clipped_line(x, self.f_inf_fit[0], self.f_inf_fit[1]) for x in x_values],
# color='darkgreen', label='f_inf_fit')
# if comp_f_infs is not None:
# plt.plot(self.stimulus_values, comp_f_infs, 'o', color='lime', label='comp values f_inf')
#
# plt.plot(self.stimulus_values, self.f_zero_frequencies, 'o', color='orange', label='f_zero')
# popt = self.f_zero_fit
# plt.plot(x_values, [fu.full_boltzmann(x, popt[0], popt[1], popt[2], popt[3]) for x in x_values],
# color='red', label='f_0_fit')
# if comp_f_zeros is not None:
# plt.plot(self.stimulus_values, comp_f_zeros, 'o', color='wheat', label='comp_values f_zero')
#
# plt.legend()
# plt.ylabel("Frequency [Hz]")
# plt.xlabel("Stimulus value")
#
# if savepath is None:
# plt.show()
# else:
# print("save")
# plt.savefig(savepath + "fi_curve.png")
# plt.close()
def plot_f_point_detections(self, save_path=None):
mean_frequencies = np.array(self.cell_data.get_mean_isi_frequencies())
time_axes = self.cell_data.get_time_axes_mean_frequencies()
for i in range(len(mean_frequencies)):
fig, axes = plt.subplots(1, 1, sharex="all")
axes.plot(time_axes[i], mean_frequencies[i], label="voltage")
axes.plot((time_axes[i][0], time_axes[i][-1]), (self.f_zeros[i], self.f_zeros[i]), label="f_zero")
axes.plot((time_axes[i][0], time_axes[i][-1]), (self.f_infinities[i], self.f_infinities[i]), '--', label="f_inf")
axes.plot((time_axes[i][0], time_axes[i][-1]), (self.f_baselines[i], self.f_baselines[i]), label="f_base")
axes.set_title(str(self.stimulus_value[i]))
axes.plot((time_axes[i][0], time_axes[i][-1]), (self.f_zero_frequencies[i], self.f_zero_frequencies[i]), label="f_zero")
axes.plot((time_axes[i][0], time_axes[i][-1]), (self.f_inf_frequencies[i], self.f_inf_frequencies[i]), '--', label="f_inf")
axes.plot((time_axes[i][0], time_axes[i][-1]), (self.f_baseline_frequencies[i], self.f_baseline_frequencies[i]), label="f_base")
axes.set_title(str(self.stimulus_values[i]))
plt.legend()
plt.show()
if save_path is None:
plt.show()
else:
plt.savefig(save_path + "GENERATE_NAMES.png")
plt.close()
class FICurveModel(FICurve):
def __init__(self, model, stimulus_values, eod_frequency):
self.eod_frequency = eod_frequency
self.model = model
super().__init__(stimulus_values)
def calculate_all_frequency_points(self):
stim_duration = 0.5
stim_start = 0.5
total_simulation_time = stim_duration + 2 * stim_start
sampling_interval = self.model.get_sampling_interval()
self.f_inf_frequencies = []
self.f_zero_frequencies = []
self.f_baseline_frequencies = []
for c in self.stimulus_values:
stimulus = SinusoidalStepStimulus(self.eod_frequency, c, stim_start, stim_duration)
_, spiketimes = self.model.simulate_fast(stimulus, total_simulation_time)
time, frequency = hF.calculate_time_and_frequency_trace(spiketimes, sampling_interval)
if len(spiketimes) < 10 or len(time) == 0 or min(time) > stim_start \
or max(time) < stim_start + stim_duration:
print("Too few spikes to calculate f_inf, f_0 and f_base")
self.f_inf_frequencies.append(0)
self.f_zero_frequencies.append(0)
self.f_baseline_frequencies.append(0)
continue
f_inf = hF.detect_f_infinity_in_freq_trace(time, frequency, stim_start, stim_duration, sampling_interval)
self.f_inf_frequencies.append(f_inf)
f_zero = hF.detect_f_zero_in_frequency_trace(time, frequency, stim_start, sampling_interval)
self.f_zero_frequencies.append(f_zero)
f_baseline = hF.detect_f_baseline_in_freq_trace(time, frequency, stim_start, sampling_interval)
self.f_baseline_frequencies.append(f_baseline)
def plot_f_point_detections(self, save_path=None):
raise NotImplementedError("TODO sorry... "
"The model version of the FiCurve class is still missing this implementation")
def get_fi_curve_class(data, stimulus_values, eod_freq=None) -> FICurve:
if isinstance(data, CellData):
return FICurveCellData(data, stimulus_values)
if isinstance(data, LifacNoiseModel):
if eod_freq is None:
raise ValueError("The FiCurveModel needs the eod variable to work")
return FICurveModel(data, stimulus_values, eod_freq)
raise ValueError("Unknown type: Cannot find corresponding Baseline class. Data was type:" + str(type(data)))

121
Fitter.py
View File

@ -3,7 +3,7 @@ from models.LIFACnoise import LifacNoiseModel
from stimuli.SinusoidalStepStimulus import SinusoidalStepStimulus
from CellData import CellData, icelldata_of_dir
from Baseline import get_baseline_class
from FiCurve import FICurve
from FiCurve import get_fi_curve_class
from AdaptionCurrent import Adaption
import helperFunctions as hF
import functions as fu
@ -40,19 +40,37 @@ def iget_start_parameters():
def run_with_real_data():
for cell_data in icelldata_of_dir("./data/"):
print("cell:", cell_data.get_data_path())
trace = cell_data.get_base_traces(trace_type=cell_data.V1)
if len(trace) == 0:
print("NO V1 TRACE FOUND")
continue
results_path = "results/" + os.path.split(cell_data.get_data_path())[-1] + "/"
print("results at:", results_path)
if not os.path.exists(results_path):
os.makedirs(results_path)
# plot cell images:
cell_save_path = results_path + "cell/"
if not os.path.exists(cell_save_path):
os.makedirs(cell_save_path)
data_baseline = get_baseline_class(cell_data)
data_baseline.plot_baseline(cell_save_path)
data_baseline.plot_interspike_interval_histogram(cell_save_path)
data_baseline.plot_serial_correlation(6, cell_save_path)
data_fi_curve = get_fi_curve_class(cell_data, cell_data.get_fi_contrasts())
data_fi_curve.plot_fi_curve(cell_save_path)
start_par_count = 0
for start_parameters in iget_start_parameters():
start_par_count += 1
print("START PARAMETERS:", start_par_count)
print("cell:", cell_data.get_data_path())
trace = cell_data.get_base_traces(trace_type=cell_data.V1)
if len(trace) == 0:
print("NO V1 TRACE FOUND")
continue
results_path = "results/" + os.path.split(cell_data.get_data_path())[-1] + "/"
print("results at:", results_path)
results_path += "parameter_set_{}".format(start_par_count) + "/"
parameter_set_path = results_path + "start_parameter_set_{}".format(start_par_count) + "/"
start_time = time.time()
fitter = Fitter()
@ -61,54 +79,49 @@ def run_with_real_data():
print(fmin)
print(parameters)
end_time = time.time()
if not os.path.exists(results_path):
os.makedirs(results_path)
with open(results_path + "parameters_info.txt".format(start_par_count), "w") as file:
if not os.path.exists(parameter_set_path):
os.makedirs(parameter_set_path)
with open(parameter_set_path + "parameters_info.txt".format(start_par_count), "w") as file:
file.writelines(["start_parameters:\t" + str(start_parameters),
"\nfinal_parameters:\t" + str(parameters),
"\nfinal_fmin:\t" + str(fmin)])
print('Fitting of cell took function took {:.3f} s'.format((end_time - start_time)))
# print(results_path)
print_comparision_cell_model(cell_data, parameters, plot=True, savepath=results_path)
break
print_comparision_cell_model(cell_data, data_baseline, data_fi_curve, parameters,
plot=True, save_path=parameter_set_path)
# from Sounds import play_finished_sound
# play_finished_sound()
pass
def print_comparision_cell_model(cell_data: CellData, parameters, plot=False, savepath=None):
res_model = LifacNoiseModel(parameters)
fi_curve = FICurve(cell_data)
def print_comparision_cell_model(cell_data, data_baseline, data_fi_curve, parameters, plot=False, save_path=None):
model = LifacNoiseModel(parameters)
eod_frequency = cell_data.get_eod_frequency()
model_baseline = get_baseline_class(res_model, cell_data.get_eod_frequency())
model_baseline = get_baseline_class(model, eod_frequency)
m_bf = model_baseline.get_baseline_frequency()
m_vs = model_baseline.get_vector_strength()
m_sc = model_baseline.get_serial_correlation(1)
m_cv = model_baseline.get_coefficient_of_variation()
_, m_f_zeros, m_f_infinities = res_model.calculate_fi_curve(fi_curve.stimulus_value,
cell_data.get_eod_frequency())
f_infinities_fit = hF.fit_clipped_line(fi_curve.stimulus_value, m_f_infinities)
m_f_infinities_slope = f_infinities_fit[0]
f_zeros_fit = hF.fit_boltzmann(fi_curve.stimulus_value, m_f_zeros)
m_f_zero_slope = fu.full_boltzmann_straight_slope(f_zeros_fit[0], f_zeros_fit[1], f_zeros_fit[2], f_zeros_fit[3])
model_ficurve = get_fi_curve_class(model, cell_data.get_fi_contrasts(), eod_frequency)
m_f_infinities = model_ficurve.get_f_inf_frequencies()
m_f_zeros = model_ficurve.get_f_zero_frequencies()
m_f_infinities_slope = model_ficurve.get_f_inf_slope()
m_f_zero_slope = model_ficurve.get_f_zero_fit_slope_at_straight()
data_baseline = get_baseline_class(cell_data)
c_bf = data_baseline.get_baseline_frequency()
c_vs = data_baseline.get_vector_strength()
c_sc = data_baseline.get_serial_correlation(1)
c_cv = data_baseline.get_coefficient_of_variation()
c_f_inf_slope = fi_curve.get_f_infinity_slope()
c_f_inf_values = fi_curve.f_infinities
c_f_inf_slope = data_fi_curve.get_f_inf_slope()
c_f_inf_values = data_fi_curve.f_inf_frequencies
c_f_zero_slope = fi_curve.get_fi_curve_slope_of_straight()
c_f_zero_values = fi_curve.f_zeros
c_f_zero_slope = data_fi_curve.get_f_zero_fit_slope_at_straight()
c_f_zero_values = data_fi_curve.f_zero_frequencies
print("EOD-frequency: {:.2f}".format(cell_data.get_eod_frequency()))
print("bf: cell - {:.2f} vs model {:.2f}".format(c_bf, m_bf))
print("vs: cell - {:.2f} vs model {:.2f}".format(c_vs, m_vs))
@ -119,8 +132,8 @@ def print_comparision_cell_model(cell_data: CellData, parameters, plot=False, sa
print("f_zero_slope: cell - {:.2f} vs model {:.2f}".format(c_f_zero_slope, m_f_zero_slope))
print("f zero values:\n cell -", c_f_zero_values, "\n model -", m_f_zeros)
if savepath is not None:
with open(savepath + "value_comparision.tsv", 'w') as value_file:
if save_path is not None:
with open(save_path + "value_comparision.tsv", 'w') as value_file:
value_file.write("Variable\tCell\tModel\n")
value_file.write("baseline_frequency\t{:.2f}\t{:.2f}\n".format(c_bf, m_bf))
value_file.write("vector_strength\t{:.2f}\t{:.2f}\n".format(c_vs, m_vs))
@ -130,26 +143,13 @@ def print_comparision_cell_model(cell_data: CellData, parameters, plot=False, sa
value_file.write("f_zero_slope\t{:.2f}\t{:.2f}\n".format(c_f_zero_slope, m_f_zero_slope))
if plot:
# plot cell images:
cell_save_path = savepath + "/cell/"
if not os.path.exists(cell_save_path):
os.makedirs(cell_save_path)
# data_baseline.plot_baseline(cell_save_path + "baseline.png")
data_baseline.plot_inter_spike_interval_histogram(cell_save_path + "isi-histogram.png")
data_baseline.plot_serial_correlation(6, cell_save_path + "serial_correlation.png")
# plot model images
model_save_path = savepath + "/model/"
if not os.path.exists(model_save_path):
os.makedirs(model_save_path)
# model_baseline.plot_baseline(model_save_path + "baseline.png")
model_baseline.plot_inter_spike_interval_histogram(model_save_path + "isi-histogram.png")
model_baseline.plot_serial_correlation(6, model_save_path + "serial_correlation.png")
if plot:
f_b, f_zero, f_inf = res_model.calculate_fi_curve(cell_data.get_fi_contrasts(), cell_data.get_eod_frequency())
model_baseline.plot_baseline(save_path)
model_baseline.plot_interspike_interval_histogram(save_path)
model_baseline.plot_serial_correlation(6, save_path)
fi_curve.plot_fi_curve(savepath=savepath, comp_f_baselines=f_b, comp_f_zeros=f_zero, comp_f_infs=f_inf)
model_ficurve.plot_fi_curve(save_path)
model_ficurve.plot_fi_curve_comparision(data_fi_curve, model_ficurve, save_path)
class Fitter:
@ -196,14 +196,14 @@ class Fitter:
self.serial_correlation = data_baseline.get_serial_correlation(self.sc_max_lag)
self.coefficient_of_variation = data_baseline.get_coefficient_of_variation()
fi_curve = FICurve(data, contrast=True)
self.fi_contrasts = fi_curve.stimulus_value
self.f_inf_values = fi_curve.f_infinities
self.f_inf_slope = fi_curve.get_f_infinity_slope()
fi_curve = get_fi_curve_class(data, data.get_fi_contrasts())
self.fi_contrasts = fi_curve.stimulus_values
self.f_inf_values = fi_curve.f_inf_frequencies
self.f_inf_slope = fi_curve.get_f_inf_slope()
self.f_zero_values = fi_curve.f_zeros
self.f_zero_fit = fi_curve.boltzmann_fit_vars
self.f_zero_slope = fi_curve.get_fi_curve_slope_of_straight()
self.f_zero_values = fi_curve.f_zero_frequencies
self.f_zero_fit = fi_curve.f_zero_fit
self.f_zero_slope = fi_curve.get_f_zero_fit_slope_at_straight()
# around 1/3 of the value at straight
# self.f_zero_slope = fi_curve.get_fi_curve_slope_at(fi_curve.get_f_zero_and_f_inf_intersection())
@ -216,7 +216,6 @@ class Fitter:
# print("delta_a: {:.3f}".format(self.delta_a), "tau_a: {:.3f}".format(self.tau_a))
return self.fit_routine_5(data, start_parameters)
# return self.fit_model(fit_adaption=False)
def fit_routine_5(self, cell_data=None, start_parameters=None):
# [error_bf, error_vs, error_sc, error_cv, error_f_inf, error_f_inf_slope, error_f_zero, error_f_zero_slope]
@ -228,7 +227,7 @@ class Fitter:
x0 = np.array([start_parameters["mem_tau"], start_parameters["noise_strength"],
start_parameters["input_scaling"], self.tau_a, self.delta_a, start_parameters["dend_tau"]])
initial_simplex = create_init_simples(x0, search_scale=2)
error_weights = (0, 2, 3, 1, 1, 1, 0.5, 1)
error_weights = (0, 2, 5, 1, 1, 1, 0.5, 1)
fmin = minimize(fun=self.cost_function_all,
args=(error_weights,), x0=x0, method="Nelder-Mead",
options={"initial_simplex": initial_simplex, "xatol": 0.001, "maxfev": 400, "maxiter": 400})

View File

@ -1,92 +0,0 @@
from FiCurve import FICurve
from CellData import CellData
from models.LIFACnoise import LifacNoiseModel
import helperFunctions as hF
import functions as fu
import numpy as np
CELL_PATH = "data/2012-06-27-ah-invivo-1/"
# current parameters from fit with folus on improving model f0 response
# MODEL_PARAMETERS = {'step_size': 5e-05, 'mem_tau': 0.042542178602690675, 'v_base': 0, 'v_zero': 0, 'threshold': 1, 'v_offset': -111.328125, 'input_scaling': 388.9439738592248, 'delta_a': 0.05513136301255167, 'tau_a': 0.1017720885626184, 'a_zero': 2, 'noise_strength': 0.01740931732483443}
# parameters fit with fixed adaption focus on serial cor and f_inf_slope
MODEL_PARAMETERS = {'step_size': 5e-05, 'mem_tau': 0.03547683648372142, 'v_base': 0, 'v_zero': 0, 'threshold': 1, 'v_offset': -43.75, 'input_scaling': 162.97353975832954, 'delta_a': 0.024625305808413798, 'tau_a': 0.07632538029074364, 'a_zero': 2, 'noise_strength': 0.00408169739163286}
SAVE_PATH = "results/test/"
def main():
cell_data = CellData(CELL_PATH)
fi_curve = FICurve(cell_data)
model = LifacNoiseModel(MODEL_PARAMETERS)
print_characteristics(cell_data, fi_curve, model)
plot_fi_curve(cell_data, fi_curve, model)
def print_characteristics(cell_data: CellData, fi_curve: FICurve, model):
sc_max_lag = 1
eod_freq = cell_data.get_eod_frequency()
fi_contrasts = fi_curve.stimulus_value
cell_bf = cell_data.get_base_frequency()
cell_sc = cell_data.get_serial_correlation(sc_max_lag)
cell_vs = cell_data.get_vector_strength()
cell_f_inf_slope = fi_curve.get_f_infinity_slope()
cell_f_inf_values = fi_curve.f_infinities
cell_f_zero_slope = fi_curve.get_fi_curve_slope_of_straight()
cell_f_zero_values = fi_curve.f_zeros
# calculate Model characteristics:
baseline_freq, vector_strength, serial_correlation = model.calculate_baseline_markers(eod_freq, sc_max_lag)
f_baselines, f_zeros, f_infinities = model.calculate_fi_curve(fi_contrasts, eod_freq)
f_infinities_fit = hF.fit_clipped_line(fi_contrasts, f_infinities)
f_infinities_slope = f_infinities_fit[0]
f_zeros_fit = hF.fit_boltzmann(fi_contrasts, f_zeros)
f_zero_slope = fu.full_boltzmann_straight_slope(f_zeros_fit[0], f_zeros_fit[1], f_zeros_fit[2], f_zeros_fit[3])
print_value("Base frequency", cell_bf, baseline_freq)
for i in range(sc_max_lag):
print_value("Serial correlation lag {}".format(i+1), cell_sc[i], serial_correlation[i])
print_value("Vector strength", cell_vs, vector_strength)
print_value("f_inf slope", cell_f_inf_slope, f_infinities_slope)
print_f_values("f_inf values", cell_f_inf_values, f_infinities)
print_value("f_zero slope", cell_f_zero_slope, f_zero_slope)
print_f_values("f_zero values", cell_f_zero_values, f_zeros)
def print_value(name, cell_value, model_value):
print("{} - expected: {:.2f}, current: {:.2f}, %-error: {:.3f}".format(name,
cell_value, model_value, (model_value-cell_value)/cell_value))
def print_f_values(name, cell_values, model_values):
cell_values = np.array(cell_values)
model_values = np.array(model_values)
mean_perc_error = 0
for c,m in zip(cell_values, model_values):
mean_perc_error += (m-c)/ c
mean_perc_error = mean_perc_error/ len(cell_values)
print("{}:\nexpected:".format(name), np.around(cell_values), "\ncurrent: ", np.around(model_values),
"\nmean %-error: {:.3f}".format(mean_perc_error))
def plot_fi_curve(cell_data, fi_curve, model, save=False):
f_b, f_zero, f_inf = model.calculate_fi_curve(cell_data.get_fi_contrasts(), cell_data.get_eod_frequency())
if save:
fi_curve.plot_fi_curve(savepath=SAVE_PATH, comp_f_baselines=f_b, comp_f_zeros=f_zero, comp_f_infs=f_inf)
else:
fi_curve.plot_fi_curve(comp_f_baselines=f_b, comp_f_zeros=f_zero, comp_f_infs=f_inf)
if __name__ == '__main__':
main()

View File

@ -208,7 +208,7 @@ class Fitter:
self.coefficient_of_variation = data.get_coefficient_of_variation()
fi_curve = FICurve(data, contrast=True)
self.fi_contrasts = fi_curve.stimulus_value
self.fi_contrasts = fi_curve.stimulus_values
print("Fitter: fi-contrasts", self.fi_contrasts)
self.f_infinities = fi_curve.f_infinities
self.f_infinities_slope = fi_curve.get_f_infinity_slope()