コード例 #1
0
    def test_condense_simple(self):
        complexes, reactions = read_pil("""
        # File generated by peppercorn-v0.5.0
        
        # Domain Specifications 
        length d1 = 15
        length t0 = 5
        
        # Resting-set Complexes 
        c1 = t0 d1 
        c2 = d1( + ) t0* 
        c4 = t0( d1( + ) ) 
        c5 = d1 
        
        # Transient Complexes 
        c3 = t0( d1 + d1( + ) ) 
        
        # Detailed Reactions 
        reaction [bind21         =      100 /M/s ] c1 + c2 -> c3
        reaction [open           =       50 /s   ] c3 -> c1 + c2
        reaction [branch-3way    =       50 /s   ] c3 -> c4 + c5
        """)

        # (rs1) c1                c4 (rs3)
        #         \              /
        #          <---> c3 ---->
        #         /              \
        # (rs2) c2                c5 (rs4)

        enum = Enumerator(complexes.values(), reactions)
        enum.enumerate() 
        enum.condense()
        for con in enum.condensed_reactions:
            assert con.rate_constant[0] == 50
        del enum

        # old interface ...
        c1 = PepperMacrostate([complexes['c1']])
        c2 = PepperMacrostate([complexes['c2']])
        c4 = PepperMacrostate([complexes['c4']])
        c5 = PepperMacrostate([complexes['c5']])
        cond_react = PepperReaction([c1, c2], [c4, c5], 'condensed')
        cond_react.rate_constant = 20, None

        enum = Enumerator(complexes.values(), reactions)
        enum.dry_run()
        enumRG = PepperCondensation(enum)
        enumRG.condense()
        for con in enumRG.condensed_reactions:
            assert con.rate_constant[0] == 20
コード例 #2
0
    def compute_fates(self, scc):
        """
        Processes a single SCC neighborhood, generating resting set multisets
        for each complex, and storing the mappings in the outer-scope
        `complex_fates` dict

        """
        complex_fates = self._complex_fates

        if scc[0] in complex_fates:
            # Dirty check to see if the scc has been processed before.
            return

        # Convert to a set for fast lookup
        scc_set = frozenset(scc)

        outgoing_reactions = []
        for c in scc:
            for r in self.reactions_consuming(c):
                if self.is_fast(r) and is_outgoing(r, scc_set):
                    outgoing_reactions.append(r)

        # If this SCC is a resting set:
        if len(outgoing_reactions) == 0:
            # build new resting set
            try:
                resting_set = PepperMacrostate(scc)
            except DSDDuplicationError, e:
                resting_set = e.existing

            self._set_to_fate[scc_set] = resting_set

            # calculate stationary distribution
            self._stationary_distributions[
                resting_set] = self.get_stationary_distribution(scc)

            # assign fate to each complex in the SCC
            fate = (resting_set, )  # needs to be iterable..
            fates = frozenset([fate])

            for c in scc:
                if c in complex_fates:
                    raise CondensationError(
                        'complex should not be assigned yet')
                complex_fates[c] = SetOfFates(fates)

                # all complexes in this SCC decay to this SCC with probability 1,
                # e.g. P(c -> SCC) = 1 for all c in this SCC
                self._decay_probabilities[(c, fate)] = 1.0
コード例 #3
0
 def rs(self, names):
     return PepperMacrostate(map(self.cplx, names), memorycheck=False)
