Skip to content

Commit

Permalink
force_calibration: tighten test tolerances
Browse files Browse the repository at this point in the history
`Numpy` uses a small absolute tolerance as the default for checking closeness (probably to make checks against zero possible). See: https://numpy.org/doc/stable/reference/generated/numpy.isclose.html?highlight=isclose#numpy.isclose

However, this can be problematic when values being compared are very small (as big relative differences will still fall under the tolerance). The `isclose` in `math` actually uses the safer zero absolute tolerance as default:
https://docs.python.org/3/library/math.html#math.isclose

Interesting discussion here: numpy/numpy#10161
  • Loading branch information
JoepVanlier committed Jun 8, 2021
1 parent b180068 commit f02d34e
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 18 deletions.
2 changes: 1 addition & 1 deletion lumicks/pylake/force_calibration/tests/test_power_model.py
Expand Up @@ -69,7 +69,7 @@ def test_fit_analytic(
fit = fit_analytical_lorentzian(ps.in_range(1e1, 1e4))

assert np.allclose(fit.fc, corner_frequency)
assert np.allclose(fit.D, diffusion_constant)
assert np.allclose(fit.D, diffusion_constant, rtol=1e-5, atol=0)
assert np.allclose(fit.sigma_fc, sigma_fc)
assert np.allclose(fit.sigma_D, sigma_diffusion)

Expand Down
8 changes: 4 additions & 4 deletions lumicks/pylake/force_calibration/tests/test_power_spectrum.py
Expand Up @@ -28,7 +28,7 @@ def test_power_spectrum_attrs(frequency, num_data, sample_rate):
assert np.allclose(determined_frequency, frequency) # Is the frequency at the right position?

# Is all the power at this frequency? (Valid when dealing with multiples of the sample rate)
assert np.allclose(power_spectrum.power[np.argmax(power_spectrum.power)], np.sum(power_spectrum.power))
assert np.allclose(power_spectrum.power[np.argmax(power_spectrum.power)], np.sum(power_spectrum.power), atol=1e-16)
assert np.allclose(power_spectrum.total_duration, num_data / sample_rate)


Expand All @@ -50,7 +50,7 @@ def test_power_spectrum_blocking(frequency, num_data, sample_rate, num_blocks, f
downsampling_factor = len(power_spectrum.frequency) // num_blocks
blocked = power_spectrum.downsampled_by(downsampling_factor)
assert np.allclose(blocked.frequency, f_blocked)
assert np.allclose(blocked.power, p_blocked)
assert np.allclose(blocked.power, p_blocked, atol=1e-16)
assert np.allclose(blocked.num_samples(), len(f_blocked))
assert np.allclose(len(power_spectrum.power), num_data // 2 + 1)
assert np.allclose(blocked.num_points_per_block, np.floor(len(power_spectrum.power) / num_blocks))
Expand Down Expand Up @@ -83,7 +83,7 @@ def test_in_range(frequency, num_data, sample_rate, num_blocks, f_min, f_max):
# Note that this different from the slice behaviour you'd normally expect
mask = (power_spectrum.frequency > f_min) & (power_spectrum.frequency <= f_max)
assert np.allclose(power_subset.frequency, power_spectrum.frequency[mask])
assert np.allclose(power_subset.power, power_spectrum.power[mask])
assert np.allclose(power_subset.power, power_spectrum.power[mask], atol=1e-16)
assert np.allclose(power_spectrum.total_duration, power_subset.total_duration)
assert np.allclose(power_spectrum.sample_rate, power_subset.sample_rate)

Expand All @@ -100,7 +100,7 @@ def test_replace_spectrum():
replaced = power_spectrum.with_spectrum(np.arange(6))

assert np.allclose(power_spectrum.frequency, replaced.frequency)
assert np.allclose(replaced.power, np.arange(6))
assert np.allclose(replaced.power, np.arange(6), atol=1e-16)
assert np.allclose(replaced.num_points_per_block, 1)
assert np.allclose(replaced.sample_rate, power_spectrum.sample_rate)
assert np.allclose(replaced.total_duration, power_spectrum.total_duration)
Expand Up @@ -55,14 +55,14 @@ def test_calibration_result():
"corner_frequency,diffusion_constant,alpha,f_diode,num_samples,viscosity,bead_diameter,temperature,err_fc,err_d,"
"err_f_diode,err_alpha,",
[
[1000, 1e-9, 0.5, 10000, 30000, 1.002e-3, 4.0, 20.0, 29.77266, 0.00000, 1239.06183, 0.05650019],
[1500, 1.2e-9, 0.5, 10000, 50000, 1.002e-3, 4.0, 20.0, 47.21810, 0.00000, 1399.04982, 0.05896166],
[1500, 1.2e-9, 0.5, 5000, 10000, 1.002e-3, 4.0, 20.0, 84.85429, 0.00000, 827.43118, 0.03077534],
[1500, 1.2e-9, 0.5, 5000, 10000, 1.2e-3, 4.0, 20.0, 84.85429, 0.00000, 827.43118, 0.03077534],
[1500, 1.2e-9, 0.5, 5000, 10000, 1.002e-3, 8.0, 20.0, 84.85429, 0.00000, 827.43118, 0.03077534],
[1500, 1.2e-9, 0.5, 5000, 10000, 1.002e-3, 4.0, 34.0, 84.85429, 0.00000, 827.43118, 0.03077534],
[1000, 1e-9, 0.5, 10000, 30000, 1.002e-3, 4.0, 20.0, 29.77266, 0.00000, 1239.06183, 0.05650019],
[1000, 1e-9, 0.5, 10000, 30000, 1, 4.0, 20.0, 29.77266, 0.00000, 1239.06183, 0.05650019],
[1000, 1e-9, 0.5, 10000, 30000, 1.002e-3, 4.0, 20.0, 29.77266, 2.9846e-11, 1239.06183, 0.05650019],
[1500, 1.2e-9, 0.5, 10000, 50000, 1.002e-3, 4.0, 20.0, 47.21810, 4.5890e-11, 1399.04982, 0.05896166],
[1500, 1.2e-9, 0.5, 5000, 10000, 1.002e-3, 4.0, 20.0, 84.85429, 1.04547e-10, 827.43118, 0.03077534],
[1500, 1.2e-9, 0.5, 5000, 10000, 1.2e-3, 4.0, 20.0, 84.85429, 1.04547e-10, 827.43118, 0.03077534],
[1500, 1.2e-9, 0.5, 5000, 10000, 1.002e-3, 8.0, 20.0, 84.85429, 1.04547e-10, 827.43118, 0.03077534],
[1500, 1.2e-9, 0.5, 5000, 10000, 1.002e-3, 4.0, 34.0, 84.85429, 1.04547e-10, 827.43118, 0.03077534],
[1000, 1e-9, 0.5, 10000, 30000, 1.002e-3, 4.0, 20.0, 29.77266, 2.9846e-11, 1239.06183, 0.05650019],
[1000, 1e-9, 0.5, 10000, 30000, 1, 4.0, 20.0, 29.77266, 2.9846e-11, 1239.06183, 0.05650019],
],
)
def test_good_fit_integration_test(
Expand All @@ -86,7 +86,7 @@ def test_good_fit_integration_test(
ps_calibration = psc.fit_power_spectrum(power_spectrum=power_spectrum, model=model)

assert np.allclose(ps_calibration["fc (Hz)"], corner_frequency, rtol=1e-4)
assert np.allclose(ps_calibration["D (V^2/s)"], diffusion_constant, rtol=1e-5)
assert np.allclose(ps_calibration["D (V^2/s)"], diffusion_constant, rtol=1e-4, atol=0)
assert np.allclose(ps_calibration["alpha"], alpha, rtol=1e-4)
assert np.allclose(ps_calibration["f_diode (Hz)"], f_diode, rtol=1e-4)

Expand All @@ -102,7 +102,7 @@ def test_good_fit_integration_test(
assert np.allclose(ps_calibration["chi_squared_per_deg"], 0) # Noise free

assert np.allclose(ps_calibration["err_fc"], err_fc)
assert np.allclose(ps_calibration["err_D"], err_d)
assert np.allclose(ps_calibration["err_D"], err_d, rtol=1e-4, atol=0)
assert np.allclose(ps_calibration["err_f_diode"], err_f_diode)
assert np.allclose(ps_calibration["err_alpha"], err_alpha)

Expand Down Expand Up @@ -155,15 +155,15 @@ def reference_calibration_result():
def test_actual_spectrum(reference_calibration_result):
ps_calibration, model, reference_spectrum = reference_calibration_result

assert np.allclose(ps_calibration["D (V^2/s)"], 0.0018512665210876748, rtol=1e-4)
assert np.allclose(ps_calibration["D (V^2/s)"], 0.0018512665210876748, rtol=1e-4, atol=0)
assert np.allclose(ps_calibration["Rd (um/V)"], 7.253645956145265, rtol=1e-4)
assert np.allclose(ps_calibration["Rf (pN/V)"], 1243.9711315478219, rtol=1e-4)
assert np.allclose(ps_calibration["kappa (pN/nm)"], 0.17149598134079505, rtol=1e-4)
assert np.allclose(ps_calibration["alpha"], 0.5006103727942776, rtol=1e-4)
assert np.allclose(ps_calibration["backing (%)"], 66.4331056392512, rtol=1e-4)
assert np.allclose(ps_calibration["chi_squared_per_deg"], 1.063783302378645, rtol=1e-4)
assert np.allclose(ps_calibration["err_fc"], 32.23007993226726, rtol=1e-4)
assert np.allclose(ps_calibration["err_D"], 6.43082000774291e-05, rtol=1e-4)
assert np.allclose(ps_calibration["err_D"], 6.43082000774291e-05, rtol=1e-4, atol=0)
assert np.allclose(ps_calibration["err_alpha"], 0.013141463933316694, rtol=1e-4)
assert np.allclose(ps_calibration["err_f_diode"], 561.6377089699399, rtol=1e-4)

Expand All @@ -185,7 +185,6 @@ def test_attributes_ps_calibration(reference_calibration_result):

def test_repr(reference_calibration_result):
ps_calibration, model, reference_spectrum = reference_calibration_result
print(str(ps_calibration))
assert str(ps_calibration) == dedent("""\
Name Description Value
------------------- -------------------------------------------------------- -----------------------
Expand Down

0 comments on commit f02d34e

Please sign in to comment.