Exemple #1
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])
    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)
Exemple #3
0
    def test_hashable(self):
        knockout_target1 = ReactionKnockoutTarget("ACALD")
        knockout_target2 = ReactionKnockoutTarget("ACALD")

        assert knockout_target1 == knockout_target2
        assert hash(knockout_target1) == hash(knockout_target2)

        assert len({knockout_target1, knockout_target2}) == 1
Exemple #4
0
    def test_reaction_knockout_target(self, model):
        knockout_target = ReactionKnockoutTarget("ACALD")
        with model:
            knockout_target.apply(model)
            assert model.reactions.ACALD.lower_bound == 0
            assert model.reactions.ACALD.upper_bound == 0

        assert model.reactions.ACALD.lower_bound == -1000
        assert model.reactions.ACALD.upper_bound == 1000
Exemple #5
0
    def test_reaction_knockout_target(self, model):
        knockout_target = ReactionKnockoutTarget("ACALD")
        with TimeMachine() as tm:
            knockout_target.apply(model, time_machine=tm)
            assert model.reactions.ACALD.lower_bound == 0
            assert model.reactions.ACALD.upper_bound == 0

        assert model.reactions.ACALD.lower_bound == -1000
        assert model.reactions.ACALD.upper_bound == 1000
Exemple #6
0
    def test_design_to_gnomic(self, cad_reaction):
        from gnomic import Genotype
        t1 = ReactionKnockoutTarget('PGI')
        t2 = ReactionKnockoutTarget('GAPD')
        t3 = ReactionKnockinTarget("CAD", cad_reaction)

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

        sd_gnomic = strain_design1.to_gnomic()

        assert isinstance(sd_gnomic, Genotype)
        assert len(sd_gnomic.added_features) == 1
        assert len(sd_gnomic.removed_features) == 2
    def test_design_to_gnomic(self):
        from gnomic import Genotype
        t1 = ReactionKnockoutTarget('PGI')
        t2 = ReactionKnockoutTarget('GAPD')
        t3 = ReactionKnockinTarget("CAD", self.cad_reaction)

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

        sd_gnomic = strain_design1.to_gnomic()

        self.assertIsInstance(sd_gnomic, Genotype)
        self.assertEqual(len(sd_gnomic.added_features), 1)
        self.assertEqual(len(sd_gnomic.removed_features), 2)
Exemple #8
0
    def _generate_designs(knockouts):
        designs = []
        for knockout_design in knockouts:
            designs.append(
                StrainDesign(
                    [ReactionKnockoutTarget(ko for ko in knockout_design)]))

        return designs
Exemple #9
0
    def test_create_strain_design(self, cad_reaction):
        t1 = ReactionKnockoutTarget('PGI')
        t2 = ReactionKnockoutTarget('GAPD')
        t3 = ReactionKnockinTarget("CAD", cad_reaction)

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

        assert len(strain_design) == 3
        strain_design2 = StrainDesign([t1, t2, t3])
        strain_design3 = StrainDesign([t2, t1, t3])

        assert strain_design == strain_design2
        assert strain_design == strain_design3
        assert strain_design3 == strain_design2

        assert t1 in strain_design
        assert t2 in strain_design
        assert t3 in strain_design
    def test_create_strain_design(self):
        t1 = ReactionKnockoutTarget('PGI')
        t2 = ReactionKnockoutTarget('GAPD')
        t3 = ReactionKnockinTarget("CAD", self.cad_reaction)

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

        self.assertEqual(len(strain_design), 3)
        strain_design2 = StrainDesign([t1, t2, t3])
        strain_design3 = StrainDesign([t2, t1, t3])

        self.assertEqual(strain_design, strain_design2)
        self.assertEqual(strain_design, strain_design3)
        self.assertEqual(strain_design3, strain_design2)

        self.assertIn(t1, strain_design)
        self.assertIn(t2, strain_design)
        self.assertIn(t3, strain_design)
    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)
Exemple #12
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
Exemple #13
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
Exemple #14
0
    def test_invalid_reaction_knockout_target(self, model):
        knockout_target = ReactionKnockoutTarget("ACALDXYZ")

        with pytest.raises(KeyError):
            knockout_target.apply(model)
Exemple #15
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