コード例 #4
0
    def test_cooperative_binding(self):
        # cooperative binding with k-fast 25
        complexes, reactions = read_pil("""
        # File generated by peppercorn-v0.5.0
        
        # Domain Specifications 
        length a = 5
        length b = 5
        length x = 10
        length y = 10
        
        # Resting-set Complexes 
        C = x( y( + b* ) ) a* 
        CR = x( y( + y b( + ) ) ) a* 
        CRF = x( y + y( b( + ) ) ) a* 
        L = a x 
        LC = a( x + x( y( + b* ) ) ) 
        LCF = a( x( + x y( + b* ) ) ) 
        LR = a( x( + y( b( + ) ) ) ) 
        R = y b 
        T = x y 
        
        # Transient Complexes 
        LCR = a( x + x( y( + y b( + ) ) ) ) 
        LCRF1 = a( x( + x y( + y b( + ) ) ) ) 
        LCRF2 = a( x + x( y + y( b( + ) ) ) ) 
        
        # Detailed Reactions 
        reaction [bind21         =      1.5e+06 /M/s ] C + L -> LC
        reaction [bind21         =      1.5e+06 /M/s ] C + R -> CR
        reaction [open           =           20 /s   ] CR -> C + R
        reaction [branch-3way    =           30 /s   ] CR -> CRF
        reaction [branch-3way    =           30 /s   ] CRF -> CR
        reaction [bind21         =      1.5e+06 /M/s ] L + CR -> LCR
        reaction [bind21         =      1.5e+06 /M/s ] L + CRF -> LCRF2
        reaction [open           =           20 /s   ] LC -> C + L
        reaction [branch-3way    =           30 /s   ] LC -> LCF
        reaction [branch-3way    =           30 /s   ] LCF -> LC
        reaction [branch-3way    =           30 /s   ] LCR -> LCRF1
        reaction [branch-3way    =           30 /s   ] LCR -> LCRF2
        reaction [branch-3way    =           30 /s   ] LCRF1 -> LCR
        reaction [branch-3way    =           30 /s   ] LCRF1 -> T + LR
        reaction [branch-3way    =           30 /s   ] LCRF2 -> LCR
        reaction [branch-3way    =           30 /s   ] LCRF2 -> T + LR
        reaction [bind21         =      1.5e+06 /M/s ] R + LC -> LCR
        reaction [bind21         =      1.5e+06 /M/s ] R + LCF -> LCRF1
        """)
        L = complexes['L']
        C = complexes['C']
        R = complexes['R']
        T = complexes['T']
        LR = complexes['LR']
        LC = complexes['LC']
        CR = complexes['CR']
        CRF = complexes['CRF']
        LCF = complexes['LCF']
        LCR = complexes['LCR']
        LCRF1 = complexes['LCRF1']
        LCRF2 = complexes['LCRF2']

        # always resting sets
        rs1 = PepperMacrostate([L], memorycheck=False)
        rs2 = PepperMacrostate([C], memorycheck=False)
        rs3 = PepperMacrostate([R], memorycheck=False)
        rs4 = PepperMacrostate([T], memorycheck=False)
        rs5 = PepperMacrostate([LR], memorycheck=False)

        rs6 = PepperMacrostate([CR, CRF], memorycheck=False)
        rs7 = PepperMacrostate([LC, LCF], memorycheck=False)

        cplx_to_fate = {  # maps Complex to its SetOfFates
            L: SetOfFates([[rs1]]),
            C: SetOfFates([[rs2]]),
            R: SetOfFates([[rs3]]),
            T: SetOfFates([[rs4]]),
            LR: SetOfFates([[rs5]]),
            CR: SetOfFates([[rs6]]),
            CRF: SetOfFates([[rs6]]),
            LC: SetOfFates([[rs7]]),
            LCF: SetOfFates([[rs7]]),
            #NOTE: only rs4 and rs5 bec. the other unimolecular reactions are now slow!!
            LCR: SetOfFates([[rs4, rs5]]),
            LCRF1: SetOfFates([[rs4, rs5]]),
            LCRF2: SetOfFates([[rs4, rs5]])
        }

        cr1 = PepperReaction([rs1, rs2], [rs7],
                             'condensed',
                             rate=1.5e6,
                             memorycheck=False)
        cr2 = PepperReaction([rs2, rs3], [rs6],
                             'condensed',
                             rate=1.5e6,
                             memorycheck=False)

        # not sure how these rates were computed...
        cr1r = PepperReaction([rs7], [rs1, rs2],
                              'condensed',
                              rate=10.0,
                              memorycheck=False)
        cr2r = PepperReaction([rs6], [rs2, rs3],
                              'condensed',
                              rate=10.0,
                              memorycheck=False)
        cr3 = PepperReaction([rs1, rs6], [rs5, rs4],
                             'condensed',
                             rate=3e6 / 2,
                             memorycheck=False)
        cr4 = PepperReaction([rs3, rs7], [rs5, rs4],
                             'condensed',
                             rate=3e6 / 2,
                             memorycheck=False)

        enum = Enumerator(complexes.values(), reactions)

        enum.k_fast = 25

        #enum.enumerate() # or enum.dry_run()
        enum.dry_run()  # or enum.dry_run()

        enumRG = PepperCondensation(enum)
        enumRG.condense()

        # Works...
        self.assertEqual(enum.k_fast, enumRG.k_fast)
        self.assertEqual(sorted([rs1, rs2, rs3, rs4, rs5, rs6, rs7]),
                         sorted(enumRG.resting_sets))

        self.assertDictEqual(cplx_to_fate, enumRG.cplx_to_fate)
        self.assertEqual(sorted([cr1, cr1r, cr2, cr2r, cr3, cr4]),
                         sorted(enumRG.condensed_reactions))

        for (r1, r2) in zip(sorted([cr1, cr1r, cr2, cr2r, cr3, cr4]),
                            sorted(enumRG.condensed_reactions)):
            self.assertEqual(r1, r2)
            self.assertAlmostEqual(r1.rate, r2.rate)
