def _init_search_grid(self, surface_only=False, improvements_only=True):
     """Initialize the grid of points to be scanned within the production envelope."""
     self.envelope = phenotypic_phase_plane(
         self.design_space_model, self.variables, objective=self.objective, points=self.points)
     intervals = self.envelope[['objective_lower_bound', 'objective_upper_bound']].copy()
     intervals['objective_lower_bound'] = float_floor(intervals.objective_lower_bound, ndecimals)
     intervals['objective_upper_bound'] = float_ceil(intervals.objective_upper_bound, ndecimals)
     max_distance = 0.
     max_interval = None
     for i, (lb, ub) in intervals.iterrows():
         distance = abs(ub - lb)
         if distance > max_distance:
             max_distance = distance
             max_interval = (lb, ub)
     step_size = (max_interval[1] - max_interval[0]) / (self.points - 1)
     grid = list()
     minimal_reference_production = self.reference_flux_ranges['lower_bound'][self.objective]
     for i, row in self.envelope.iterrows():
         variables = row[self.variables]
         lb = row.objective_lower_bound
         if improvements_only:
             lb = max(lb, minimal_reference_production) + step_size
         ub = row.objective_upper_bound
         if not surface_only:
             coordinate = lb
             while coordinate < ub:
                 grid.append(list(variables.values) + [coordinate])
                 coordinate += step_size
         if improvements_only and ub <= minimal_reference_production:
             continue
         else:
             grid.append(list(variables.values) + [ub])
     columns = self.variables + [self.objective]
     self.grid = DataFrame(grid, columns=columns)
 def _init_search_grid(self, surface_only=False, improvements_only=True):
     """Initialize the grid of points to be scanned within the production envelope."""
     self.envelope = phenotypic_phase_plane(
         self.design_space_model, self.variables, objective=self.objective, points=self.points)
     intervals = self.envelope[['objective_lower_bound', 'objective_upper_bound']].copy()
     intervals['objective_lower_bound'] = float_floor(intervals.objective_lower_bound, ndecimals)
     intervals['objective_upper_bound'] = float_ceil(intervals.objective_upper_bound, ndecimals)
     max_distance = 0.
     max_interval = None
     for i, (lb, ub) in intervals.iterrows():
         distance = abs(ub - lb)
         if distance > max_distance:
             max_distance = distance
             max_interval = (lb, ub)
     step_size = (max_interval[1] - max_interval[0]) / (self.points - 1)
     grid = list()
     minimal_reference_production = self.reference_flux_ranges['lower_bound'][self.objective]
     for i, row in self.envelope.iterrows():
         variables = row[self.variables]
         lb = row.objective_lower_bound
         if improvements_only:
             lb = max(lb, minimal_reference_production) + step_size
         ub = row.objective_upper_bound
         if not surface_only:
             coordinate = lb
             while coordinate < ub:
                 grid.append(list(variables.values) + [coordinate])
                 coordinate += step_size
         if improvements_only and ub <= minimal_reference_production:
             continue
         else:
             grid.append(list(variables.values) + [ub])
     columns = self.variables + [self.objective]
     self.grid = DataFrame(grid, columns=columns)
Beispiel #3
0
 def test_float_conversions(self):
     val = 1.3456
     new_value = float_floor(val, 2)
     assert new_value == 1.34
     new_value = float_ceil(val, 2)
     assert new_value == 1.35
     new_value = float_floor(val, 1)
     assert new_value == 1.3
     new_value = float_ceil(val, 1)
     assert new_value == 1.4
     new_value = float_floor(val)
     assert new_value == 1
     new_value = float_ceil(val)
     assert new_value == 2
     val = 0.00000
     for i in range(1, 10):
         new_value = float_floor(val, i)
         assert new_value == 0
         new_value = float_ceil(val, i)
         assert new_value == 0
    def _generate_designs(cls, solutions, reference_fva, reference_fluxes):
        """
        Generates strain designs for Differential FVA.

        The conversion method has three scenarios:
        #### 1. Knockout

            Creates a ReactionKnockoutTarget.

        #### 2. Flux reversal

            If the new flux is negative then it should be at least the upper bound of the interval.
            Otherwise it should be at least the lower bound of the interval.

        #### 3. The flux increases or decreases

            This table illustrates the possible combinations.
                * Gap is the sign of the normalized gap between the intervals.
                * Ref is the sign of the closest bound (see _closest_bound).
                * Bound is the value to use

            +-------------------+
            | Gap | Ref | Bound |
            +-----+-----+-------+
            |  -  |  -  |   LB  |
            |  -  |  +  |   UB  |
            |  +  |  -  |   UB  |
            |  +  |  +  |   LB  |
            +-----+-----+-------+


        Parameters
        ----------
        solutions: pandas.Panel
            The DifferentialFVA panel with all the solutions. Each DataFrame is a design.
        reference_fva: pandas.DataFrame
            The FVA limits for the reference strain.
        reference_fluxes:
            The optimal flux distribution for the reference strain.

        Returns
        -------
        list
            A list of cameo.core.strain_design.StrainDesign for each DataFrame in solutions.
        """
        designs = []
        for _, solution in solutions.groupby(('biomass', 'production')):
            targets = []
            relevant_targets = solution.loc[
                (numpy.abs(solution['normalized_gaps']) > non_zero_flux_threshold) & (
                    numpy.logical_not(solution['excluded'])) & (
                        numpy.logical_not(solution['free_flux']))
            ]
            for rid, relevant_row in relevant_targets.iterrows():
                if relevant_row.KO:
                    targets.append(ReactionKnockoutTarget(rid))
                elif relevant_row.flux_reversal:
                    if reference_fva['upper_bound'][rid] > 0:
                        targets.append(ReactionInversionTarget(rid,
                                                               value=float_ceil(relevant_row.upper_bound, ndecimals),
                                                               reference_value=reference_fluxes[rid]))
                    else:
                        targets.append(ReactionInversionTarget(rid,
                                                               value=float_floor(relevant_row.lower_bound, ndecimals),
                                                               reference_value=reference_fluxes[rid]))
                else:
                    gap_sign = relevant_row.normalized_gaps > 0

                    ref_interval = reference_fva[['lower_bound', 'upper_bound']].loc[rid].values
                    row_interval = (relevant_row.lower_bound, relevant_row.upper_bound)

                    closest_bound, ref_sign = cls._closest_bound(ref_interval, row_interval)

                    if gap_sign ^ ref_sign:
                        value = float_ceil(relevant_row.upper_bound, ndecimals)
                    else:
                        value = float_floor(relevant_row.lower_bound, ndecimals)

                    targets.append(ReactionModulationTarget(rid,
                                                            value=value,
                                                            reference_value=reference_fva[closest_bound][rid]))

            designs.append(StrainDesign(targets))
        return designs
