From a4baea04ef4f8ee80f25610aa741c48f789082f4 Mon Sep 17 00:00:00 2001 From: Ishaan Desai Date: Fri, 13 Dec 2024 14:22:17 +0100 Subject: [PATCH] Add common function to both adaptivity variants for general micro output field --- micro_manager/adaptivity/global_adaptivity.py | 82 +++++++++++++------ micro_manager/adaptivity/local_adaptivity.py | 32 ++++++++ micro_manager/micro_manager.py | 23 ++---- 3 files changed, 97 insertions(+), 40 deletions(-) diff --git a/micro_manager/adaptivity/global_adaptivity.py b/micro_manager/adaptivity/global_adaptivity.py index d12b2ba..97f1f70 100644 --- a/micro_manager/adaptivity/global_adaptivity.py +++ b/micro_manager/adaptivity/global_adaptivity.py @@ -83,14 +83,20 @@ def compute_adaptivity( micro_sims : list List of objects of class MicroProblem, which are the micro simulations adaptivity_data_nm1 : list - List of numpy arrays: similarity_dists (2D array having similarity distances between each micro simulation pair), is_sim_active (1D array having state (active or inactive) of each micro simulation), sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None) + List of numpy arrays: + similarity_dists (2D array having similarity distances between each micro simulation pair) + is_sim_active (1D array having state (active or inactive) of each micro simulation) + sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None) data_for_adaptivity : dict Dictionary with keys as names of data to be used in the similarity calculation, and values as the respective data for the micro simulations Results ------- list - List of numpy arrays: similarity_dists (2D array having similarity distances between each micro simulation pair), is_sim_active (1D array having state (active or inactive) of each micro simulation), sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None) + List of numpy arrays: + similarity_dists (2D array having similarity distances between each micro simulation pair) + is_sim_active (1D array having state (active or inactive) of each micro simulation) + sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None) """ for name in data_for_adaptivity.keys(): if name not in self._adaptivity_data_names: @@ -142,7 +148,55 @@ def compute_adaptivity( return [similarity_dists, is_sim_active, sim_is_associated_to] - def communicate_micro_output( + def get_active_sim_ids(self) -> np.ndarray: + """ + Get the ids of active simulations. + + Returns + ------- + numpy array + 1D array of active simulation ids + """ + return self._active_sim_ids + + def get_inactive_sim_ids(self) -> np.ndarray: + """ + Get the ids of inactive simulations. + + Returns + ------- + numpy array + 1D array of inactive simulation ids + """ + return self._inactive_sim_ids + + def get_full_field_micro_output( + self, adaptivity_data: list, micro_output: list + ) -> list: + """ + Get the full field micro output from active simulations to inactive simulations. + + Parameters + ---------- + adaptivity_data : list + List of numpy arrays: + similarity_dists (2D array having similarity distances between each micro simulation pair) + is_sim_active (1D array having state (active or inactive) of each micro simulation) + sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None) + micro_output : list + List of dicts having individual output of each simulation. Only the active simulation outputs are entered. + + Returns + ------- + micro_output : list + List of dicts having individual output of each simulation. Active and inactive simulation outputs are entered. + """ + micro_sims_output = deepcopy(micro_output) + self._communicate_micro_output(adaptivity_data[1:3], micro_sims_output) + + return micro_sims_output + + def _communicate_micro_output( self, adaptivity_data: list, micro_output: list, @@ -201,28 +255,6 @@ def communicate_micro_output( for local_id in active_to_inactive_map[assoc_active_ids[count]]: micro_output[local_id] = deepcopy(output) - def get_active_sim_ids(self) -> np.ndarray: - """ - Get the ids of active simulations. - - Returns - ------- - numpy array - 1D array of active simulation ids - """ - return self._active_sim_ids - - def get_inactive_sim_ids(self) -> np.ndarray: - """ - Get the ids of inactive simulations. - - Returns - ------- - numpy array - 1D array of inactive simulation ids - """ - return self._inactive_sim_ids - def _update_inactive_sims( self, similarity_dists: np.ndarray, diff --git a/micro_manager/adaptivity/local_adaptivity.py b/micro_manager/adaptivity/local_adaptivity.py index 2aa7f24..2c8292f 100644 --- a/micro_manager/adaptivity/local_adaptivity.py +++ b/micro_manager/adaptivity/local_adaptivity.py @@ -4,6 +4,7 @@ each other. A global comparison is not done. """ import numpy as np +from copy import deepcopy from .adaptivity import AdaptivityCalculator @@ -108,6 +109,37 @@ def get_inactive_sim_ids(self) -> np.ndarray: """ return self._inactive_sim_ids + def get_full_field_micro_output( + self, adaptivity_data: list, micro_output: list + ) -> list: + """ + Get the full field micro output from active simulations to inactive simulations. + + Parameters + ---------- + adaptivity_data : list + List of numpy arrays: + is_sim_active (1D array having state (active or inactive) of each micro simulation) + sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None) + micro_output : list + List of dicts having individual output of each simulation. Only the active simulation outputs are entered. + + Returns + ------- + micro_output : list + List of dicts having individual output of each simulation. Active and inactive simulation outputs are entered. + """ + micro_sims_output = deepcopy(micro_output) + + sim_is_associated_to = adaptivity_data[2] + + for inactive_id in self._inactive_sim_ids: + micro_sims_output[inactive_id] = deepcopy( + micro_sims_output[sim_is_associated_to[inactive_id]] + ) + + return micro_sims_output + def _update_inactive_sims( self, similarity_dists: np.ndarray, diff --git a/micro_manager/micro_manager.py b/micro_manager/micro_manager.py index 34b34fd..76f8b80 100644 --- a/micro_manager/micro_manager.py +++ b/micro_manager/micro_manager.py @@ -126,7 +126,10 @@ def solve(self) -> None: dt = min(self._participant.get_max_time_step_size(), self._micro_dt) - # adaptivity_data is a of numpy arrays: similarity_dists (2D array having similarity distances between each micro simulation pair), is_sim_active (1D array having state (active or inactive) of each micro simulation), sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None) + # adaptivity_data is a list of numpy arrays: + # 1. similarity_dists (2D array having similarity distances between each micro simulation pair) + # 2. is_sim_active (1D array having state (active or inactive) of each micro simulation) + # 3. sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None) adaptivity_data: list = [] if self._is_adaptivity_on: @@ -343,8 +346,6 @@ def initialize(self) -> None: self._global_ids_of_local_sims.append(sim_id) sim_id += 1 - # self._micro_sims = [None] * self._local_number_of_sims # DECLARATION - # Setup for simulation crashes self._has_sim_crashed = [False] * self._local_number_of_sims if self._interpolate_crashed_sims: @@ -706,13 +707,12 @@ def _solve_micro_simulations_with_adaptivity( self._data_for_adaptivity, ) - sim_is_associated_to = adaptivity_data[2] - active_sim_ids = self._adaptivity_controller.get_active_sim_ids() for active_id in active_sim_ids: self._micro_sims_active_steps[active_id] += 1 + active_sim_ids = self._adaptivity_controller.get_active_sim_ids() inactive_sim_ids = self._adaptivity_controller.get_inactive_sim_ids() micro_sims_output = [None] * self._local_number_of_sims @@ -779,16 +779,9 @@ def _solve_micro_simulations_with_adaptivity( micro_sims_input, micro_sims_output, unset_sim, active_sim_ids ) - # For each inactive simulation, copy data from most similar active simulation - if self._adaptivity_type == "global": - self._adaptivity_controller.communicate_micro_output( - adaptivity_data[1:3], micro_sims_output - ) - elif self._adaptivity_type == "local": - for inactive_id in inactive_sim_ids: - micro_sims_output[inactive_id] = deepcopy( - micro_sims_output[sim_is_associated_to[inactive_id]] - ) + self._adaptivity_controller.get_full_field_micro_output( + adaptivity_data, micro_sims_output + ) # Resolve micro sim output data for inactive simulations for inactive_id in inactive_sim_ids: