seperate baseline attribute calculation

This commit is contained in:
a.ott
2020-05-11 13:56:56 +02:00
parent 9485492f4d
commit 11c37c9f2a
4 changed files with 283 additions and 87 deletions

View File

@@ -1,4 +1,3 @@
from stimuli.AbstractStimulus import AbstractStimulus
from models.AbstractModel import AbstractModel
import numpy as np
@@ -10,6 +9,7 @@ from scipy.optimize import curve_fit
from warnings import warn
import matplotlib.pyplot as plt
class LifacNoiseModel(AbstractModel):
# all times in milliseconds
# possible mem_res: 100 * 1000000 exact value unknown in p-units
@@ -56,7 +56,8 @@ class LifacNoiseModel(AbstractModel):
for i in range(1, len(time), 1):
time_point = time[i]
# rectified input:
stimulus_strength = self._calculate_input_voltage_step(input_voltage[i-1], fu.rectify(stimulus.value_at_time_in_s(time_point)))
stimulus_strength = self._calculate_input_voltage_step(input_voltage[i - 1],
fu.rectify(stimulus.value_at_time_in_s(time_point)))
v_next = self._calculate_voltage_step(current_v, stimulus_strength - current_a)
a_next = self._calculate_adaption_step(current_a)
@@ -97,7 +98,9 @@ class LifacNoiseModel(AbstractModel):
def _calculate_input_voltage_step(self, current_i, rectified_input):
# input_voltage[i] = input_voltage[i - 1] + (-input_voltage[i - 1] + rectified_stimulus_array[i] * input_scaling) / dend_tau
return current_i + ((-current_i + rectified_input * self.parameters["input_scaling"]) / self.parameters["dend_tau"]) * self.parameters["step_size"]
return current_i + (
(-current_i + rectified_input * self.parameters["input_scaling"]) / self.parameters["dend_tau"]) * \
self.parameters["step_size"]
def simulate_fast(self, stimulus: AbstractStimulus, total_time_s, time_start=0):
@@ -115,7 +118,9 @@ class LifacNoiseModel(AbstractModel):
dend_tau = self.parameters["dend_tau"]
rectified_stimulus = rectify_stimulus_array(stimulus.as_array(time_start, total_time_s, step_size))
parameters = np.array([v_zero, a_zero, step_size, threshold, v_base, delta_a, tau_a, v_offset, mem_tau, noise_strength, time_start, input_scaling, dend_tau])
parameters = np.array(
[v_zero, a_zero, step_size, threshold, v_base, delta_a, tau_a, v_offset, mem_tau, noise_strength,
time_start, input_scaling, dend_tau])
voltage_trace, adaption, spiketimes, input_voltage = simulate_fast(rectified_stimulus, total_time_s, parameters)
@@ -168,31 +173,6 @@ class LifacNoiseModel(AbstractModel):
def get_model_copy(self):
return LifacNoiseModel(self.parameters)
def calculate_baseline_markers(self, stimulus_freq, max_lag=1, simulation_time=30):
"""
calculates the baseline markers baseline frequency, vector strength and serial correlation
based on simulated 30 seconds with a standard Sinusoidal stimulus with the given frequency
:return: baseline_freq, vs, sc
"""
base_stimulus = SinusoidalStepStimulus(stimulus_freq, 0)
_, spiketimes = self.simulate_fast(base_stimulus, simulation_time)
time_x = 5
baseline_freq = hF.mean_freq_of_spiketimes_after_time_x(spiketimes, time_x)
if baseline_freq < 1:
return baseline_freq, 0, [0]*max_lag
else:
time_trace = np.arange(0, 30, self.get_sampling_interval())
stimulus_array = base_stimulus.as_array(0, 30, self.get_sampling_interval())
vector_strength = hF.calculate_vector_strength_from_spiketimes(time_trace, stimulus_array, spiketimes, self.get_sampling_interval())
serial_correlation = hF.calculate_serial_correlation(np.array(spiketimes), max_lag)
coeffient_of_variation = hF.calculate_coefficient_of_variation(np.array(spiketimes))
return baseline_freq, vector_strength, serial_correlation, coeffient_of_variation
def calculate_fi_markers(self, contrasts, stimulus_freq):
"""
calculates the fi markers f_infinity, f_infinity_slope for given contrasts
@@ -204,9 +184,10 @@ class LifacNoiseModel(AbstractModel):
f_infinities = []
for contrast in contrasts:
stimulus = SinusoidalStepStimulus(stimulus_freq, contrast, stimulus_start, stimulus_duration)
_, spiketimes = self.simulate_fast(stimulus, stimulus_start*2+stimulus_duration)
_, spiketimes = self.simulate_fast(stimulus, stimulus_start * 2 + stimulus_duration)
time, freq = hF.calculate_time_and_frequency_trace(spiketimes, self.get_sampling_interval())
f_inf = hF.detect_f_infinity_in_freq_trace(time, freq, stimulus_start, stimulus_duration, self.get_sampling_interval())
f_inf = hF.detect_f_infinity_in_freq_trace(time, freq, stimulus_start, stimulus_duration,
self.get_sampling_interval())
f_infinities.append(f_inf)
popt = hF.fit_clipped_line(contrasts, f_infinities)
@@ -217,7 +198,6 @@ class LifacNoiseModel(AbstractModel):
def calculate_fi_curve(self, contrasts, stimulus_freq):
stim_duration = 0.5
stim_start = 0.5
total_simulation_time = stim_duration + 2 * stim_start
@@ -240,7 +220,8 @@ class LifacNoiseModel(AbstractModel):
# plt.plot(frequency)
# plt.show()
if len(spiketimes) < 10 or len(time) == 0 or min(time) > stim_start or max(time) < stim_start+stim_duration:
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")
f_infinities.append(0)
f_zeros.append(0)
@@ -290,16 +271,18 @@ class LifacNoiseModel(AbstractModel):
lower_bound = current_v_offset - v_search_step_size
upper_bound = current_v_offset
return binary_search_base_freq(test_model, base_stimulus, goal_baseline_frequency, simulation_length, lower_bound, upper_bound, threshold)
return binary_search_base_freq(test_model, base_stimulus, goal_baseline_frequency, simulation_length,
lower_bound, upper_bound, threshold)
def binary_search_base_freq(model: LifacNoiseModel, base_stimulus, goal_frequency, simulation_length, lower_bound, upper_bound, threshold):
def binary_search_base_freq(model: LifacNoiseModel, base_stimulus, goal_frequency, simulation_length, lower_bound,
upper_bound, threshold):
counter = 0
if threshold <= 0:
raise ValueError("binary_search_base_freq() - LifacNoiseModel: threshold is not allowed to be negative!")
while True:
counter += 1
middle = upper_bound - (upper_bound - lower_bound)/2
middle = upper_bound - (upper_bound - lower_bound) / 2
frequency = test_v_offset(model, middle, base_stimulus, simulation_length)
# print('{:.1f}, {:.1f}, {:.1f}, {:.1f} vs {:.1f} '.format(lower_bound, middle, upper_bound, frequency, goal_frequency))
@@ -311,10 +294,11 @@ def binary_search_base_freq(model: LifacNoiseModel, base_stimulus, goal_frequenc
elif frequency > goal_frequency:
upper_bound = middle
else:
print('lower bound: {:.1f}, middle: {:.1f}, upper_bound: {:.1f}, frequency: {:.1f} vs goal: {:.1f} '.format(lower_bound, middle, upper_bound, frequency, goal_frequency))
print('lower bound: {:.1f}, middle: {:.1f}, upper_bound: {:.1f}, frequency: {:.1f} vs goal: {:.1f} '.format(
lower_bound, middle, upper_bound, frequency, goal_frequency))
raise ValueError("binary_search_base_freq() - LifacNoiseModel: Goal frequency might be nan?")
if abs(upper_bound-lower_bound) < 0.0001:
if abs(upper_bound - lower_bound) < 0.0001:
warn("Search was stopped no value was found!")
return middle
@@ -373,18 +357,15 @@ def simulate_fast(rectified_stimulus_array, total_time_s, parameters: np.ndarray
noise_value = np.random.normal()
noise = noise_strength * noise_value / np.sqrt(step_size)
input_voltage[i] = input_voltage[i - 1] + ((-input_voltage[i - 1] + rectified_stimulus_array[i]) / dend_tau) * step_size
output_voltage[i] = output_voltage[i-1] + ((v_base - output_voltage[i-1] + v_offset + (input_voltage[i] * input_scaling) - adaption[i-1] + noise) / mem_tau) * step_size
adaption[i] = adaption[i-1] + ((-adaption[i-1]) / tau_a) * step_size
input_voltage[i] = input_voltage[i - 1] + (
(-input_voltage[i - 1] + rectified_stimulus_array[i]) / dend_tau) * step_size
output_voltage[i] = output_voltage[i - 1] + ((v_base - output_voltage[i - 1] + v_offset + (
input_voltage[i] * input_scaling) - adaption[i - 1] + noise) / mem_tau) * step_size
adaption[i] = adaption[i - 1] + ((-adaption[i - 1]) / tau_a) * step_size
if output_voltage[i] > threshold:
output_voltage[i] = v_base
spiketimes.append(i*step_size)
spiketimes.append(i * step_size)
adaption[i] += delta_a / tau_a
return output_voltage, adaption, spiketimes, input_voltage