示例#1
0
    def test_compatible_targets(self):
        modulation_target = ReactionModulationTarget("a", 1, 0)
        ki_target = ReactionKnockinTarget("a", None)

        ensemble_1 = EnsembleTarget("a", [modulation_target, ki_target])
        ensemble_2 = EnsembleTarget("a", [ki_target, modulation_target])

        assert ensemble_1.targets == ensemble_2.targets

        modulation_target = ReactionModulationTarget("b", 1, 0)
        swap_target = ReactionCofactorSwapTarget("b", [("nad_c", "nadh_c"),
                                                       ("nadp_c", "nadph_c")])

        ensemble_1 = EnsembleTarget("b", [modulation_target, swap_target])
        ensemble_2 = EnsembleTarget("b", [swap_target, modulation_target])

        assert ensemble_1.targets == ensemble_2.targets

        ki_target = ReactionKnockinTarget("c", None)
        modulation_target = ReactionModulationTarget("c", 1, 0)
        swap_target = ReactionCofactorSwapTarget("c", [("nad_c", "nadh_c"),
                                                       ("nadp_c", "nadph_c")])

        ensemble = EnsembleTarget("c",
                                  [modulation_target, swap_target, ki_target])
        assert ensemble.targets[0] == ki_target
        assert ensemble.targets[1] == swap_target
        assert ensemble.targets[2] == modulation_target
示例#2
0
    def test_add_strain_design(self):
        t1 = ReactionKnockoutTarget('PGI')
        t2 = ReactionKnockoutTarget('GAPD')
        t3 = ReactionKnockinTarget("CAD", self.cad_reaction)

        strain_design1 = StrainDesign([t1, t2, t3])

        t4 = ReactionModulationTarget("PGI", 5, 1)

        strain_design2 = StrainDesign([t4])

        self.assertRaises(IncompatibleTargets, strain_design1.__add__, strain_design2)
        self.assertRaises(IncompatibleTargets, strain_design2.__add__, strain_design1)

        self.assertRaises(IncompatibleTargets, strain_design1.__iadd__, strain_design2)
        self.assertRaises(IncompatibleTargets, strain_design2.__iadd__, strain_design1)

        t5 = ReactionModulationTarget("RPI", 2, 0)
        strain_design3 = StrainDesign([t5])

        strain_design4 = strain_design3 + strain_design1
        self.assertIn(t1, strain_design4)
        self.assertIn(t2, strain_design4)
        self.assertIn(t3, strain_design4)
        self.assertNotIn(t4, strain_design4)
        self.assertIn(t5, strain_design4)

        strain_design3 += strain_design1

        self.assertIn(t1, strain_design3)
        self.assertIn(t2, strain_design3)
        self.assertIn(t3, strain_design3)
        self.assertNotIn(t4, strain_design3)
        self.assertIn(t5, strain_design3)
示例#3
0
    def test_reaction_down_regulation_target(self, model):
        reaction_id = "PGI"
        ref_val = 4.86
        value = 3.4

        # (B - A) / A
        fold_change = -0.30041

        down_reg_target = ReactionModulationTarget(reaction_id, value, ref_val)
        assert round(abs(down_reg_target.fold_change - fold_change), 5) == 0
        with model:
            down_reg_target.apply(model)
            assert model.reactions.PGI.upper_bound == 3.4
            assert model.reactions.PGI.lower_bound == -1000
            assert abs(model.slim_optimize() - 0.8706) < 0.0001

        assert model.reactions.PGI.upper_bound == 1000
        assert model.reactions.PGI.lower_bound == -1000

        reaction_id = "RPI"
        ref_val = -2.28150
        value = -1.5

        fold_change = -0.342537

        down_reg_target = ReactionModulationTarget(reaction_id, value, ref_val)
        assert round(abs(down_reg_target.fold_change - fold_change), 5) == 0
        with model:
            down_reg_target.apply(model)
            assert model.reactions.RPI.lower_bound == -1.5
            assert model.reactions.RPI.upper_bound == 1000
            assert abs(model.slim_optimize() - 0.8691) < 0.0001

        assert model.reactions.RPI.lower_bound == -1000
        assert model.reactions.RPI.upper_bound == 1000
