Skip to content
This repository has been archived by the owner on Oct 23, 2021. It is now read-only.

Commit

Permalink
Merge pull request #24 from s-weigand/refactor-tests-to-leverage-pote…
Browse files Browse the repository at this point in the history
…ntial-of-pytest

refactored tests to reduce code overhead
  • Loading branch information
joernweissenborn committed Jul 20, 2018
2 parents aca20cc + bbc2968 commit d9b4d8e
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 95 deletions.
22 changes: 22 additions & 0 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import math
import numpy as np


def assert_epsilon(wanted_value, given_value):
"""
Test helper function to assert, if not all values of wanted_value and given_value
are smaller than epsilon.
Epsilon is 3 orders of magnitude smaller than the minimum of the absolute
values of wanted_value.
Parameters
----------
wanted_value: np.array, float, int
Wanted value
given_value: np.array, float, int
Given Value
"""
min_want = np.min(np.abs(wanted_value))
epsilon = 10**(math.floor(math.log10(min_want)) - 3)
msg = 'Want: {} Have: {} with epsilon {}'.format(wanted_value, given_value, epsilon)
assert np.any(np.abs(wanted_value - given_value) < epsilon), msg
176 changes: 81 additions & 95 deletions tests/test_simple_kinetic_model.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import math
from unittest import TestCase
from lmfit_varpro import SeparableModel
from lmfit import Parameters
import numpy as np
import pytest

from lmfit_varpro import SeparableModel
from .test_helpers import assert_epsilon


class OneCompartmentDecay(SeparableModel):
Expand All @@ -13,12 +14,24 @@ def data(self, **kwargs):

def c_matrix(self, parameter, *args, **kwargs):
parameter = parameter.valuesdict()
kinpar = np.asarray([parameter["p0"]])
c = np.exp(np.outer(np.asarray(kwargs['times']), -kinpar))
kinpar = np.array([parameter["p0"]])
c = np.exp(np.outer(np.array(kwargs['times']), -kinpar))
return [c]

def e_matrix(self, parameter, **kwargs):
return np.asarray([[1.0]])
return np.array([[1.0]])

def get_test_param_dict(self):
rparams = [101e-4]
params = [100e-5]
wanted_e_matrix = [1.0]
result_is_e_matrix = True
test_param_dict = {"rparams": rparams,
"params": params,
"wanted_params": rparams,
"wanted_e_matrix": wanted_e_matrix,
"result_is_e_matrix": result_is_e_matrix}
return test_param_dict


class TwoComparmentDecay(SeparableModel):
Expand All @@ -28,34 +41,46 @@ def data(self, **kwargs):
return data

def c_matrix(self, parameter, *args, **kwargs):
kinpar = np.asarray([parameter["p0"], parameter["p1"]])
kinpar = np.array([parameter["p0"], parameter["p1"]])
c = np.exp(np.outer(kwargs['times'], -kinpar))
return [c]

def e_matrix(self, parameter, **kwargs):
return np.asarray([[1.0, 2.0]])
return np.array([[1.0, 2.0]])

def get_test_param_dict(self):
rparams = [101e-4, 202e-5]
params = [100e-5, 200e-6]
wanted_e_matrix = [1.0, 2.0]
result_is_e_matrix = True
test_param_dict = {"rparams": rparams,
"params": params,
"wanted_params": rparams,
"wanted_e_matrix": wanted_e_matrix,
"result_is_e_matrix": result_is_e_matrix}
return test_param_dict


class MultiChannelMultiCompartmentDecay(SeparableModel):

wavenum = np.asarray(np.arange(12820, 15120, 4.6))
wavenum = np.arange(12820, 15120, 4.6)

def data(self, **kwargs):
data = [kwargs['data'][i, :] for i in
range(self.wavenum.shape[0])]
return data

def c_matrix(self, parameter, *args, **kwargs):
kinpar = np.asarray([parameter["p{}".format(i)] for i in
range(len((parameter)))])
kinpar = np.array([parameter["p{}".format(i)] for i in
range(len((parameter)))])
c = np.exp(np.outer(kwargs['times'], -kinpar))
return [c for _ in range(self.wavenum.shape[0])]