Beispiel #5
0
    def _generate_designs(cls, solutions, reference_fva, reference_fluxes):
        """
        Generates strain designs for Differential FVA.

        The conversion method has three scenarios:
        #### 1. Knockout

            Creates a ReactionKnockoutTarget.

        #### 2. Flux reversal

            If the new flux is negative then it should be at least the upper bound of the interval.
            Otherwise it should be at least the lower bound of the interval.

        #### 3. The flux increases or decreases

            This table illustrates the possible combinations.
                * Gap is the sign of the normalized gap between the intervals.
                * Ref is the sign of the closest bound (see _closest_bound).
                * Bound is the value to use

            +-------------------+
            | Gap | Ref | Bound |
            +-----+-----+-------+
            |  -  |  -  |   LB  |
            |  -  |  +  |   UB  |
            |  +  |  -  |   UB  |
            |  +  |  +  |   LB  |
            +-----+-----+-------+


        Parameters
        ----------
        solutions: pandas.Panel
            The DifferentialFVA panel with all the solutions. Each DataFrame is a design.
        reference_fva: pandas.DataFrame
            The FVA limits for the reference strain.
        reference_fluxes:
            The optimal flux distribution for the reference strain.

        Returns
        -------
        list
            A list of cameo.core.strain_design.StrainDesign for each DataFrame in solutions.
        """
        designs = []
        for _, solution in solutions.groupby(('biomass', 'production')):
            targets = []
            relevant_targets = solution.loc[
                (numpy.abs(solution['normalized_gaps']) >
                 non_zero_flux_threshold)
                & (numpy.logical_not(solution['excluded'])) &
                (numpy.logical_not(solution['free_flux']))]
            for rid, relevant_row in relevant_targets.iterrows():
                if relevant_row.KO:
                    targets.append(ReactionKnockoutTarget(rid))
                elif relevant_row.flux_reversal:
                    if reference_fva['upper_bound'][rid] > 0:
                        targets.append(
                            ReactionInversionTarget(
                                rid,
                                value=float_ceil(relevant_row.upper_bound,
                                                 ndecimals),
                                reference_value=reference_fluxes[rid]))
                    else:
                        targets.append(
                            ReactionInversionTarget(
                                rid,
                                value=float_floor(relevant_row.lower_bound,
                                                  ndecimals),
                                reference_value=reference_fluxes[rid]))
                else:
                    gap_sign = relevant_row.normalized_gaps > 0

                    ref_interval = reference_fva[[
                        'lower_bound', 'upper_bound'
                    ]].loc[rid].values
                    row_interval = (relevant_row.lower_bound,
                                    relevant_row.upper_bound)

                    closest_bound, ref_sign = cls._closest_bound(
                        ref_interval, row_interval)

                    if gap_sign ^ ref_sign:
                        value = float_ceil(relevant_row.upper_bound, ndecimals)
                    else:
                        value = float_floor(relevant_row.lower_bound,
                                            ndecimals)

                    targets.append(
                        ReactionModulationTarget(
                            rid,
                            value=value,
                            reference_value=reference_fva[closest_bound][rid]))

            designs.append(StrainDesign(targets))
        return designs