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],
def fit_line(self): stimulus_start, sampling_interval)
popt, pcov = curve_fit(fu.clipped_line, self.stimulus_value, self.f_infinities) self.f_baselines.append(f_baseline)
self.f_infinity_fit = popt f_infinity = hF.detect_f_infinity_in_freq_trace(time_axes[i], mean_frequencies[i],
stimulus_start, stimulus_duration, sampling_interval)
def fit_boltzmann(self): self.f_infinities.append(f_infinity)
max_f0 = float(max(self.f_zeros))
min_f0 = 0.1 # float(min(self.f_zeros)) # def __calculate_f_baseline__(self, time, frequency, buffer=0.025):
mean_int = float(np.mean(self.stimulus_value)) #
# stim_start = self.cell_data.get_stimulus_start() - time[0]
total_increase = max_f0 - min_f0 # sampling_interval = self.cell_data.get_sampling_interval()
total_change_int = max(self.stimulus_value) - min(self.stimulus_value) # if stim_start < 0.1:
start_k = float((total_increase / total_change_int * 4) / max_f0) # warn("FICurve:__calculate_f_baseline__(): Quite short delay at the start.")
#
popt, pcov = curve_fit(fu.full_boltzmann, self.stimulus_value, self.f_zeros, # start_idx = 0
p0=(max_f0, min_f0, start_k, mean_int), # end_idx = int((stim_start-buffer)/sampling_interval)
maxfev=10000, bounds=([0, 0, -np.inf, -np.inf], [5000, 1, np.inf, np.inf])) # f_baseline = np.mean(frequency[start_idx:end_idx])
#
self.boltzmann_fit_vars = popt # return f_baseline
#
def __calculate_f_baseline__(self, time, frequency, buffer=0.025): # def __calculate_f_zero__(self, time, frequency, peak_buffer_percent=0.05, buffer=0.025):
#
stim_start = self.cell_data.get_stimulus_start() - time[0] # 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() # sampling_interval = self.cell_data.get_sampling_interval()
if stim_start < 0.1: #
warn("FICurve:__calculate_f_baseline__(): Quite short delay at the start.") # freq_before = frequency[0:int((stimulus_start - buffer) / sampling_interval)]
# min_before = min(freq_before)
start_idx = 0 # max_before = max(freq_before)
end_idx = int((stim_start-buffer)/sampling_interval) # mean_before = np.mean(freq_before)
f_baseline = np.mean(frequency[start_idx:end_idx]) #
# # time where the f-zero is searched in
return f_baseline # start_idx = int((stimulus_start-0.1*buffer) / sampling_interval)
# end_idx = int((stimulus_start + buffer) / sampling_interval)
def __calculate_f_zero__(self, time, frequency, peak_buffer_percent=0.05, buffer=0.025): #
# min_during_start_of_stim = min(frequency[start_idx:end_idx])
stimulus_start = self.cell_data.get_stimulus_start() - time[0] # time start is generally != 0 and != delay # max_during_start_of_stim = max(frequency[start_idx:end_idx])
sampling_interval = self.cell_data.get_sampling_interval() #
# if abs(mean_before-min_during_start_of_stim) > abs(max_during_start_of_stim-mean_before):
freq_before = frequency[0:int((stimulus_start - buffer) / sampling_interval)] # f_zero = min_during_start_of_stim
min_before = min(freq_before) # else:
max_before = max(freq_before) # f_zero = max_during_start_of_stim
mean_before = np.mean(freq_before) #
# peak_buffer = (max_before - min_before) * peak_buffer_percent
# time where the f-zero is searched in # if min_before - peak_buffer <= f_zero <= max_before + peak_buffer:
start_idx = int((stimulus_start-0.1*buffer) / sampling_interval) # end_idx = start_idx + int((end_idx-start_idx)/2)
end_idx = int((stimulus_start + buffer) / sampling_interval) # f_zero = np.mean(frequency[start_idx:end_idx])
#
min_during_start_of_stim = min(frequency[start_idx:end_idx]) # return f_zero
max_during_start_of_stim = max(frequency[start_idx:end_idx]) #
# # start_idx = int(stimulus_start / sampling_interval)
if abs(mean_before-min_during_start_of_stim) > abs(max_during_start_of_stim-mean_before): # # end_idx = int((stimulus_start + buffer*2) / sampling_interval)
f_zero = min_during_start_of_stim # #
else: # # freq_before = frequency[start_idx-(int(length_of_mean/sampling_interval)):start_idx]
f_zero = max_during_start_of_stim # # fb_mean = np.mean(freq_before)
# # fb_std = np.std(freq_before)
peak_buffer = (max_before - min_before) * peak_buffer_percent # #
if min_before - peak_buffer <= f_zero <= max_before + peak_buffer: # # peak_frequency = fb_mean
end_idx = start_idx + int((end_idx-start_idx)/2) # # count = 0
f_zero = np.mean(frequency[start_idx:end_idx]) # # for i in range(start_idx + 1, end_idx):
# # if fb_mean-3*fb_std <= frequency[i] <= fb_mean+3*fb_std:
return f_zero # # continue
# #
# start_idx = int(stimulus_start / sampling_interval) # # if abs(frequency[i] - fb_mean) > abs(peak_frequency - fb_mean):
# end_idx = int((stimulus_start + buffer*2) / sampling_interval) # # peak_frequency = frequency[i]
# # # count += 1
# freq_before = frequency[start_idx-(int(length_of_mean/sampling_interval)):start_idx] #
# fb_mean = np.mean(freq_before) # # return peak_frequency
# fb_std = np.std(freq_before) #
# # def __calculate_f_infinity__(self, time, frequency, length=0.1, buffer=0.025):
# peak_frequency = fb_mean # stimulus_end_time = self.cell_data.get_stimulus_start() + self.cell_data.get_stimulus_duration() - time[0]
# count = 0 #
# for i in range(start_idx + 1, end_idx): # start_idx = int((stimulus_end_time - length - buffer) / self.cell_data.get_sampling_interval())
# if fb_mean-3*fb_std <= frequency[i] <= fb_mean+3*fb_std: # end_idx = int((stimulus_end_time - buffer) / self.cell_data.get_sampling_interval())
# continue #
# # # TODO add way to plot detected f_zero, f_inf, f_base. With detection of remaining slope?
# if abs(frequency[i] - fb_mean) > abs(peak_frequency - fb_mean): # # x = np.arange(start_idx, end_idx, 1) # time[start_idx:end_idx]
# peak_frequency = frequency[i] # # slope, intercept, r_value, p_value, std_err = linregress(x, frequency[start_idx:end_idx])
# count += 1 # # if p_value < 0.0001:
# # plt.title("significant slope: {:.2f}, p: {:.5f}, r: {:.5f}".format(slope, p_value, r_value))
# return peak_frequency # # plt.plot(x, [i*slope + intercept for i in x], color="black")
# #
def __calculate_f_infinity__(self, time, frequency, length=0.1, buffer=0.025): # #
stimulus_end_time = self.cell_data.get_stimulus_start() + self.cell_data.get_stimulus_duration() - time[0] # # 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()
start_idx = int((stimulus_end_time - length - buffer) / self.cell_data.get_sampling_interval()) # # plt.show()
end_idx = int((stimulus_end_time - buffer) / self.cell_data.get_sampling_interval()) # # plt.close()
#
# TODO add way to plot detected f_zero, f_inf, f_base. With detection of remaining slope? # return np.mean(frequency[start_idx:end_idx])
# 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()