示例#4
0
    def test_incompatible_targets(self):
        ko_target = ReactionKnockoutTarget("a")
        ki_target = ReactionKnockinTarget("a", None)

        with pytest.raises(IncompatibleTargets):
            EnsembleTarget("a", [ko_target, ki_target])
        with pytest.raises(IncompatibleTargets):
            EnsembleTarget("a", [ki_target, ko_target])

        ko_target = ReactionKnockoutTarget("b")
        swap_target = ReactionCofactorSwapTarget("b", [("nad_c", "nadh_c"),
                                                       ("nadp_c", "nadph_c")])

        with pytest.raises(IncompatibleTargets):
            EnsembleTarget("b", [ko_target, swap_target])
        with pytest.raises(IncompatibleTargets):
            EnsembleTarget("b", [swap_target, ko_target])

        modulation_target = ReactionModulationTarget("c", 0, 0)
        ki_target = ReactionKnockinTarget("c", None)

        with pytest.raises(IncompatibleTargets):
            EnsembleTarget("c", [modulation_target, ki_target])
        with pytest.raises(IncompatibleTargets):
            EnsembleTarget("c", [ki_target, modulation_target])
示例#5
0
    def _generate_designs(solutions, reference_fva):
        designs = []

        for _, solution in solutions.iteritems():
            targets = []
            relevant_targets = solution[solution.normalized_gaps != 0]
            for rid, relevant_target in relevant_targets.iterrows():
                if relevant_target.normalized_gaps > 0:
                    targets.append(
                        ReactionModulationTarget(
                            rid, reference_fva['upper_bound'][rid],
                            relevant_target.lower_bound))
                else:
                    targets.append(
                        ReactionModulationTarget(
                            rid, reference_fva['lower_bound'][rid],
                            relevant_target.upper_bound))
            designs.append(StrainDesign(targets))
        return designs
示例#6
0
    def _generate_designs(reference, enforced_levels, reaction_results):
        for i, level in enumerate(enforced_levels):
            targets = []
            for reaction, value in six.iteritems(reaction_results):
                if abs(reference[reaction.id]) > 0:
                    if value[i] == 0:
                        targets.append(ReactionKnockoutTarget(reaction.id))
                    elif value[i] > reference[reaction.id]:
                        targets.append(ReactionModulationTarget(reaction.id, value[i], reference[reaction.id]))

            yield StrainDesign(targets)
示例#7
0
    def test_add_strain_design(self, cad_reaction):
        t1 = ReactionKnockoutTarget('PGI')
        t2 = ReactionKnockoutTarget('GAPD')
        t3 = ReactionKnockinTarget("CAD", cad_reaction)

        strain_design1 = StrainDesign([t1, t2, t3])

        t4 = ReactionModulationTarget("PGI", 5, 1)

        strain_design2 = StrainDesign([t4])

        with pytest.raises(IncompatibleTargets):
            strain_design1.__add__(strain_design2)
        with pytest.raises(IncompatibleTargets):
            strain_design2.__add__(strain_design1)

        with pytest.raises(IncompatibleTargets):
            strain_design1.__iadd__(strain_design2)
        with pytest.raises(IncompatibleTargets):
            strain_design2.__iadd__(strain_design1)

        t5 = ReactionModulationTarget("RPI", 2, 0)
        strain_design3 = StrainDesign([t5])

        strain_design4 = strain_design3 + strain_design1
        assert t1 in strain_design4
        assert t2 in strain_design4
        assert t3 in strain_design4
        assert t4 not in strain_design4
        assert t5 in strain_design4

        strain_design3 += strain_design1

        assert t1 in strain_design3
        assert t2 in strain_design3
        assert t3 in strain_design3
        assert t4 not in strain_design3
        assert t5 in strain_design3
