|
| 1 | +import numpy as np |
| 2 | +import pytest |
| 3 | + |
| 4 | + |
| 5 | +def old_helper_retract_fraction(tip_position, force, fraction_force): |
| 6 | + fraction = int(0.8 * len(force)) |
| 7 | + max_force = np.max(force[:fraction]) |
| 8 | + max_position = -1 * tip_position[0] |
| 9 | + fit_stop = int(np.argwhere(force < (max_force * fraction_force))[0]) |
| 10 | + position_seg = tip_position[:fit_stop].copy() |
| 11 | + force_seg = force[:fit_stop].copy() |
| 12 | + return position_seg, force_seg, max_position, max_force |
| 13 | + |
| 14 | + |
| 15 | +def new_helper_retract_fraction(tip_position, force, fraction_force): |
| 16 | + """Reference implementation using NumPy 1.x and 2.x compatible indexing.""" |
| 17 | + fraction = int(0.8 * len(force)) |
| 18 | + max_force = np.max(force[:fraction]) |
| 19 | + max_position = -1 * tip_position[0] |
| 20 | + |
| 21 | + # new part |
| 22 | + _mask = force < (max_force * fraction_force) |
| 23 | + if not np.any(_mask): |
| 24 | + raise ValueError("No force values below threshold") |
| 25 | + fit_stop = int(np.argmax(_mask)) |
| 26 | + |
| 27 | + position_seg = tip_position[:fit_stop].copy() |
| 28 | + force_seg = force[:fit_stop].copy() |
| 29 | + return position_seg, force_seg, max_position, max_force |
| 30 | + |
| 31 | + |
| 32 | +def test_helper_behavior_differs_between_numpy_1_and_2(): |
| 33 | + """Show that newest version works for both numpy 1 and 2""" |
| 34 | + tip_position = np.linspace(0.0, -9.0, 10) |
| 35 | + force = np.array([10.0, 9.0, 8.0, 6.0, 4.0, 3.0, 2.0, 1.0, 0.0, 0.0]) |
| 36 | + fraction_force = 0.5 # threshold = 5.0 -> first below threshold at index 4 |
| 37 | + |
| 38 | + major = int(np.__version__.split(".", 1)[0]) |
| 39 | + if major < 2: |
| 40 | + # both old and new KVM work for numpy version 1 |
| 41 | + old = old_helper_retract_fraction(tip_position, force, fraction_force) |
| 42 | + new = new_helper_retract_fraction(tip_position, force, fraction_force) |
| 43 | + np.testing.assert_allclose(old[0], new[0]) |
| 44 | + np.testing.assert_allclose(old[1], new[1]) |
| 45 | + assert old[2] == new[2] |
| 46 | + assert old[3] == new[3] |
| 47 | + else: |
| 48 | + # old implementation creates errors on NumPy 2 |
| 49 | + # ("only length-1 arrays..." / "only 0-d arrays..."). |
| 50 | + with pytest.raises(TypeError): |
| 51 | + old_helper_retract_fraction(tip_position, force, fraction_force) |
| 52 | + # therefore we need the new implementation, which works |
| 53 | + # with numpy version 2 |
| 54 | + new_helper_retract_fraction(tip_position, force, fraction_force) |
0 commit comments