debug and add unittests 1
This commit is contained in:
130
unittests/testHelperFunctions.py
Normal file
130
unittests/testHelperFunctions.py
Normal file
@@ -0,0 +1,130 @@
|
||||
import unittest
|
||||
import numpy as np
|
||||
import helperFunctions as hF
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
class HelperFunctionsTester(unittest.TestCase):
|
||||
|
||||
noise_levels = [0, 0.05, 0.1, 0.2]
|
||||
frequencies = [0, 1, 5, 30, 100, 500, 750, 1000]
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_calculate_eod_frequency(self):
|
||||
start = 0
|
||||
end = 5
|
||||
step = 0.1 / 1000
|
||||
freqs = [0, 1, 10, 500, 700, 1000]
|
||||
for freq in freqs:
|
||||
time = np.arange(start, end, step)
|
||||
eod = np.sin(freq*(2*np.pi) * time)
|
||||
self.assertEqual(freq, round(hF.calculate_eod_frequency(time, eod), 2))
|
||||
|
||||
def test__vector_strength__is_1(self):
|
||||
length = 2000
|
||||
rel_spike_times = np.full(length, 0.3)
|
||||
eod_durations = np.full(length, 0.14)
|
||||
|
||||
self.assertEqual(1, round(hF.__vector_strength__(rel_spike_times,eod_durations), 2))
|
||||
|
||||
def test__vector_strength__is_0(self):
|
||||
length = 2000
|
||||
period = 0.14
|
||||
rel_spike_times = np.arange(0, period, period/length)
|
||||
eod_durations = np.full(length, period)
|
||||
|
||||
self.assertEqual(0, round(hF.__vector_strength__(rel_spike_times, eod_durations), 5))
|
||||
|
||||
def test_mean_freq_of_spiketimes_after_time_x(self):
|
||||
simulation_time = 8
|
||||
for freq in self.frequencies:
|
||||
for n in self.noise_levels:
|
||||
spikes = generate_jittered_spiketimes(freq, n, end=simulation_time)
|
||||
sim_freq = hF.mean_freq_of_spiketimes_after_time_x(spikes, 0.00005, simulation_time/4, time_in_ms=False)
|
||||
|
||||
max_diff = round(n*(10+0.7*np.sqrt(freq)), 2)
|
||||
# print("noise: {:.2f}".format(n), "\texpected: {:.2f}".format(freq), "\tgotten: {:.2f}".format(round(sim_freq, 2)), "\tfreq diff: {:.2f}".format(abs(freq-round(sim_freq, 2))), "\tmax_diff:", max_diff)
|
||||
self.assertTrue(abs(freq-round(sim_freq)) <= max_diff, msg="expected freq: {:.2f} vs calculated: {:.2f}. max diff was {:.2f}".format(freq, sim_freq, max_diff))
|
||||
|
||||
def test_calculate_isi_frequency(self):
|
||||
simulation_time = 1
|
||||
sampling_interval = 0.00005
|
||||
|
||||
for freq in self.frequencies:
|
||||
for n in self.noise_levels:
|
||||
spikes = generate_jittered_spiketimes(freq, n, end=simulation_time)
|
||||
sim_freq = hF.calculate_isi_frequency(spikes, sampling_interval, time_in_ms=False)
|
||||
|
||||
isis = np.diff(spikes)
|
||||
step_length = isis / sampling_interval
|
||||
rounded_step_length = np.around(step_length)
|
||||
expected_length = sum(rounded_step_length)
|
||||
|
||||
length = len(sim_freq)
|
||||
self.assertEqual(expected_length, length)
|
||||
|
||||
|
||||
|
||||
# def test(self):
|
||||
# test_distribution()
|
||||
|
||||
def generate_jittered_spiketimes(frequency, noise_level, start=0, end=5):
|
||||
if frequency == 0:
|
||||
return []
|
||||
|
||||
mean_isi = 1 / frequency
|
||||
if noise_level == 0:
|
||||
return np.arange(start, end, mean_isi)
|
||||
|
||||
spikes = [start]
|
||||
count = 0
|
||||
while True:
|
||||
next_isi = np.random.normal(mean_isi, noise_level*mean_isi)
|
||||
if next_isi <= 0:
|
||||
count += 1
|
||||
continue
|
||||
next_spike = spikes[-1] + next_isi
|
||||
if next_spike > end:
|
||||
break
|
||||
spikes.append(spikes[-1] + next_isi)
|
||||
|
||||
# print("count: {:} percentage of missed: {:.2f}".format(count, count/len(spikes)))
|
||||
if count > 0.01*len(spikes):
|
||||
print("!!! Danger of lowering actual simulated frequency")
|
||||
pass
|
||||
return spikes
|
||||
|
||||
|
||||
def test_distribution():
|
||||
simulation_time = 5
|
||||
freqs = [5, 30, 100, 500, 1000]
|
||||
noise_level = [0.05, 0.1, 0.2, 0.3]
|
||||
repetitions = 1000
|
||||
for freq in freqs:
|
||||
diffs_per_noise = []
|
||||
for n in noise_level:
|
||||
diffs = []
|
||||
print("#### - freq:", freq, "noise level:", n )
|
||||
for reps in range(repetitions):
|
||||
spikes = generate_jittered_spiketimes(freq, n, end=simulation_time)
|
||||
sim_freq = hF.mean_freq_of_spiketimes_after_time_x(spikes, 0.0002, simulation_time / 4, time_in_ms=False)
|
||||
diffs.append(sim_freq-freq)
|
||||
|
||||
diffs_per_noise.append(diffs)
|
||||
|
||||
fig, axs = plt.subplots(1, len(noise_level), figsize=(3.5*len(noise_level), 4), sharex='all')
|
||||
|
||||
for i in range(len(diffs_per_noise)):
|
||||
max_diff = np.max(np.abs(diffs_per_noise[i]))
|
||||
print("Freq: ", freq, "noise: {:.2f}".format(noise_level[i]), "mean: {:.2f}".format(np.mean(diffs_per_noise[i])), "max_diff: {:.4f}".format(max_diff))
|
||||
bins = np.arange(-max_diff, max_diff, 2*max_diff/100)
|
||||
axs[i].hist(diffs_per_noise[i], bins=bins)
|
||||
axs[i].set_title('Noise level: {:.2f}'.format(noise_level[i]))
|
||||
|
||||
plt.show()
|
||||
plt.close()
|
||||
70
unittests/testLifacNoise.py
Normal file
70
unittests/testLifacNoise.py
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
import unittest
|
||||
import numpy as np
|
||||
import helperFunctions as hF
|
||||
import matplotlib.pyplot as plt
|
||||
from models.LIFACnoise import LifacNoiseModel
|
||||
from stimuli.SinusAmplitudeModulation import SinusAmplitudeModulationStimulus
|
||||
|
||||
|
||||
class HelperFunctionsTester(unittest.TestCase):
|
||||
|
||||
# TODO specify exact parameters for all test (multiple sets?)
|
||||
def setUp(self) -> None:
|
||||
self.model = LifacNoiseModel()
|
||||
self.model.set_variable("noise_strength", 0)
|
||||
|
||||
self.step_sinus = SinusAmplitudeModulationStimulus(700, 0.5, 10, start_time=0.5, duration=0.5)
|
||||
self.base_sinus = SinusAmplitudeModulationStimulus(700, 0, 0)
|
||||
self.none_stimulus = SinusAmplitudeModulationStimulus(700, 0, 0, amplitude=0)
|
||||
self.simulation_time = 1.5
|
||||
self.voltage_precision = 0.000001
|
||||
|
||||
def test_simulate_fast_step_sinus(self):
|
||||
v1, spikes = self.model.simulate(self.step_sinus, self.simulation_time)
|
||||
v_fast, spikes_fast = self.model.simulate_fast(self.step_sinus, self.simulation_time)
|
||||
test = [abs(v1[i] - v_fast[i]) > self.voltage_precision for i in range(len(v1))]
|
||||
|
||||
self.assertTrue(sum(test) == 0, msg="The voltage traces between the fast and slow simulation aren't equal diff: {:}".format(sum(test)))
|
||||
self.assertTrue(np.array_equal(spikes, spikes_fast), msg="The spike times between the fast and slow simulation aren't equal")
|
||||
|
||||
def test_simulate_fast_base_sinus(self):
|
||||
v1, spikes = self.model.simulate(self.base_sinus, self.simulation_time)
|
||||
v_fast, spikes_fast = self.model.simulate_fast(self.base_sinus, self.simulation_time)
|
||||
|
||||
test = [abs(v1[i] - v_fast[i]) > self.voltage_precision for i in range(len(v1))]
|
||||
|
||||
self.assertTrue(sum(test) == 0, msg="The voltage traces between the fast and slow simulation aren't equal diff: {:}".format(sum(test)))
|
||||
self.assertTrue(np.array_equal(spikes, spikes_fast), msg="The spike times between the fast and slow simulation aren't equal")
|
||||
|
||||
def test_simulate_fast_no_stimulus(self):
|
||||
v1, spikes = self.model.simulate(self.none_stimulus, self.simulation_time)
|
||||
v_fast, spikes_fast = self.model.simulate_fast(self.none_stimulus, self.simulation_time)
|
||||
|
||||
test = [abs(v1[i] - v_fast[i]) > self.voltage_precision for i in range(len(v1))]
|
||||
|
||||
self.assertTrue(sum(test) == 0, msg="The voltage traces between the fast and slow simulation aren't equal diff: {:}".format(sum(test)))
|
||||
self.assertTrue(np.array_equal(spikes, spikes_fast), msg="The spike times between the fast and slow simulation aren't equal")
|
||||
|
||||
def test_find_v_offset(self):
|
||||
v_offsets = [50, 100, 150, 250, 1000]
|
||||
threshold = 0.01
|
||||
test_model = self.model.get_model_copy()
|
||||
stimulus = SinusAmplitudeModulationStimulus(700, 0, 0, amplitude=0) # no stimulus
|
||||
for offset in v_offsets:
|
||||
test_model.set_variable("v_offset", offset)
|
||||
|
||||
_, spikes = test_model.simulate_fast(stimulus, 5)
|
||||
goal_freq = hF.mean_freq_of_spiketimes_after_time_x(spikes, 0.0005, 1)
|
||||
|
||||
if goal_freq <= threshold:
|
||||
print("test Offset ({:.1f}) generates a too low frequency: {:.2f}".format(offset, goal_freq))
|
||||
continue
|
||||
|
||||
measured_offset = self.model.find_v_offset(goal_freq, stimulus, threshold)
|
||||
# print(offset, measured_offset)
|
||||
self.assertTrue(abs(offset - measured_offset) < 1)
|
||||
|
||||
def test_fin_v_offset_threshold_limit(self):
|
||||
for threshold in [0, -0.0001, -2, -500]:
|
||||
self.assertRaises(ValueError, self.model.find_v_offset, 700, self.base_sinus, threshold)
|
||||
Reference in New Issue
Block a user