コード例 #5
0
    def test_zhang_cooperative_binding(self):
        complexes, reactions = read_pil("""
        # Figure 1 of David Yu Zhang, "Cooperative hybridization of oligonucleotides", JACS, 2012

        # File generated by peppercorn-v0.5.0

        # Domain Specifications 
        length d1 = 8
        length d2 = 18
        length d3 = 18
        length d4 = 8

        # Resting-set Complexes 
        C1 = d2( d3( + d4* ) ) d1* 
        L1 = d1( d2 + d2( d3( + d4* ) ) ) 
        L2 = d1( d2( + d2 d3( + d4* ) ) ) 
        Out = d2 d3 
        R1 = d2( d3( + d3 d4( + ) ) ) d1* 
        R2 = d2( d3 + d3( d4( + ) ) ) d1* 
        T1 = d1 d2 
        T2 = d3 d4 
        Waste = d1( d2( + d3( d4( + ) ) ) ) 

        # Transient Complexes 
        L1R1 = d1( d2 + d2( d3( + d3 d4( + ) ) ) ) 
        L1R2 = d1( d2 + d2( d3 + d3( d4( + ) ) ) ) 
        L2R1 = d1( d2( + d2 d3( + d3 d4( + ) ) ) ) 

        # Detailed Reactions 
        reaction [bind21         =      2.4e+06 /M/s ] C1 + T2 -> R1
        reaction [bind21         =      2.4e+06 /M/s ] L1 + T2 -> L1R1
        reaction [branch-3way    =      18.5185 /s   ] L1 -> L2
        reaction [branch-3way    =      18.5185 /s   ] L1R1 -> L1R2
        reaction [branch-3way    =      18.5185 /s   ] L1R1 -> L2R1
        reaction [branch-3way    =      18.5185 /s   ] L1R2 -> L1R1
        reaction [branch-3way    =      18.5185 /s   ] L1R2 -> Waste + Out
        reaction [bind21         =      2.4e+06 /M/s ] L2 + T2 -> L2R1
        reaction [branch-3way    =      18.5185 /s   ] L2 -> L1
        reaction [branch-3way    =      18.5185 /s   ] L2R1 -> L1R1
        reaction [branch-3way    =      18.5185 /s   ] L2R1 -> Waste + Out
        reaction [branch-3way    =      18.5185 /s   ] R1 -> R2
        reaction [branch-3way    =      18.5185 /s   ] R2 -> R1
        reaction [bind21         =      2.4e+06 /M/s ] T1 + C1 -> L1
        reaction [bind21         =      2.4e+06 /M/s ] T1 + R1 -> L1R1
        reaction [bind21         =      2.4e+06 /M/s ] T1 + R2 -> L1R2
        """)

        enum = Enumerator(complexes.values(), reactions)
        enum.k_fast = 0.01
        enum.release_cutoff = 10
        #enum.enumerate() # or enum.dry_run()
        enum.dry_run()

        enumRG = PepperCondensation(enum)
        enumRG.condense()
        """
        macrostate rC1 = [C1]
        macrostate rL2 = [L2, L1]
        macrostate rOut = [Out]
        macrostate rR1 = [R1, R2]
        macrostate rT1 = [T1]
        macrostate rT2 = [T2]
        macrostate rWaste = [Waste]

        reaction [condensed      =      2.4e+06 /M/s ] rT1 + rC1 -> rL2
        reaction [condensed      =      2.4e+06 /M/s ] rL2 + rT2 -> rWaste + rOut
        reaction [condensed      =      2.4e+06 /M/s ] rC1 + rT2 -> rR1
        reaction [condensed      =      2.4e+06 /M/s ] rT1 + rR1 -> rWaste + rOut
        reaction [condensed      =   0.00316623 /s   ] rL2 -> rT1 + rC1
        reaction [condensed      =   0.00316623 /s   ] rR1 -> rC1 + rT2
        """

        L1 = complexes['L1']
        L2 = complexes['L2']
        rL2 = PepperMacrostate([L2, L1], memorycheck=False)
        Out = complexes['Out']
        rOut = PepperMacrostate([Out], memorycheck=False)
        Waste = complexes['Waste']
        rWaste = PepperMacrostate([Waste], memorycheck=False)
        T2 = complexes['T2']
        rT2 = PepperMacrostate([T2], memorycheck=False)

        # calculated by hand...
        cr1 = PepperReaction([rL2, rT2], [rWaste, rOut],
                             'condensed',
                             rate=2.4e6,
                             memorycheck=False)

        found = False
        for r in enumRG.condensed_reactions:
            if r == cr1:
                found = True
                self.assertAlmostEqual(r.rate, cr1.rate)

        self.assertTrue(found)
