From 1f82f062090408b66b626186998988e3b6f939d9 Mon Sep 17 00:00:00 2001 From: "a.ott" Date: Tue, 12 May 2020 14:14:55 +0200 Subject: [PATCH] separate FIcurve class, change fitter results structure --- AdaptionCurrent.py | 26 +-- Baseline.py | 100 ++++++----- DataParserFactory.py | 4 +- FiCurve.py | 387 ++++++++++++++++++++++++++++++++---------- Fitter.py | 121 +++++++------ compareModelVsCell.py | 92 ---------- fit_lifacnoise.py | 2 +- 7 files changed, 429 insertions(+), 303 deletions(-) delete mode 100644 compareModelVsCell.py diff --git a/AdaptionCurrent.py b/AdaptionCurrent.py index 944425f..332a108 100644 --- a/AdaptionCurrent.py +++ b/AdaptionCurrent.py @@ -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]") diff --git a/Baseline.py b/Baseline.py index a67a420..dd6faea 100644 --- a/Baseline.py +++ b/Baseline.py @@ -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: diff --git a/DataParserFactory.py b/DataParserFactory.py index 9ca3440..9e35330 100644 --- a/DataParserFactory.py +++ b/DataParserFactory.py @@ -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 diff --git a/FiCurve.py b/FiCurve.py index e6c7377..9100ff2 100644 --- a/FiCurve.py +++ b/FiCurve.py @@ -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))) diff --git a/Fitter.py b/Fitter.py index 013f3c3..3959fe5 100644 --- a/Fitter.py +++ b/Fitter.py @@ -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}) diff --git a/compareModelVsCell.py b/compareModelVsCell.py deleted file mode 100644 index 9f5c9bb..0000000 --- a/compareModelVsCell.py +++ /dev/null @@ -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() diff --git a/fit_lifacnoise.py b/fit_lifacnoise.py index 339b6c1..11341e5 100644 --- a/fit_lifacnoise.py +++ b/fit_lifacnoise.py @@ -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()