def e_matrix(self, parameter, **kwargs):
location = np.asarray(
location = np.array(
[14705, 13513, 14492, 14388, 14184, 13986])
delta = np.asarray([400, 1000, 300, 200, 350, 330])
amp = np.asarray([1, 0.1, 10, 100, 1000, 10000])
delta = np.array([400, 1000, 300, 200, 350, 330])
amp = np.array([1, 0.1, 10, 100, 1000, 10000])

E = np.empty((self.wavenum.shape[0], location.shape[0]),
dtype=np.float64,
Expand All @@ -69,97 +94,58 @@ def e_matrix(self, parameter, **kwargs):
)
return E

def get_test_param_dict(self):
rparams = [.006667, .006667, 0.00333, 0.00035, 0.0303, 0.000909]
params = [.005, 0.003, 0.00022, 0.0300, 0.000888]
wanted_params = [.006667, 0.00333, 0.00035, 0.0303, 0.000909]
result_is_e_matrix = False
test_param_dict = {"rparams": rparams,
"params": params,
"wanted_params": wanted_params,
"result_is_e_matrix": result_is_e_matrix}
return test_param_dict

class TestSimpleKinetic(TestCase):

def assertEpsilon(self, number, value):
epsilon = 10**(math.floor(math.log10(abs(number))) - 3)
self.assertTrue(abs(number - value) < epsilon,
msg='Want: {} Have: {} with epsilon {}'
''.format(number, value, epsilon))

def test_one_compartment_decay(self):

model = OneCompartmentDecay()
times = np.asarray(np.arange(0, 1000, 1.5))

params = [101e-4]

real_params = Parameters()
for i in range(len(params)):
real_params.add("p{}".format(i), params[i])
data = model.eval(real_params, **{"times": times})

initial_parameter = Parameters()
initial_parameter.add("p0", 100e-5)

result = model.fit(initial_parameter, False, [], **{"times": times,
"data": data})
for i in range(len(params)):
self.assertEpsilon(params[i],
result.best_fit_parameter["p{}".format(i)].value)
amps = result.e_matrix(data, **{"times": times, "data": data})
print(amps)
self.assertEpsilon(amps[0], 1.0)

def test_two_compartment_decay(self):

model = TwoComparmentDecay()
times = np.asarray(np.arange(0, 1500, 1.5))

params = [101e-4, 202e-5]

real_params = Parameters()
for i in range(len(params)):
real_params.add("p{}".format(i), params[i])

data = model.eval(real_params, **{"times": times})

initial_parameter = Parameters()
initial_parameter.add("p0", 100e-5)
initial_parameter.add("p1", 200e-6)
@pytest.mark.parametrize("compartment_decay_model",
[
TwoComparmentDecay,
OneCompartmentDecay,
MultiChannelMultiCompartmentDecay
])
def test_compartment_decay(compartment_decay_model):

result = model.fit(initial_parameter, False, [], **{"times": times,
"data": data})
for i in range(len(params)):
self.assertEpsilon(params[i],
result.best_fit_parameter["p{}".format(i)]
.value)
amps = result.e_matrix(data, **{"times": times, "data": data})[0]
print(amps)
want = [1.0, 2.0]
for i in range(len(want)):
self.assertEpsilon(amps[i], want[i])
model = compartment_decay_model()
times = np.arange(0, 1500, 1.5)

def test_multi_compartment_multi_channel_decay(self):
test_param_dict = model.get_test_param_dict()

model = MultiChannelMultiCompartmentDecay()
times = np.asarray(np.arange(0, 1500, 1.5))
rparams = test_param_dict["rparams"]

rparams = [.006667, .006667, 0.00333, 0.00035, 0.0303, 0.000909]
real_params = Parameters()
for index, rparam in enumerate(rparams):
real_params.add("p{}".format(index), rparam)

real_params = Parameters()
for i in range(len(rparams)):
real_params.add("p{}".format(i), rparams[i])
data = model.eval(real_params, times=times)

data = model.eval(real_params, **{"times": times})
params = test_param_dict["params"]

params = [.005, 0.003, 0.00022, 0.0300, 0.000888]
initial_parameter = Parameters()
for i in range(len(params)):
initial_parameter.add("p{}".format(i), params[i])
initial_parameter = Parameters()
for index, param in enumerate(params):
initial_parameter.add("p{}".format(index), param)

result = model.fit(initial_parameter, False, [], **{"times": times,
"data": data})
result = model.fit(initial_parameter, False, [], times=times, data=data)

wanted_params = [.006667, 0.00333, 0.00035, 0.0303, 0.000909]
for i in range(len(wanted_params)):
self.assertEpsilon(wanted_params[i],
result.best_fit_parameter["p{}".format(i)]
.value)
wanted_params = test_param_dict["wanted_params"]

fitted = result.eval(**{"times": times, "data": data})
for index, wanted_param in enumerate(wanted_params):
fit_value = result.best_fit_parameter["p{}".format(index)].value
assert_epsilon(wanted_param, fit_value)

for i in range(fitted.shape[0]):
for j in range(fitted.shape[1]):
self.assertEpsilon(data[i, j], fitted[i, j])
if test_param_dict["result_is_e_matrix"]:
wanted_e_matrix = test_param_dict["wanted_e_matrix"]
amplitudes = result.e_matrix(data, times=times, data=data)[0]
for amplitude, want in zip(amplitudes, wanted_e_matrix):
assert_epsilon(amplitude, want)
else:
fitted = result.eval(times=times, data=data)
assert_epsilon(data, fitted)

0 comments on commit d9b4d8e

Please sign in to comment.