move detection (f_zero,...) and fitting to helperfunctions

This commit is contained in:
AlexanderOtt 2020-04-02 10:09:10 +02:00
parent af40a60189
commit d2e83e8bc2

View File

@ -6,6 +6,7 @@ from scipy.stats import linregress
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from warnings import warn from warnings import warn
import functions as fu import functions as fu
import helperFunctions as hF
class FICurve: class FICurve:
@ -29,12 +30,16 @@ class FICurve:
self.f_infinity_fit = [] self.f_infinity_fit = []
self.all_calculate_frequency_points() self.all_calculate_frequency_points()
self.fit_line() self.f_infinity_fit = hF.fit_clipped_line(self.stimulus_value, self.f_infinities)
self.fit_boltzmann() self.boltzmann_fit_vars = hF.fit_boltzmann(self.stimulus_value, self.f_zeros)
def all_calculate_frequency_points(self): def all_calculate_frequency_points(self):
mean_frequencies = self.cell_data.get_mean_isi_frequencies() mean_frequencies = self.cell_data.get_mean_isi_frequencies()
time_axes = self.cell_data.get_time_axes_mean_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: if len(mean_frequencies) == 0:
warn("FICurve:all_calculate_frequency_points(): mean_frequencies is empty.\n" warn("FICurve:all_calculate_frequency_points(): mean_frequencies is empty.\n"
"Was all_calculate_mean_isi_frequencies already called?") "Was all_calculate_mean_isi_frequencies already called?")
@ -48,110 +53,97 @@ class FICurve:
self.f_infinities.append(-1) self.f_infinities.append(-1)
continue continue
self.f_zeros.append(self.__calculate_f_zero__(time_axes[i], mean_frequencies[i])) f_zero = hF.detect_f_zero_in_frequency_trace(time_axes[i], mean_frequencies[i],
self.f_baselines.append(self.__calculate_f_baseline__(time_axes[i], mean_frequencies[i])) stimulus_start, sampling_interval)
self.f_infinities.append(self.__calculate_f_infinity__(time_axes[i], mean_frequencies[i])) 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 fit_line(self): # def __calculate_f_baseline__(self, time, frequency, buffer=0.025):
popt, pcov = curve_fit(fu.clipped_line, self.stimulus_value, self.f_infinities) #
self.f_infinity_fit = popt # stim_start = self.cell_data.get_stimulus_start() - time[0]
# sampling_interval = self.cell_data.get_sampling_interval()
def fit_boltzmann(self): # if stim_start < 0.1:
max_f0 = float(max(self.f_zeros)) # warn("FICurve:__calculate_f_baseline__(): Quite short delay at the start.")
min_f0 = 0.1 # float(min(self.f_zeros)) #
mean_int = float(np.mean(self.stimulus_value)) # start_idx = 0
# end_idx = int((stim_start-buffer)/sampling_interval)
total_increase = max_f0 - min_f0 # f_baseline = np.mean(frequency[start_idx:end_idx])
total_change_int = max(self.stimulus_value) - min(self.stimulus_value) #
start_k = float((total_increase / total_change_int * 4) / max_f0) # return f_baseline
#
popt, pcov = curve_fit(fu.full_boltzmann, self.stimulus_value, self.f_zeros, # def __calculate_f_zero__(self, time, frequency, peak_buffer_percent=0.05, buffer=0.025):
p0=(max_f0, min_f0, start_k, mean_int), #
maxfev=10000, bounds=([0, 0, -np.inf, -np.inf], [5000, 1, np.inf, np.inf])) # stimulus_start = self.cell_data.get_stimulus_start() - time[0] # time start is generally != 0 and != delay
# sampling_interval = self.cell_data.get_sampling_interval()
self.boltzmann_fit_vars = popt #
# freq_before = frequency[0:int((stimulus_start - buffer) / sampling_interval)]
def __calculate_f_baseline__(self, time, frequency, buffer=0.025): # min_before = min(freq_before)
# max_before = max(freq_before)
stim_start = self.cell_data.get_stimulus_start() - time[0] # mean_before = np.mean(freq_before)
sampling_interval = self.cell_data.get_sampling_interval() #
if stim_start < 0.1: # # time where the f-zero is searched in
warn("FICurve:__calculate_f_baseline__(): Quite short delay at the start.") # start_idx = int((stimulus_start-0.1*buffer) / sampling_interval)
# end_idx = int((stimulus_start + buffer) / sampling_interval)
start_idx = 0 #
end_idx = int((stim_start-buffer)/sampling_interval) # min_during_start_of_stim = min(frequency[start_idx:end_idx])
f_baseline = np.mean(frequency[start_idx:end_idx]) # max_during_start_of_stim = max(frequency[start_idx:end_idx])
#
return f_baseline # if abs(mean_before-min_during_start_of_stim) > abs(max_during_start_of_stim-mean_before):
# f_zero = min_during_start_of_stim
def __calculate_f_zero__(self, time, frequency, peak_buffer_percent=0.05, buffer=0.025): # else:
# f_zero = max_during_start_of_stim
stimulus_start = self.cell_data.get_stimulus_start() - time[0] # time start is generally != 0 and != delay #
sampling_interval = self.cell_data.get_sampling_interval() # peak_buffer = (max_before - min_before) * peak_buffer_percent
# if min_before - peak_buffer <= f_zero <= max_before + peak_buffer:
freq_before = frequency[0:int((stimulus_start - buffer) / sampling_interval)] # end_idx = start_idx + int((end_idx-start_idx)/2)
min_before = min(freq_before) # f_zero = np.mean(frequency[start_idx:end_idx])
max_before = max(freq_before) #
mean_before = np.mean(freq_before) # return f_zero
#
# time where the f-zero is searched in # # start_idx = int(stimulus_start / sampling_interval)
start_idx = int((stimulus_start-0.1*buffer) / sampling_interval) # # end_idx = int((stimulus_start + buffer*2) / sampling_interval)
end_idx = int((stimulus_start + buffer) / sampling_interval) # #
# # freq_before = frequency[start_idx-(int(length_of_mean/sampling_interval)):start_idx]
min_during_start_of_stim = min(frequency[start_idx:end_idx]) # # fb_mean = np.mean(freq_before)
max_during_start_of_stim = max(frequency[start_idx:end_idx]) # # fb_std = np.std(freq_before)
# #
if abs(mean_before-min_during_start_of_stim) > abs(max_during_start_of_stim-mean_before): # # peak_frequency = fb_mean
f_zero = min_during_start_of_stim # # count = 0
else: # # for i in range(start_idx + 1, end_idx):
f_zero = max_during_start_of_stim # # if fb_mean-3*fb_std <= frequency[i] <= fb_mean+3*fb_std:
# # continue
peak_buffer = (max_before - min_before) * peak_buffer_percent # #
if min_before - peak_buffer <= f_zero <= max_before + peak_buffer: # # if abs(frequency[i] - fb_mean) > abs(peak_frequency - fb_mean):
end_idx = start_idx + int((end_idx-start_idx)/2) # # peak_frequency = frequency[i]
f_zero = np.mean(frequency[start_idx:end_idx]) # # count += 1
#
return f_zero # # return peak_frequency
#
# start_idx = int(stimulus_start / sampling_interval) # def __calculate_f_infinity__(self, time, frequency, length=0.1, buffer=0.025):
# end_idx = int((stimulus_start + buffer*2) / sampling_interval) # stimulus_end_time = self.cell_data.get_stimulus_start() + self.cell_data.get_stimulus_duration() - time[0]
# #
# freq_before = frequency[start_idx-(int(length_of_mean/sampling_interval)):start_idx] # start_idx = int((stimulus_end_time - length - buffer) / self.cell_data.get_sampling_interval())
# fb_mean = np.mean(freq_before) # end_idx = int((stimulus_end_time - buffer) / self.cell_data.get_sampling_interval())
# fb_std = np.std(freq_before) #
# # # TODO add way to plot detected f_zero, f_inf, f_base. With detection of remaining slope?
# peak_frequency = fb_mean # # x = np.arange(start_idx, end_idx, 1) # time[start_idx:end_idx]
# count = 0 # # slope, intercept, r_value, p_value, std_err = linregress(x, frequency[start_idx:end_idx])
# for i in range(start_idx + 1, end_idx): # # if p_value < 0.0001:
# if fb_mean-3*fb_std <= frequency[i] <= fb_mean+3*fb_std: # # plt.title("significant slope: {:.2f}, p: {:.5f}, r: {:.5f}".format(slope, p_value, r_value))
# continue # # plt.plot(x, [i*slope + intercept for i in x], color="black")
# # #
# if abs(frequency[i] - fb_mean) > abs(peak_frequency - fb_mean): # #
# peak_frequency = frequency[i] # # plt.plot((start_idx, end_idx), (np.mean(frequency[start_idx:end_idx]), np.mean(frequency[start_idx:end_idx])), label="f_inf")
# count += 1 # # plt.legend()
# # plt.show()
# return peak_frequency # # plt.close()
#
def __calculate_f_infinity__(self, time, frequency, length=0.1, buffer=0.025): # return np.mean(frequency[start_idx:end_idx])
stimulus_end_time = self.cell_data.get_stimulus_start() + self.cell_data.get_stimulus_duration() - time[0]
start_idx = int((stimulus_end_time - length - buffer) / self.cell_data.get_sampling_interval())
end_idx = int((stimulus_end_time - buffer) / self.cell_data.get_sampling_interval())
# TODO add way to plot detected f_zero, f_inf, f_base. With detection of remaining slope?
# x = np.arange(start_idx, end_idx, 1) # time[start_idx:end_idx]
# slope, intercept, r_value, p_value, std_err = linregress(x, frequency[start_idx:end_idx])
# if p_value < 0.0001:
# plt.title("significant slope: {:.2f}, p: {:.5f}, r: {:.5f}".format(slope, p_value, r_value))
# plt.plot(x, [i*slope + intercept for i in x], color="black")
#
#
# plt.plot((start_idx, end_idx), (np.mean(frequency[start_idx:end_idx]), np.mean(frequency[start_idx:end_idx])), label="f_inf")
# plt.legend()
# plt.show()
# plt.close()
return np.mean(frequency[start_idx:end_idx])
def get_f_zero_inverse_at_frequency(self, frequency): def get_f_zero_inverse_at_frequency(self, frequency):
b_vars = self.boltzmann_fit_vars b_vars = self.boltzmann_fit_vars
@ -226,7 +218,6 @@ class FICurve:
if comp_f_zeros is not None: if comp_f_zeros is not None:
plt.plot(self.stimulus_value, comp_f_zeros, 'o', color='wheat', label='comp_values f_zero') plt.plot(self.stimulus_value, comp_f_zeros, 'o', color='wheat', label='comp_values f_zero')
plt.legend() plt.legend()
plt.ylabel("Frequency [Hz]") plt.ylabel("Frequency [Hz]")
if self.using_contrast: if self.using_contrast:
@ -236,6 +227,7 @@ class FICurve:
if savepath is None: if savepath is None:
plt.show() plt.show()
else: else:
print("save")
plt.savefig(savepath + "fi_curve.png") plt.savefig(savepath + "fi_curve.png")
plt.close() plt.close()
@ -246,9 +238,9 @@ class FICurve:
for i in range(len(mean_frequencies)): for i in range(len(mean_frequencies)):
fig, axes = plt.subplots(1, 1, sharex="all") fig, axes = plt.subplots(1, 1, sharex="all")
axes.plot(time_axes[i], mean_frequencies[i], label="voltage") 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_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_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.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.set_title(str(self.stimulus_value[i]))
plt.legend() plt.legend()