コード例 #6
0
    def test_condense_simple(self):
        complexes, reactions = read_pil("""
        # File generated by peppercorn-v0.5.0
        
        # Domain Specifications 
        length d1 = 15
        length t0 = 5
        
        # Resting-set Complexes 
        c1 = t0 d1 
        c2 = d1( + ) t0* 
        c4 = t0( d1( + ) ) 
        c5 = d1 
        
        # Transient Complexes 
        c3 = t0( d1 + d1( + ) ) 
        
        # Detailed Reactions 
        reaction [bind21         =      100 /M/s ] c1 + c2 -> c3
        reaction [open           =       50 /s   ] c3 -> c1 + c2
        reaction [branch-3way    =       50 /s   ] c3 -> c4 + c5
        """)

        # (rs1) c1                c4 (rs3)
        #         \              /
        #          <---> c3 ---->
        #         /              \
        # (rs2) c2                c5 (rs4)

        # RestingSet representation
        rs1 = PepperMacrostate([complexes['c1']], memorycheck=False)
        rs2 = PepperMacrostate([complexes['c2']], memorycheck=False)
        rs3 = PepperMacrostate([complexes['c4']], memorycheck=False)
        rs4 = PepperMacrostate([complexes['c5']], memorycheck=False)

        # Frozensets instead of RestingMacrostates
        fs1 = frozenset([complexes['c1']])
        fs2 = frozenset([complexes['c2']])
        fs3 = frozenset([complexes['c4']])
        fs4 = frozenset([complexes['c5']])

        cplx_to_state = {  # maps Complex to its RestingMacrostate
            complexes['c1']: rs1,
            complexes['c2']: rs2,
            complexes['c4']: rs3,
            complexes['c5']: rs4
        }

        cplx_to_fate = {  # maps Complex to its SetOfFates
            complexes['c1']: SetOfFates([[rs1]]),
            complexes['c2']: SetOfFates([[rs2]]),
            complexes['c3']: SetOfFates([[rs1, rs2], [rs3, rs4]]),
            complexes['c4']: SetOfFates([[rs3]]),
            complexes['c5']: SetOfFates([[rs4]])
        }

        cplx_to_set = {  # maps Complex to its frozenset
            complexes['c1']: fs1,
            complexes['c2']: fs2,
            complexes['c4']: fs3,
            complexes['c5']: fs4
        }

        set_to_fate = {  # maps frozenset to the RestingMacrostate
            fs1: rs1,
            fs2: rs2,
            fs3: rs3,
            fs4: rs4
        }

        cond_react = PepperReaction([rs1, rs2], [rs3, rs4],
                                    'condensed',
                                    memorycheck=False)
        cond_react.rate = 100 * (float(50) / (50 + 50))

        enum = Enumerator(complexes.values(), reactions)
        enum.dry_run()  # does not change the rates!

        enumRG = PepperCondensation(enum)
        enumRG.condense()

        self.assertEqual(sorted([rs1, rs2, rs3, rs4]),
                         sorted(enumRG.resting_sets))
        self.assertDictEqual(set_to_fate, enumRG.set_to_fate)
        self.assertDictEqual(cplx_to_fate, enumRG.cplx_to_fate)
        #self.assertDictEqual(cplx_to_set,  info['complexes_to_resting_set'])

        self.assertEqual([cond_react], enumRG.condensed_reactions)
        self.assertEqual(cond_react.rate, enumRG.condensed_reactions[0].rate)
        self.assertEqual(enumRG.condensed_reactions[0].rate, 50)
