def test_fail_when_request_sim_and_sim_group(self): # prepare the grid study = self.study sim = study.simulations[0] grid = SimulationGroup(name="SG", simulations=[sim]) with self.assertRaises(ValueError): build_chromatogram_model(self.study, sims=[sim], sim_group=grid)
def test_run_sim_group(self): study = self.study2 cp = study.simulations[0] diff = (SingleParamSimulationDiff("binding_model.sma_ka[1]", 0.01), ) group = SimulationGroup(center_point_simulation=cp, name="foo", simulation_diffs=[diff]) # Before running the group, the simulations have no results. assert not group.has_run for sim in group.simulations: self.assertIsNone(sim.output) assert not sim.has_run with self.assertTraitChanges(group, 'has_run', 1): study.run_simulation_group(self.job_manager, sim_group=group, wait=True) # Has run assert group.has_run for sim in group.simulations: self.assertIsInstance(sim.output, ChromatographyResults) assert sim.has_run df = group.group_data self.assertIsInstance(df, pd.DataFrame) self.assertEqual(df.shape, (1, 8)) self.assertEqual(df.loc[0, "binding_model.sma_ka[1]"], 0.01) output_cols = [ 'pool_volume (CV)', 'pool_concentration (g/L)', 'step_yield (%)' ] self.assertFalse(np.any(np.isnan(df.loc[:, output_cols])))
def test_search_simulation_in_group_by_name(self): study = self.study2 cp = study.simulations.pop(0) group = SimulationGroup(name="BLAH", simulations=[cp]) study.analysis_tools.simulation_grids.append(group) with self.assertRaises(KeyError): study.search_simulation_by_name(cp.name, how="shallow") searched = study.search_simulation_by_name(cp.name, how="deep") self.assertIs(searched, cp)
def test_create_run_save_load_sim_grid_flow_rate(self): """ Save a grid that scanned a flow rate.""" cp = make_sample_simulation2() diff = (SingleParamSimulationDiff("method.method_steps[0].flow_rate", UnitScalar(5, units=cm_per_hr)), ) object_to_save = SimulationGroup(center_point_simulation=cp, name="foo", simulation_diffs=[diff]) self.run_and_assert_serialization_succeeds(object_to_save)
def make_sample_simulation_group(cp=None): from kromatography.model.simulation_group import SimulationGroup, \ SingleParamSimulationDiff if cp is None: cp = make_sample_simulation2() diff = (SingleParamSimulationDiff("binding_model.sma_ka[1]", 0.01),) sim_group = SimulationGroup(center_point_simulation=cp, name="foo", simulation_diffs=[diff]) return sim_group
def test_create_save_load_sim_grid_unit_scalar(self): cp = make_sample_simulation2() diff = (SingleParamSimulationDiff("method.method_steps[0].flow_rate", UnitScalar(5, units=cm_per_hr)), ) obj = SimulationGroup(center_point_simulation=cp, name="foo", simulation_diffs=[diff]) assert_roundtrip_identical(obj, ignore=SIM_GROUP_IGNORE) assert_round_trip_to_file_identical(self.filepath, obj, ignore=SIM_GROUP_IGNORE)
def test_simulation_groups_exist(self): task = self.task2 study = self.study2 # The properties are correct self.assertFalse(task.simulation_groups_exist) sim_group_menu = get_run_simulation_group(task) # The menu entry is disabled self.assertFalse(sim_group_menu.items[1].enabled) sim = build_sim_from_study(study) sim_gp = SimulationGroup(center_point_simulation=sim, name="Group0") study.analysis_tools.simulation_grids.append(sim_gp) self.assertTrue(task.simulation_groups_exist)
def build_df_editor_grid_data(group_data, num_outputs): """ Build a dataframe editor for grid data. """ adapter = DataFrameWithColumnOutputsAdapter(num_outputs=num_outputs, df_attr_name="group_data") formats = {SIM_COL_NAME: "%s"} for key in group_data: if SimulationGroup.col_is_output(key): formats[key] = "%.3f" elif key != SIM_COL_NAME: formats[key] = "%g" # Because of the way the DataFrame editor is implemented, # the `model.` prefix should not be passed for the update name: sim_group_df_editor = DataFrameEditor(adapter=adapter, formats=formats, update="group_data_updated_event") return sim_group_df_editor
def make_sample_simulation_group2(size=3, cp=None): """ Build a sample simulation group scanning the sma_ka parameters. Parameters ---------- size : int (default: 3) Number of values to scan. cp : Simulation or None (default: None) Center point simulation to build the simulation group from if any. By default a sample simulation is built from the std example data. """ from kromatography.model.simulation_group import SimulationGroup, \ SingleParamSimulationDiff if cp is None: cp = make_sample_simulation() orig_val = cp.binding_model.sma_ka[1] no_diff = (SingleParamSimulationDiff("binding_model.sma_ka[1]", orig_val),) simulation_map = {no_diff: cp} if size > 1: sim2 = cp.clone_traits(copy="deep") sim2.name = "sim2" sim2.binding_model.sma_ka[1] = 0.01 diff2 = (SingleParamSimulationDiff("binding_model.sma_ka[1]", 0.01),) simulation_map[diff2] = sim2 if size > 2: sim3 = cp.clone_traits(copy="deep") sim3.name = "sim3" sim3.binding_model.sma_ka[1] = 0.1 diff3 = (SingleParamSimulationDiff("binding_model.sma_ka[1]", 0.1),) simulation_map[diff3] = sim3 group = SimulationGroup( center_point_simulation=cp, name="foo", simulation_diffs=simulation_map.keys() ) return group
def setUp(self): self.study = make_sample_study2(add_transp_bind_models=True, add_sims='Run_1') self.sim = self.study.simulations[0] # Save time by loading results from an already generated file: self.result_filepath = io_data_path("std_example_xlsx_run1_cadet.h5") update_simulation_results(self.sim, output_fname=self.result_filepath) self.sim.set_as_run() # Add a simulation grid grp = SimulationGroup(center_point_simulation=self.sim, name="new group") self.study.analysis_tools.simulation_grids.append(grp) # Add a Monte Carlo simulation group mc_grp = make_sample_mc_simulation_group() self.study.analysis_tools.monte_carlo_explorations.append(mc_grp) # Skip attributes not stored in a study/task: (user) datasource, # study_datasource.dirty, sim group's cp, self.ignore = {'center_point_simulation', 'datasource', 'perf_params', 'dirty'}
def get_instance(self, constructor_data): from kromatography.model.simulation_group import SimulationGroup instance = SimulationGroup(**constructor_data['kwargs']) return instance
def build_5_point_groups_from_param_desc(cp_sim, param_list, param_labels=None): """ Build 5-point simulation groups from a list of parameters to study their impact on performances. Parameter descriptions specify their operational and characterization ranges. Parameters ---------- cp_sim : Simulation Center point simulation around which to scan and compare to. param_list : dict Dictionary mapping parameter paths to scan to a tuple describing how to scan it. That tuple must be of length 4, containing respectively the low operating value, high operating value, low characterization value and high characterization value. All values must be in the unit the center point simulation has that parameter in, if applicable. Note that both keys and values can be replaced with tuples of paths and tuples of 4-value tuples when multiple parameters must be scanned together. param_labels : dict [OPTIONAL] Map between a parameter path and a nice string representation for it. It will be used as the grid's name. Returns ------- dict Map between the parameter path to explore (the first one in each dimension) and the corresponding simulation group to run. """ from kromatography.plotting.mpl_param_impact_plot import PARAM_LABELS if param_labels is None: param_labels = PARAM_LABELS groups = {} for coupled_params, coupled_param_values in param_list.items(): if isinstance(coupled_params, basestring): coupled_params = [coupled_params] coupled_param_values = [coupled_param_values] else: # Convert to list to be able to modify it: coupled_param_values = list(coupled_param_values) for i in range(len(coupled_params)): param_name = coupled_params[i] values = coupled_param_values[i] print("Exploring {} impact".format(param_name)) if len(values) != 4: msg = "Format of param_list argument not supported: it should"\ " contain the following values: low_or, high_or, low_cr"\ ", high_cr." logger.exception(msg) raise ValueError(msg) # Replace values with unitted values if needed: cp_val = eval("sim.{}".format(param_name), {}, {"sim": cp_sim}) if isinstance(cp_val, UnitScalar): coupled_param_values[i] = [ UnitScalar(p, units=cp_val.units) for p in values ] values = coupled_param_values[i] # Reorder to be low_cr, low_or, center, high_or, high_cr since # it is the plotting function default: coupled_param_values[i] = [ values[2], values[0], values[1], values[3] ] coupled_param_values[i].insert(2, cp_val) # Build all sim diffs for each parameter in the dimension diffs = [[SingleParamSimulationDiff(param, val) for val in vals] for param, vals in zip(coupled_params, coupled_param_values)] # Regroup the coupled parameter diffs together: diffs = zip(*diffs) dimension_name = param_labels.get(coupled_params[0], coupled_params[0]) group = SimulationGroup(name="Explore {}".format(dimension_name), center_point_simulation=cp_sim, simulation_diffs=diffs) groups[coupled_params[0]] = group return groups
def build_group_or_groups(group_name, center_sim, simulation_diffs, max_size, group_type=SIM_GROUP_GRID_TYPE, auto_delete_run_sims=False): """ Build a group or a list of groups from simulation diffs based on the group size limit. Parameters ---------- group_name center_sim: Simulation Simulation from which to build the group. simulation_diffs : list List of simulation differences to build the group's simulation from. max_size : int Max size of the future simulation group. If the resulting group will be bigger, a list of groups is returned rather than 1 group. Then, each group has a size less or equal to max_size. group_type : str [OPTIONAL, default="Multi-Param Grid"] Type of simulation group to build. Must be "Multi-Param Grid" or "Monte-Carlo Exploration". auto_delete_run_sims : bool [OPTIONAL, default=False] Delete CADET files and in memory simulations once they run? Returns ------- SimulationGroup or list(SimulationGroup) SimulationGroup created from the list of parameter scans the group should explore. If a max_size is provided, returns a list of SimulationGroup instances collectively scanning the entire parameter space described by parameter_scans, each with 0 < size <= max_size. """ group_traits = dict(center_point_simulation=center_sim, type=group_type, auto_delete_run_sims=auto_delete_run_sims) if not max_size: group = SimulationGroup(name=group_name, simulation_diffs=simulation_diffs, **group_traits) return group else: # Split the simulation diffs into blocks of size at or below max_size groups = [] # Compute the number of groups to split all diffs into: factor, mod = divmod(len(simulation_diffs), max_size) num_group = factor if mod: num_group += 1 for i in range(num_group): block_sim_diffs = simulation_diffs[i * max_size:(i + 1) * max_size] block_name = "Block_{}_".format(i) + group_name group = SimulationGroup(name=block_name, simulation_diffs=block_sim_diffs, **group_traits) groups.append(group) return groups