示例#8
0
    def test_invalid_reaction_modulation_target(self, model):
        reaction_id = "PGI_XY"
        ref_val = 4.86
        value = 4

        down_reg_target = ReactionModulationTarget(reaction_id, value, ref_val)

        with pytest.raises(KeyError):
            down_reg_target.apply(model)

        reaction_id = "RPI_Z"
        ref_val = -2.28150
        value = -2.0

        down_reg_target = ReactionModulationTarget(reaction_id, value, ref_val)

        with pytest.raises(KeyError):
            down_reg_target.apply(model)
示例#9
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
示例#10
0
    def _generate_designs(cls, solutions, reference_fva):
        """
        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.

        Returns
        -------
        list
            A list of cameo.core.strain_design.StrainDesign for each DataFrame in solutions.
        """
        designs = []
        for _, solution in solutions.groupby(['biomass', 'production'],
                                             as_index=False,
                                             sort=False):
            targets = []
            relevant_targets = solution[
                (solution['normalized_gaps'].abs() > non_zero_flux_threshold)
                & (~solution['excluded']) & (~solution['free_flux'])]
            # Generate all knock-out targets.
            for rid in relevant_targets.loc[relevant_targets["KO"],
                                            "reaction"]:
                targets.append(ReactionKnockoutTarget(rid))
            # Generate all flux inversion targets.
            for row in relevant_targets[
                    relevant_targets["flux_reversal"]].itertuples():
                rid = row.Index
                ref_lower = reference_fva.at[rid, 'lower_bound']
                ref_upper = reference_fva.at[rid, 'upper_bound']
                if ref_upper > 0:
                    # Production point is negative so closest inversion is
                    # from reference lower bound to production upper bound.
                    targets.append(
                        ReactionInversionTarget(rid,
                                                value=row.upper_bound,
                                                reference_value=ref_lower))
                else:
                    # Production point is positive so closest inversion is
                    # from reference upper bound to production lower bound.
                    targets.append(
                        ReactionInversionTarget(rid,
                                                value=row.lower_bound,
                                                reference_value=ref_upper))
            # Generate all suddenly essential targets where we know the
            # reference interval lies around zero.
            for row in relevant_targets[
                    relevant_targets["suddenly_essential"]].itertuples():
                rid = row.Index
                if row.lower_bound > 0:
                    targets.append(
                        ReactionModulationTarget(
                            rid,
                            value=row.lower_bound,
                            reference_value=reference_fva.at[rid,
                                                             "upper_bound"]))
                else:
                    targets.append(
                        ReactionModulationTarget(
                            rid,
                            value=row.upper_bound,
                            reference_value=reference_fva.at[rid,
                                                             "lower_bound"]))
            # Generate all other flux modulation targets.
            for row in relevant_targets[
                (~relevant_targets["KO"])
                    & (~relevant_targets["flux_reversal"]) &
                (~relevant_targets["suddenly_essential"])].itertuples():
                rid = row.Index
                ref_lower = reference_fva.at[rid, 'lower_bound']
                ref_upper = reference_fva.at[rid, 'upper_bound']
                if row.normalized_gaps > 0:
                    # For now we ignore reactions that have a positive
                    # normalized gap, indicating that their flux is important
                    # for production, but where the reference flux is higher
                    # than the production flux.
                    if abs(ref_upper) > abs(row.lower_bound):
                        continue
                    targets.append(
                        ReactionModulationTarget(
                            rid,
                            value=row.lower_bound,
                            reference_value=ref_upper,
                            fold_change=row.normalized_gaps))
                else:
                    # For now we ignore reactions that have a negative
                    # normalized gap, indicating that their flux needs to
                    # decrease in production, but where the production
                    # interval is larger than the reference interval.
                    if abs(row.upper_bound) > abs(ref_lower):
                        continue
                    targets.append(
                        ReactionModulationTarget(
                            rid,
                            value=row.upper_bound,
                            reference_value=ref_lower,
                            fold_change=row.normalized_gaps))

            designs.append(StrainDesign(targets))
        return designs