Ejemplo n.º 1
0
    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 build_object(self, serial_data):
     from kromatography.model.simulation_group import \
         SingleParamSimulationDiff
     data = serial_data['data']
     val = serial_data['data']['val']
     deserializer = self.select_deserializer(val)
     data["val"] = deserializer.build_object(val)
     return SingleParamSimulationDiff(**data)
    def setUp(self):
        orig_val = self.sim.binding_model.sma_ka[1]
        self.no_diff = (SingleParamSimulationDiff("binding_model.sma_ka[1]",
                                                  orig_val), )
        self.study = Study(name="test study", simulations=[self.sim])

        def frozen_sim_group_maker(**kw):
            return make_sample_simulation_group2(cp=self.sim, **kw)

        self.sim_group_maker = frozen_sim_group_maker
    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)
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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 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)
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
def sim_diffs_from_random_parameter_scans(parameter_scans,
                                          group_size,
                                          adtl_params=None):
    """ Transform all RandomParameterScanDescription into a list of Simulation
    diffs.

    Parameters
    ----------
    parameter_scans : list
        List of RandomParameterScanDescription describing which parameters to
        scan and following which random distribution.

    group_size : int
        Number of random values to generate. Corresponds to the future size of
        the group.

    adtl_params : dict
        Map between scanned parameter names and a list of additional parameters
        that must be modified in the same simulation. If that's the case, the
        values must be lists of 2-tuples, containing the attribute path for the
        additional parameter that must change in sync and a callable which
        receives the random value of the source parameter and returns the value
        of the additional parameter.

        This advanced feature can be needed when scanning a proportion of a
        component, and needing to adjust another one every time to keep the
        total at 100%.

    Examples
    --------
    This will create a 100 size simulation group scanning uniformly the elution
    flow rate and the start collect::

    >>> parameters = [
        RandomParameterScanDescription(
            name="method.method_steps[2].flow_rate",
            distribution="uniform",
            dist_param1=50, dist_param2=100
        ),
        RandomParameterScanDescription(
            name="method.collection_criteria.start_collection_target",
            distribution="uniform",
            dist_param1=30, dist_param2=50
        ),
    ]

    >>> sim_diffs_from_random_parameter_scans(parameters, 100)
    [(SingleParamSimulationDiff...]
    """
    if adtl_params is None:
        adtl_params = {p.name: [] for p in parameter_scans}
    else:
        for p in parameter_scans:
            if p.name not in adtl_params:
                adtl_params[p.name] = []

    if len(parameter_scans) == 0:
        simulation_diffs = []
    else:
        # Generate the arrays of random values for each parameter
        all_param_values = {}
        for param in parameter_scans:
            func = DISTRIBUTION_MAP.get(param.distribution, None)
            if func is None:
                func = getattr(random, param.distribution)

            param_values = func(param.dist_param1,
                                param.dist_param2,
                                *param.additional_params,
                                size=group_size)
            all_param_values[param] = param_values

        # Generate the simulation diffs from the random values
        simulation_diffs = []
        # FIXME: Inefficient! GET RID OF THIS FOR LOOP or cythonize it!
        for diff_num in range(group_size):
            sim_diff = []
            for param in parameter_scans:
                value = all_param_values[param][diff_num]
                if isinstance(param.center_value, UnitScalar):
                    units = param.center_value.units
                    value = UnitScalar(value, units=units)

                diff = SingleParamSimulationDiff(param.name, value)
                sim_diff.append(diff)
                for additional_param_desc in adtl_params[param.name]:
                    adtl_param_name, evaluator = additional_param_desc
                    diff = SingleParamSimulationDiff(adtl_param_name,
                                                     evaluator(value))
                    sim_diff.append(diff)

            simulation_diffs.append(tuple(sim_diff))

    return simulation_diffs