Skip to content

Commit

Permalink
Fix bugs in adaptivity computation (#80)
Browse files Browse the repository at this point in the history
* Fix bugs in global adaptivity

* Fix formatting and also a bug in the local adaptivity

* Set coarse tolerance to sys.float_info.min if all the similarity distances are zero
  • Loading branch information
IshaanDesai authored Feb 8, 2024
1 parent 02af54a commit 60755e6
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 3 deletions.
9 changes: 8 additions & 1 deletion micro_manager/adaptivity/adaptivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import numpy as np
from math import exp
from typing import Callable
from warnings import warn


class AdaptivityCalculator:
Expand Down Expand Up @@ -84,7 +85,13 @@ def _update_active_sims(
_is_sim_active : numpy array
Updated 1D array having state (active or inactive) of each micro simulation
"""
self._coarse_tol = self._coarse_const * self._refine_const * np.amax(similarity_dists)
max_similarity_dist = np.amax(similarity_dists)

if max_similarity_dist == 0.0:
warn("All similarity distances are zero, probably because all the data for adaptivity is the same. Coarsening tolerance will be manually set to minimum float number.")
self._coarse_tol = sys.float_info.min
else:
self._coarse_tol = self._coarse_const * self._refine_const * max_similarity_dist

_is_sim_active = np.copy(is_sim_active) # Input is_sim_active is not longer used after this point

Expand Down
6 changes: 5 additions & 1 deletion micro_manager/adaptivity/global_adaptivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,15 @@ def compute_adaptivity(
is_sim_active = self._update_active_sims(similarity_dists, is_sim_active_nm1)

is_sim_active, sim_is_associated_to = self._update_inactive_sims(
similarity_dists, is_sim_active_nm1, sim_is_associated_to_nm1, micro_sims)
similarity_dists, is_sim_active, sim_is_associated_to_nm1, micro_sims)

print("sim_is_associated_to: {}".format(sim_is_associated_to))

sim_is_associated_to = self._associate_inactive_to_active(
similarity_dists, is_sim_active, sim_is_associated_to)

print("sim_is_associated_to: {}".format(sim_is_associated_to))

self._logger.info(
"{} active simulations, {} inactive simulations".format(
np.count_nonzero(
Expand Down
2 changes: 1 addition & 1 deletion micro_manager/adaptivity/local_adaptivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def compute_adaptivity(
is_sim_active = self._update_active_sims(similarity_dists, is_sim_active_nm1)

is_sim_active, sim_is_associated_to = self._update_inactive_sims(
similarity_dists, is_sim_active_nm1, sim_is_associated_to_nm1, micro_sims)
similarity_dists, is_sim_active, sim_is_associated_to_nm1, micro_sims)

sim_is_associated_to = self._associate_inactive_to_active(
similarity_dists, is_sim_active, sim_is_associated_to)
Expand Down
57 changes: 57 additions & 0 deletions tests/unit/test_adaptivity_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,63 @@ def get_state(self):
elif self._rank == 1:
self.assertTrue(np.array_equal([2, 2, 2], dummy_micro_sims[1].get_state()))

def test_update_all_active_sims_global_adaptivity(self):
"""
Test functionality to calculate adaptivity when all simulations are active, for a global adaptivity setting.
Run this test in parallel using MPI with 2 ranks.
"""
if self._rank == 0:
global_ids = [0, 1, 2]
data_for_adaptivity = {"data1": [1.0, 1.0, 1.0], "data2": [13.0, 13.0, 13.0]}
elif self._rank == 1:
global_ids = [3, 4]
data_for_adaptivity = {"data1": [1.0, 1.0], "data2": [13.0, 13.0]}

similarity_dists = np.zeros((5, 5))
is_sim_active = np.array([True, True, True, True, True])
sim_is_associated_to = [-2, -2, -2, -2, -2]
expected_is_sim_active = np.array([False, False, False, False, True])
expected_sim_is_associated_to = [4, 4, 4, 4, -2]

configurator = MagicMock()
configurator.get_adaptivity_hist_param = MagicMock(return_value=0.1)
configurator.get_adaptivity_refining_const = MagicMock(return_value=0.05)
configurator.get_adaptivity_coarsening_const = MagicMock(return_value=0.2)
configurator.get_adaptivity_similarity_measure = MagicMock(return_value="L2rel")
adaptivity_controller = GlobalAdaptivityCalculator(
configurator,
MagicMock(),
5,
global_ids,
rank=self._rank,
comm=self._comm)

adaptivity_controller._adaptivity_data_names = {"data1": "scalar", "data2": "scalar"}

class MicroSimulation():
def __init__(self, global_id) -> None:
self._global_id = global_id
self._state = [global_id] * 3

def get_global_id(self):
return self._global_id

def set_state(self, state):
self._state = state

def get_state(self):
return self._state.copy()

dummy_micro_sims = []
for i in global_ids:
dummy_micro_sims.append(MicroSimulation(i))

_, is_sim_active, sim_is_associated_to = adaptivity_controller.compute_adaptivity(
0.1, dummy_micro_sims, similarity_dists, is_sim_active, sim_is_associated_to, data_for_adaptivity)

self.assertTrue(np.array_equal(expected_is_sim_active, is_sim_active))
self.assertTrue(np.array_equal(expected_sim_is_associated_to, sim_is_associated_to))

def test_communicate_micro_output(self):
"""
Test functionality to communicate micro output from active sims to their associated inactive sims, for a global adaptivity setting.
Expand Down

0 comments on commit 60755e6

Please sign in to comment.