tests, correct stimulus-type for fi-curve, general changes

This commit is contained in:
a.ott
2020-03-11 18:03:21 +01:00
parent 15166042be
commit 6012927416
14 changed files with 460 additions and 149 deletions

View File

@@ -5,7 +5,7 @@ import numpy as np
import functions as fu
from numba import jit
import helperFunctions as hF
from stimuli.SinusAmplitudeModulation import SinusAmplitudeModulationStimulus
from stimuli.SinusoidalStepStimulus import SinusoidalStepStimulus
from scipy.optimize import curve_fit
from warnings import warn
@@ -13,22 +13,22 @@ from warnings import warn
class LifacNoiseModel(AbstractModel):
# all times in milliseconds
# possible mem_res: 100 * 1000000 exact value unknown in p-units
DEFAULT_VALUES = {"mem_tau": 20,
DEFAULT_VALUES = {"mem_tau": 0.015,
"v_base": 0,
"v_zero": 0,
"threshold": 1,
"v_offset": 50,
"input_scaling": 1,
"delta_a": 0.4,
"tau_a": 0.04,
"a_zero": 0,
"noise_strength": 3,
"v_offset": -10,
"input_scaling": 60,
"delta_a": 0.08,
"tau_a": 0.1,
"a_zero": 10,
"noise_strength": 0.05,
"step_size": 0.00005}
def __init__(self, params: dict = None):
super().__init__(params)
if self.parameters["step_size"] >= 0.0001:
if self.parameters["step_size"] > 0.0001:
warn("LifacNoiseModel: The step size is quite big simulation could fail.")
self.voltage_trace = []
self.adaption_trace = []
@@ -60,7 +60,7 @@ class LifacNoiseModel(AbstractModel):
if v_next > self.parameters["threshold"]:
v_next = self.parameters["v_base"]
spiketimes.append(time_point)
a_next += self.parameters["delta_a"] / (self.parameters["tau_a"])
a_next += self.parameters["delta_a"] / self.parameters["tau_a"]
output_voltage[i] = v_next
adaption[i] = a_next
@@ -164,17 +164,22 @@ class LifacNoiseModel(AbstractModel):
:return: baseline_freq, vs, sc
"""
base_stimulus = SinusAmplitudeModulationStimulus(base_stimulus_freq, 0, 0)
base_stimulus = SinusoidalStepStimulus(base_stimulus_freq, 0)
_, spiketimes = self.simulate_fast(base_stimulus, 30)
time_x = 5
baseline_freq = hF.mean_freq_of_spiketimes_after_time_x(spiketimes, time_x)
relative_spiketimes = np.array([s % (1 / base_stimulus_freq) for s in spiketimes])
eod_durations = np.full((len(spiketimes)), 1 / base_stimulus_freq)
vector_strength = hF.__vector_strength__(relative_spiketimes, eod_durations)
serial_correlation = hF.calculate_serial_correlation(np.array(spiketimes), max_lag)
if baseline_freq < 1:
return baseline_freq, 0, [0]*max_lag
return baseline_freq, vector_strength, serial_correlation
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)
return baseline_freq, vector_strength, serial_correlation
def calculate_fi_markers(self, contrasts, base_freq, modulation_frequency):
"""
@@ -185,7 +190,7 @@ class LifacNoiseModel(AbstractModel):
f_infinities = []
for contrast in contrasts:
stimulus = SinusAmplitudeModulationStimulus(base_freq, contrast, modulation_frequency)
stimulus = SinusoidalStepStimulus(base_freq, contrast)
_, spiketimes = self.simulate_fast(stimulus, 1)
f_infinity = hF.mean_freq_of_spiketimes_after_time_x(spiketimes, 0.3)
@@ -197,7 +202,7 @@ class LifacNoiseModel(AbstractModel):
return f_infinities, f_infinities_slope
def find_v_offset(self, goal_baseline_frequency, base_stimulus, threshold=10):
def find_v_offset(self, goal_baseline_frequency, base_stimulus, threshold=10, border=50000):
test_model = self.get_model_copy()
simulation_length = 5
@@ -208,9 +213,14 @@ class LifacNoiseModel(AbstractModel):
current_freq = test_v_offset(test_model, current_v_offset, base_stimulus, simulation_length)
while current_freq < goal_baseline_frequency:
if current_v_offset >= border:
return border
current_v_offset += v_search_step_size
current_freq = test_v_offset(test_model, current_v_offset, base_stimulus, simulation_length)
if current_v_offset == 0:
return -1000
lower_bound = current_v_offset - v_search_step_size
upper_bound = current_v_offset
@@ -218,13 +228,15 @@ class LifacNoiseModel(AbstractModel):
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
frequency = test_v_offset(model, middle, base_stimulus, simulation_length)
if counter > 100:
print("meep")
# print('{:.1f}, {:.1f}, {:.1f}, {:.1f} vs {:.1f} '.format(lower_bound, middle, upper_bound, frequency, goal_frequency))
if abs(frequency - goal_frequency) < threshold:
return middle
@@ -255,7 +267,6 @@ def rectify_stimulus_array(stimulus_array: np.ndarray):
@jit(nopython=True)
def simulate_fast(rectified_stimulus_array, total_time_s, parameters: np.ndarray):
v_zero = parameters[0]
a_zero = parameters[1]
step_size = parameters[2]
@@ -273,7 +284,6 @@ def simulate_fast(rectified_stimulus_array, total_time_s, parameters: np.ndarray
length = len(time)
output_voltage = np.zeros(length)
adaption = np.zeros(length)
stimulus_values = rectified_stimulus_array
spiketimes = []
output_voltage[0] = v_zero
@@ -284,7 +294,7 @@ 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)
output_voltage[i] = output_voltage[i-1] + ((v_base - output_voltage[i-1] + v_offset + (stimulus_values[i]*input_scaling) - adaption[i-1] + noise) / mem_tau) * step_size
output_voltage[i] = output_voltage[i-1] + ((v_base - output_voltage[i-1] + v_offset + (rectified_stimulus_array[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: