tau calculation and more

This commit is contained in:
alexanderott
2021-05-22 13:10:15 +02:00
parent 2a351795ad
commit ccca6e030b
10 changed files with 280 additions and 36 deletions

View File

@@ -6,6 +6,7 @@ import numpy as np
import matplotlib.pyplot as plt
from warnings import warn
from my_util import helperFunctions as hF, functions as fu
from scipy.optimize import curve_fit
from os.path import join, exists
import pickle
from sys import stderr
@@ -23,7 +24,7 @@ class FICurve:
self.f_inf_frequencies = []
self.indices_f_zero = []
self.f_zero_frequencies = []
self.taus = []
# increase, offset
self.f_inf_fit = []
# f_max, f_min, k, x_zero
@@ -45,9 +46,59 @@ class FICurve:
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)
def __calculate_time_constant_internal__(self, contrast, mean_frequency, baseline_freq, sampling_interval, pre_duration, plot=False):
time_constant_fit_length = 0.05
if contrast > 0:
maximum_idx = np.argmax(mean_frequency)
maximum = mean_frequency[maximum_idx]
start_fit_idx = maximum_idx
while (mean_frequency[start_fit_idx]) > 0.80 * (maximum - baseline_freq) + baseline_freq:
start_fit_idx += 1
else:
minimum_idx = np.argmin(mean_frequency)
minimum = mean_frequency[minimum_idx]
start_fit_idx = minimum_idx
# print("Border: ", baseline_freq - (0.80 * (baseline_freq - minimum)))
while (mean_frequency[start_fit_idx]) < baseline_freq - (0.80 * (baseline_freq - minimum)):
start_fit_idx += 1
# print("start:", start_fit_idx * sampling_interval - pre_duration)
end_fit_idx = start_fit_idx + int(time_constant_fit_length / sampling_interval)
x_values = np.arange(end_fit_idx - start_fit_idx) * sampling_interval
y_values = mean_frequency[start_fit_idx:end_fit_idx]
try:
popt, pcov = curve_fit(fu.exponential_function, x_values, y_values,
p0=(1 / (np.power(1, 10)), 5, 50), maxfev=100000)
# print(popt)
if plot:
if contrast > 0:
plt.title("c: {:.2f} Base_f: {:.2f}, f_zero: {:.2f}".format(contrast, baseline_freq, maximum))
else:
plt.title("c: {:.2f} Base_f: {:.2f}, f_zero: {:.2f}".format(contrast, baseline_freq, minimum))
plt.plot(np.arange(len(mean_frequency)) * sampling_interval - pre_duration, mean_frequency,
'.')
plt.plot(np.arange(start_fit_idx, end_fit_idx, 1) * sampling_interval - pre_duration, y_values,
color="darkgreen")
plt.plot(np.arange(start_fit_idx, end_fit_idx, 1) * sampling_interval - pre_duration,
fu.exponential_function(x_values, popt[0], popt[1], popt[2]), color="orange")
plt.show()
plt.close()
return popt, pcov
except RuntimeError:
print("RuntimeError happened in fit_exponential.")
return [], []
def calculate_all_frequency_points(self):
raise NotImplementedError("NOT YET OVERRIDDEN FROM ABSTRACT CLASS")
def calculate_time_constant(self, contrast_idx, plot=False):
raise NotImplementedError("NOT YET OVERRIDDEN FROM ABSTRACT CLASS")
def get_f_baseline_frequencies(self):
return self.f_baseline_frequencies
@@ -143,7 +194,7 @@ class FICurve:
plt.savefig(save_path + "mean_frequency_contrast_{:.2f}.png".format(sv))
plt.close()
def plot_fi_curve(self, save_path=None):
def plot_fi_curve(self, save_path=None, title=""):
min_x = min(self.stimulus_values)
max_x = max(self.stimulus_values)
step = (max_x - min_x) / 5000
@@ -161,6 +212,7 @@ class FICurve:
color='red', label='f_0_fit')
plt.legend()
plt.title(title)
plt.ylabel("Frequency [Hz]")
plt.xlabel("Stimulus value")
@@ -231,6 +283,33 @@ class FICurve:
plt.savefig(save_path + "fi_curve_comparision.png")
plt.close()
def write_detection_data_to_csv(self, save_path, name=""):
steady_state = self.get_f_inf_frequencies()
onset = self.get_f_zero_frequencies()
baseline = self.get_f_baseline_frequencies()
contrasts = self.stimulus_values
headers = ["contrasts", "f_baseline", "f_steady_state", "f_onset"]
if len(name) is not 0:
file_name = name
else:
file_name = "fi_data.csv"
with open(save_path + file_name, 'w') as f:
for i in range(len(headers)):
if i == 0:
f.write(headers[i])
else:
f.write("," + headers[i])
f.write("\n")
for i in range(len(contrasts)):
f.write(str(contrasts[i]) + ",")
f.write(str(baseline[i]) + ",")
f.write(str(steady_state[i]) + ",")
f.write(str(onset[i]) + "\n")
def plot_f_point_detections(self, save_path=None):
raise NotImplementedError("NOT YET OVERRIDDEN FROM ABSTRACT CLASS")
@@ -243,6 +322,11 @@ class FICurve:
values["f_zero_frequencies"] = self.f_zero_frequencies
values["f_inf_fit"] = self.f_inf_fit
values["f_zero_fit"] = self.f_zero_fit
taus = []
for i in range(len(self.stimulus_values)):
taus.append(self.calculate_time_constant(i))
values["time_constants"] = taus
with open(join(save_directory, self.save_file_name), "wb") as file:
pickle.dump(values, file)
@@ -267,6 +351,7 @@ class FICurve:
self.f_zero_frequencies = values["f_zero_frequencies"]
self.f_inf_fit = values["f_inf_fit"]
self.f_zero_fit = values["f_zero_fit"]
self.taus = values["time_constants"]
print("Fi-Curve: Values loaded!")
return True
@@ -277,6 +362,21 @@ class FICurveCellData(FICurve):
self.cell_data = cell_data
super().__init__(stimulus_values, save_dir, recalculate)
def calculate_time_constant(self, contrast_idx, plot=False):
if len(self.taus) > 0:
return self.taus[contrast_idx]
mean_frequency = self.cell_data.get_mean_fi_curve_isi_frequencies()[contrast_idx]
baseline_freq = self.get_f_baseline_frequencies()[contrast_idx]
pre_duration = -1*self.cell_data.get_recording_times()[0]
sampling_interval = self.cell_data.get_sampling_interval()
# __calculate_time_constant_internal__(self, contrast, mean_frequency, baseline_freq, sampling_interval, pre_duration, plot=False):
popt, pcov = super().__calculate_time_constant_internal__(self.stimulus_values[contrast_idx], mean_frequency,
baseline_freq, sampling_interval, pre_duration, plot=plot)
return popt[1]
def calculate_all_frequency_points(self):
mean_frequencies = self.cell_data.get_mean_fi_curve_isi_frequencies()
time_axes = self.cell_data.get_time_axes_fi_curve_mean_frequencies()
@@ -458,6 +558,22 @@ class FICurveModel(FICurve):
self.f_baseline_frequencies.append(f_baseline)
self.indices_f_baseline.append(f_base_idx)
def calculate_time_constant(self, contrast_idx, plot=False):
if len(self.taus) > 0:
return self.taus[contrast_idx]
mean_frequency = self.mean_frequency_traces[contrast_idx]
baseline_freq = self.get_f_baseline_frequencies()[contrast_idx]
pre_duration = 0
sampling_interval = self.model.get_sampling_interval()
popt, pcov = super().__calculate_time_constant_internal__(self.stimulus_values[contrast_idx], mean_frequency,
baseline_freq, sampling_interval, pre_duration, plot=plot)
if len(popt) > 0:
return popt[1]
else:
return -1
def get_mean_time_and_freq_traces(self):
return self.mean_time_traces, self.mean_frequency_traces