コード例 #7
0
 def rs(self, names):
     return PepperMacrostate(list(map(self.cplx, names)))
コード例 #8
0
    def test_zhang_cooperative_binding(self):
        complexes, reactions = read_pil("""
        # Figure 1 of David Yu Zhang, "Cooperative hybridization of oligonucleotides", JACS, 2012

        # File generated by peppercorn-v0.5.0

        # Domain Specifications 
        length d1 = 8
        length d2 = 18
        length d3 = 18
        length d4 = 8

        # Resting-set Complexes 
        C1 = d2( d3( + d4* ) ) d1* 
        L1 = d1( d2 + d2( d3( + d4* ) ) ) 
        L2 = d1( d2( + d2 d3( + d4* ) ) ) 
        Out = d2 d3 
        R1 = d2( d3( + d3 d4( + ) ) ) d1* 
        R2 = d2( d3 + d3( d4( + ) ) ) d1* 
        T1 = d1 d2 
        T2 = d3 d4 
        Waste = d1( d2( + d3( d4( + ) ) ) ) 

        # Transient Complexes 
        L1R1 = d1( d2 + d2( d3( + d3 d4( + ) ) ) ) 
        L1R2 = d1( d2 + d2( d3 + d3( d4( + ) ) ) ) 
        L2R1 = d1( d2( + d2 d3( + d3 d4( + ) ) ) ) 

        # Detailed Reactions 
        reaction [bind21         =      2.4e+06 /M/s ] C1 + T2 -> R1
        reaction [bind21         =      2.4e+06 /M/s ] L1 + T2 -> L1R1
        reaction [branch-3way    =      18.5185 /s   ] L1 -> L2
        reaction [branch-3way    =      18.5185 /s   ] L1R1 -> L1R2
        reaction [branch-3way    =      18.5185 /s   ] L1R1 -> L2R1
        reaction [branch-3way    =      18.5185 /s   ] L1R2 -> L1R1
        reaction [branch-3way    =      18.5185 /s   ] L1R2 -> Waste + Out
        reaction [bind21         =      2.4e+06 /M/s ] L2 + T2 -> L2R1
        reaction [branch-3way    =      18.5185 /s   ] L2 -> L1
        reaction [branch-3way    =      18.5185 /s   ] L2R1 -> L1R1
        reaction [branch-3way    =      18.5185 /s   ] L2R1 -> Waste + Out
        reaction [branch-3way    =      18.5185 /s   ] R1 -> R2
        reaction [branch-3way    =      18.5185 /s   ] R2 -> R1
        reaction [bind21         =      2.4e+06 /M/s ] T1 + C1 -> L1
        reaction [bind21         =      2.4e+06 /M/s ] T1 + R1 -> L1R1
        reaction [bind21         =      2.4e+06 /M/s ] T1 + R2 -> L1R2
        """)

        enum = Enumerator(complexes.values(), reactions)
        enum.k_fast = 0.01 
        enum.release_cutoff = 10
        enum.enumerate() # or enum.dry_run()

        enumRG = PepperCondensation(enum)
        enumRG.condense()
        
        """
        macrostate rC1 = [C1]
        macrostate rL2 = [L2, L1]
        macrostate rOut = [Out]
        macrostate rR1 = [R1, R2]
        macrostate rT1 = [T1]
        macrostate rT2 = [T2]
        macrostate rWaste = [Waste]

        reaction [condensed      =      2.4e+06 /M/s ] rT1 + rC1 -> rL2
        reaction [condensed      =      2.4e+06 /M/s ] rL2 + rT2 -> rWaste + rOut
        reaction [condensed      =      2.4e+06 /M/s ] rC1 + rT2 -> rR1
        reaction [condensed      =      2.4e+06 /M/s ] rT1 + rR1 -> rWaste + rOut
        reaction [condensed      =   0.00316623 /s   ] rL2 -> rT1 + rC1
        reaction [condensed      =   0.00316623 /s   ] rR1 -> rC1 + rT2
        """
        
        try:
            L1 = complexes['L1']
            L2 = complexes['L2']
            L = PepperMacrostate([L1, L2])
        except SingletonError as err:
            L = err.existing
        O = PepperMacrostate([complexes['Out']])
        W = PepperMacrostate([complexes['Waste']])
        T = PepperMacrostate([complexes['T2']])

        # calculated by hand...
        cr1 = PepperReaction([L, T], [W, O], 'condensed')
        assert cr1 in enumRG.condensed_reactions
        assert cr1.rate_constant == (2.4e6, '/M/s')
