Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle crashing micro simulations #85

Merged
merged 23 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e32a825
Add first draft of simulation crash handling
Mar 12, 2024
d459714
Extend handling of crashing simulations to adaptivity and corner cases
Mar 19, 2024
493aa99
Adapt format in crash handling to pep8
Mar 20, 2024
4916f13
Add tests for simulation crashes
Mar 21, 2024
e0b3409
Adapt formatting of tests
Mar 21, 2024
57cea77
Update logger message for crashing simulation in the first run
tjwsch Mar 28, 2024
4ac4248
Restructure simulation crash handling and add global condition for exit
tjwsch Mar 28, 2024
10de7ab
Add first draft of simulation crash handling
Mar 12, 2024
29c824e
Extend handling of crashing simulations to adaptivity and corner cases
Mar 19, 2024
389fb62
Adapt format in crash handling to pep8
Mar 20, 2024
6178c7f
Add tests for simulation crashes
Mar 21, 2024
dc6b771
Adapt formatting of tests
Mar 21, 2024
5d07316
Add interpolation to crash handling
tjwsch Apr 9, 2024
564edf4
Add Inverse Distance Weighting and improve crash handling
tjwsch Apr 11, 2024
96384cd
Format with pre-commit
tjwsch Apr 11, 2024
c5b3a6c
Apply suggestions from code review
tjwsch Apr 22, 2024
1dc33ce
Incoporate review into crash handling
tjwsch Apr 23, 2024
b1464e5
Base crash interpolation on macro parameter
tjwsch Apr 26, 2024
597590e
Format simulation crash handling
tjwsch Apr 29, 2024
bd48ce4
Adapt error for no available neighbor
tjwsch Apr 29, 2024
57ec072
Apply text improvement suggestions from code review
tjwsch May 3, 2024
832fb3e
Apply suggestions from crash handling review
tjwsch May 3, 2024
c580117
Adapt interpolation test
tjwsch May 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/run-unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ jobs:
pip3 install --user .
pip3 uninstall -y pyprecice

- name: Run unit tests
- name: Run micro_manager unit test
working-directory: micro-manager/tests/unit
run: python3 -m unittest test_micro_manager.py

- name: Run interpolation unit test
working-directory: micro-manager/tests/unit
run: python3 -m unittest test_interpolation.py

- name: Run micro simulation crash unit test
working-directory: micro-manager/tests/unit
run: python3 -m unittest test_micro_simulation_crash_handling.py
83 changes: 83 additions & 0 deletions micro_manager/interpolation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import numpy as np
from sklearn.neighbors import NearestNeighbors


class Interpolation:
def __init__(self, logger):

self._logger = logger

def get_nearest_neighbor_indices(
self,
coords: np.ndarray,
inter_point: np.ndarray,
k: int,
) -> np.ndarray:
"""
Get local indices of the k nearest neighbors of a point.

Parameters
----------
coords : list
List of coordinates of all points.
inter_point : list | np.ndarray
Coordinates of the point for which the neighbors are to be found.
k : int
Number of neighbors to consider.

Returns
------
neighbor_indices : np.ndarray
Local indices of the k nearest neighbors in all local points.
"""
if len(coords) < k:
self._logger.info(
"Number of desired neighbors k = {} is larger than the number of available neighbors {}. Resetting k = {}.".format(
k, len(coords), len(coords)
)
)
k = len(coords)
neighbors = NearestNeighbors(n_neighbors=k).fit(coords)

neighbor_indices = neighbors.kneighbors(
[inter_point], return_distance=False
).flatten()

return neighbor_indices

def interpolate(self, neighbors: np.ndarray, point: np.ndarray, values):
"""
Interpolate a value at a point using inverse distance weighting. (https://en.wikipedia.org/wiki/Inverse_distance_weighting)
.. math::
f(x) = (\sum_{i=1}^{n} \frac{f_i}{\Vert x_i - x \Vert^2}) / (\sum_{j=1}^{n} \frac{1}{\Vert x_j - x \Vert^2})

Parameters
----------
neighbors : np.ndarray
Coordinates at which the values are known.
point : np.ndarray
Coordinates at which the value is to be interpolated.
values :
Values at the known coordinates.

Returns
-------
interpol_val / summed_weights :
Value at interpolation point.
"""
interpol_val = 0
summed_weights = 0
# Iterate over all neighbors
for inx in range(len(neighbors)):
# Compute the squared norm of the difference between interpolation point and neighbor
norm = np.linalg.norm(np.array(neighbors[inx]) - np.array(point)) ** 2
# If interpolation point is already part of the data it is returned as the interpolation result
# This avoids division by zero
if norm < 1e-16:
return values[inx]
# Update interpolation value
interpol_val += values[inx] / norm
# Extend normalization factor
summed_weights += 1 / norm

return interpol_val / summed_weights
Loading