コード例 #9
0
def segment_neighborhood(complexes, reactions, p_min=None):
    """
    Segmentation of a potentially incomplete neighborhood. That means only
    the specified complexes are interesting, all others should not be
    returned.

    Beware: Complexes must contain all reactants in reactions *and* there
    must not be any incoming fast reactions into complexes, other than
    those specified in reactions. Thus, we can be sure that the SCCs found here
    are consistent with SCCs found in a previous iteration.

    Args:
        complexes(list[:obj:`PepperComplex`])
    """
    index = 0
    S = []
    SCCs = []

    total = complexes[:]
    for rxn in reactions: 
        total += rxn.products

    total = list(set(total))

    # Set up for Tarjan's algorithm
    for c in total: c._index = None

    # filters reaction products such that there are only species from within complexes
    # this is ok, because it must not change the assignment of SCCs.
    rxns_within = {k: [] for k in complexes}
    rxns_consuming = {k: [r for r in reactions if (k in r.reactants)] for k in total}
    for rxn in reactions:
        assert len(rxn.reactants) == 1
        for product in rxn.products:
            if product in complexes:
                rxns_within[rxn.reactants[0]].append(product)
        rxns_consuming[rxn.reactants[0]]

    def tarjans_scc(cplx, index):
        """
        Executes an iteration of Tarjan's algorithm (a modified DFS) starting
        at the given node.
        """
        # Set this node's tarjan numbers
        cplx._index = index
        cplx._lowlink = index
        index += 1
        S.append(cplx)

        for product in rxns_within[cplx]:
            # Product hasn't been traversed; recurse
            if product._index is None :
                index = tarjans_scc(product, index)
                cplx._lowlink = min(cplx._lowlink, product._lowlink)

            # Product is in the current neighborhood
            elif product in S:
                cplx._lowlink = min(cplx._lowlink, product._index)
    
        if cplx._lowlink == cplx._index:
            scc = []
            while True:
                next = S.pop()
                scc.append(next)
                if next == cplx:
                    break
            SCCs.append(scc)
        return index

    # We now perform Tarjan's algorithm, marking nodes as appropriate
    for cplx in complexes:
        if cplx._index is None:
            tarjans_scc(cplx, index)

    resting_macrostates = []
    transient_macrostates = []
    resting_complexes = []
    transient_complexes = []

    for scc in SCCs:
        try:
            ms = PepperMacrostate(scc[:], prefix='')
        except DSDDuplicationError, e:
            assert set(e.existing.complexes) == set(scc)
            ms = e.existing
        #except DSDObjectsError, e:
        #    assert set(e.existing.complexes) <= set(scc)
        #    del PepperMacrostate.MEMORY[e.existing.canonical_form]
        #    del PepperMacrostate.NAMES[e.existing.name]
        #    ms = PepperMacrostate(scc[:], prefix='')

        for c in scc:
            for rxn in rxns_consuming[c]:
                ms.add_reaction(rxn)

        if ms.is_transient:
            transient_complexes += (scc)
        else :
            resting_macrostates.append(ms)

            if p_min:
                for (c, s) in ms.get_stationary_distribution():
                    if s < p_min:
                        transient_complexes.append(c)
                    else :
                        resting_complexes.append(c)
            else:
                resting_complexes += (scc)