def test_self_displacement_03(self): complexes, reactions = read_pil(""" length x1 = 10 length x2 = 10 length y1 = 10 length y2 = 10 B1 = x1( x2( y1( y2( x1( x2( y1 y2 x1 x2 + ) ) ) ) ) ) B2 = x1 x2 y1 y2 x1( x2( y1( y2( x1( x2( + ) ) ) ) ) ) i1 = x1( x2( y1 y2 x1 x2 y1( y2( x1( x2( + ) ) ) ) ) ) i2 = x1( x2( y1( y2( x1 x2 y1 y2 x1( x2( + ) ) ) ) ) ) """) B1 = complexes['B1'] B2 = complexes['B2'] i1 = complexes['i1'] i2 = complexes['i2'] path1 = PepperReaction([B1], [i1], 'branch-3way') path1r = PepperReaction([i1], [B1], 'branch-3way') path1f = PepperReaction([i1], [B2], 'branch-3way') path2 = PepperReaction([B2], [i2], 'branch-3way') path2r = PepperReaction([i2], [B2], 'branch-3way') path2f = PepperReaction([i2], [B1], 'branch-3way') enum = Enumerator([B1]) enum.max_helix = True enum.enumerate() self.assertEqual( sorted(enum.reactions), sorted([path1, path1r, path1f, path2, path2r, path2f]))
def test_self_displacement_01(self): complexes, reactions = read_pil(""" length x = 10 length y = 10 B1 = x( y( x( y x + ) ) ) B2 = x y x( y( x( + ) ) ) B3 = x( y( x y x( + ) ) ) B4 = x( y x y( x( + ) ) ) """) B1 = complexes['B1'] B2 = complexes['B2'] B3 = complexes['B3'] B4 = complexes['B4'] path1 = PepperReaction([B1], [B4], 'branch-3way') path1r = PepperReaction([B4], [B1], 'branch-3way') path2 = PepperReaction([B4], [B2], 'branch-3way') path3 = PepperReaction([B2], [B3], 'branch-3way') path3r = PepperReaction([B3], [B2], 'branch-3way') path4 = PepperReaction([B3], [B1], 'branch-3way') enum = Enumerator([B1]) enum.max_helix = True enum.enumerate() self.assertEqual(sorted(enum.reactions), sorted([path1, path1r, path2, path3, path3r, path4]))
def test_self_displacement_02(self): complexes, reactions = read_pil(""" length x = 10 length y = 10 T = x( y x + ) y* x* T1 = x( y x + x* y* ) T2 = x y x( + ) y* x* T3 = x( y( x( + ) ) ) T4 = x y x( + x* y* ) """) T = complexes['T'] T1 = complexes['T1'] T2 = complexes['T2'] T3 = complexes['T3'] T4 = complexes['T4'] path1 = PepperReaction([T], [T1], 'branch-3way') path1r = PepperReaction([T1], [T], 'branch-3way') path2 = PepperReaction([T], [T2], 'branch-3way') path2r = PepperReaction([T2], [T], 'branch-3way') path3 = PepperReaction([T1], [T3], 'bind11') path4 = PepperReaction([T2], [T3], 'bind11') path5 = PepperReaction([T1], [T4], 'branch-3way') path5r = PepperReaction([T4], [T1], 'branch-3way') path6 = PepperReaction([T2], [T4], 'branch-3way') path6r = PepperReaction([T4], [T2], 'branch-3way') enum = Enumerator([T]) enum.max_helix = True enum.enumerate() self.assertEqual( sorted(enum.reactions), sorted([ path1, path1r, path2, path2r, path3, path4, path5, path5r, path6, path6r ]))
def test_CondenseGraphCRN_01(self): complexes = self.complexes reactions = self.reactions cplx = self.cplx rxn = self.rxn rs = self.rs rxn('A -> B + C') rxn('B -> D + E', k=0.5) rxn('C -> F + G', k=1) #rxn('B + C -> A') # raises error enum = Enumerator(complexes.values(), list(reactions)) enum.dry_run() #for r in enum.reactions: print r, r.rate #print enum.complexes enumRG = PepperCondensation(enum) enumRG.condense() self.assertEqual(enumRG.condensed_reactions, []) self.assertEqual( enumRG.resting_sets, [rs('E'), rs('D'), rs('F'), rs('G')]) self.assertEqual(enumRG.get_fates(cplx('A')), SetOfFates([[rs('E'), rs('D'), rs('F'), rs('G')]]))
def test_CondenseGraphCRN_02(self): complexes = self.complexes reactions = self.reactions cplx = self.cplx rxn = self.rxn rs = self.rs rxn('A -> B') rxn('A -> C') rxn('B -> D') rxn('B -> E') rxn('C -> F') rxn('C -> G') enum = Enumerator(complexes.values(), list(reactions)) enum.dry_run() enumRG = PepperCondensation(enum) enumRG.condense() self.assertEqual( enumRG.resting_sets, [rs('E'), rs('D'), rs('F'), rs('G')]) self.assertEqual( enumRG.get_fates(cplx('A')), SetOfFates([[rs('E')], [rs('D')], [rs('F')], [rs('G')]])) self.assertEqual(enumRG.get_fates(cplx('C')), SetOfFates([[rs('F')], [rs('G')]])) self.assertEqual(enumRG.get_fates(cplx('F')), SetOfFates([[rs('F')]]))
def test_CondenseGraphCRN_03(self): complexes = self.complexes reactions = self.reactions cplx = self.cplx rxn = self.rxn rs = self.rs rxn('X -> T1', k=0.1) rxn('T1 -> T2') rxn('T2 -> T1') rxn('T1 -> A') rxn('T1 -> B') rxn('T2 -> T3') rxn('T3 -> D') rxn('T3 -> C') enum = Enumerator(complexes.values(), list(reactions)) enum.k_fast = 0.5 enum.dry_run() enumRG = PepperCondensation(enum) enumRG.condense() self.assertEqual(sorted(enumRG.resting_sets), sorted([rs('X'), rs('A'), rs('B'), rs('C'), rs('D')])) self.assertEqual(enumRG.get_fates(cplx('X')), SetOfFates([[rs('X')]])) self.assertEqual( enumRG.get_fates(cplx('T1')), SetOfFates([[rs('A')], [rs('B')], [rs('C')], [rs('D')]]))
def test_bind_and_displace3way(self): complexes, reactions = read_pil(""" length a = 10 length b = 10 length c = 10 length t = 5 I = a b c J = b c C = b( c( + ) ) a* B = a( b c + b( c( + ) ) ) D = a( b( c( + ) ) ) """) I = complexes['I'] J = complexes['J'] C = complexes['C'] B = complexes['B'] D = complexes['D'] # DSD-pathway "bind21" path1 = PepperReaction([I, C], [B], 'bind21') # DSD-pathway "branch3way" path2 = PepperReaction([B], [D, J], 'branch-3way') enum = Enumerator(list(complexes.values())) enum.enumerate() self.assertEqual(sorted(enum.reactions), sorted([path1, path2]))
def test_peppercorn_interface(self): """ Make sure peppercorn.utils did not change """ t0 = peputils.Domain('t0', 5, sequence='H'*5) t0_ = peputils.Domain('t0', 5, sequence='D'*5, is_complement=True) d1 = peputils.Domain('d1', 15, sequence='H'*15) d1_ = peputils.Domain('d1', 15, sequence='D'*15, is_complement=True) domains = [t0,t0_,d1,d1_] s0 = peputils.Strand('s0', [t0, d1]) s1 = peputils.Strand('s1', [d1]) s2 = peputils.Strand('s2', [d1_, t0_]) strands = [s0,s1,s2] c1s = peputils.parse_dot_paren('..') c1 = peputils.Complex('c1', [s0], c1s) c1.check_structure() c2s = peputils.parse_dot_paren('(+).') c2 = peputils.Complex('c2', [s1,s2], c2s) c2.check_structure() complexes = [c1,c2] enum = Enumerator(domains, strands, complexes) enum.enumerate() ########################### # Get full output CRN reactions = enum.reactions self.assertEqual(len(reactions), 3) r1_kernel = 't0 d1 + d1( + ) t0* -> t0( d1 + d1( + ) )' r2_kernel = 't0( d1 + d1( + ) ) -> t0( d1( + ) ) + d1' r3_kernel = 't0( d1 + d1( + ) ) -> t0 d1 + d1( + ) t0*' p_cntr = Counter() r_cntr = Counter() for r in sorted(reactions): #print r.kernel_string() for cx in r.reactants : p_cntr += Counter(map(str, cx.strands)) for cx in r.products: r_cntr += Counter(map(str, cx.strands)) self.assertEqual(p_cntr, r_cntr) self.assertTrue(r.kernel_string() in [r1_kernel, r2_kernel, r3_kernel]) ########################### # Get condensed output CRN condensed = condense_resting_states(enum, compute_rates=True, k_fast = 0.) reactions = condensed['reactions'] self.assertEqual(len(reactions), 1) result_kernel = 't0 d1 + d1( + ) t0* -> t0( d1( + ) ) + d1' self.assertEqual(reactions[0].kernel_string(), result_kernel)
def test_cooperative_binding_fail(self): 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 """) enum = Enumerator(complexes.values()) enum.enumerate() # or enum.dry_run() enumRG = PepperCondensation(enum) # TODO: It should raise an error here, saying that the condensed graph # is disconnected! #with self.assertRaises(c.CondensationError): enumRG.condense() self.assertEqual(enumRG.condensed_reactions, [])
def test_max_helix_02(self): complexes, reactions = read_pil(""" length d1 = 15 length d4 = 15 length d6 = 15 length d7 = 15 length h8 = 15 length t0 = 6 length t2 = 6 length t3 = 6 length t5 = 6 # Initial Complexes B2 = d7 t3 d4 t5 helper = t3 d7 t3 PR_FL_B2 = d1 t2( d6( + d7( t3( d4 t5 + ) ) t3* ) ) @ initial 0 M # Intermediate Complexes PR_FLh1B2 = d1 t2( d6( + t3( d7 t3 + d7( t3( d4 t5 + ) ) ) ) ) @ initial 0 M PR_FLh2B2 = d1 t2( d6( + t3 d7 t3( + d7( t3( d4 t5 + ) ) ) ) ) @ initial 0 M PR_FL_h1w = d1 t2( d6( + t3( d7( t3( + ) ) ) ) ) @ initial 0 M # sidestuff PR_FLB2B2 = d1 t2( d6( + d7 t3( d4 t5 + d7( t3( d4 t5 + ) ) ) ) ) @ initial 0 M # casey-semantics PR_FLh2B2_v2 = d1 t2( d6( + t3( d7( t3 + d7 t3( d4 t5 + ) ) ) ) ) @ initial 0 M PR_FLh2w = d1 t2( d6( + t3( d7( t3 + t3* ) ) ) ) @ initial 0 M """) B2 = complexes['B2'] helper = complexes['helper'] PR_FL_B2 = complexes['PR_FL_B2'] PR_FLh1B2 = complexes['PR_FLh1B2'] PR_FLh2B2 = complexes['PR_FLh2B2'] PR_FL_h1w = complexes['PR_FL_h1w'] PR_FLB2B2 = complexes['PR_FLB2B2'] PR_FLh2B2_v2 = complexes['PR_FLh2B2_v2'] PR_FLh2w = complexes['PR_FLh2w'] path1 = PepperReaction([PR_FL_B2, helper], [PR_FLh1B2], 'bind21') path1r = PepperReaction([PR_FLh1B2], [PR_FL_B2, helper], 'open') path2 = PepperReaction([PR_FL_B2, helper], [PR_FLh2B2], 'bind21') path2r = PepperReaction([PR_FLh2B2], [PR_FL_B2, helper], 'open') path3 = PepperReaction([PR_FLh1B2], [PR_FL_h1w, B2], 'branch-3way') path4 = PepperReaction([PR_FL_B2, B2], [PR_FLB2B2], 'bind21') path4r = PepperReaction([PR_FLB2B2], [PR_FL_B2, B2], 'open') path5 = PepperReaction([PR_FLh1B2], [PR_FLh2B2], 'branch-3way') path6 = PepperReaction([PR_FLh2B2], [PR_FLh1B2], 'branch-3way') enum = Enumerator([B2, helper, PR_FL_B2]) enum.max_helix = True enum.enumerate() assert sorted(enum.reactions) == sorted( [path1, path1r, path2, path2r, path3, path4, path4r, path5, path6])
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
def test_interface_01(self): PepperComplex.PREFIX = 'enum' complexes, reactions = read_pil(""" # Domain Specifications length a = 8 length b = 8 length c = 8 length d2 = 8 length d3 = 8 length t = 4 # Resting-set Complexes e0 = d2( d3( + ) a* + a*( b*( c ) ) ) t* e12 = d2 d3( + ) a* e13 = t( d2( d3 + a*( b*( c ) ) ) ) e21 = d2 d3 e22 = t( d2( d3( + ) a*( + a* b*( c ) ) ) ) e27 = t( d2( d3( + ) a* + a*( b*( c ) ) ) ) gate = d2( d3( + ) a*( + a* b*( c ) ) ) t* t23 = t d2 d3 # Transient Complexes e5 = t( d2 d3 + d2( d3( + ) a*( + a* b*( c ) ) ) ) e7 = t( d2 d3 + d2( d3( + ) a* + a*( b*( c ) ) ) ) e18 = t( d2( d3 + d2 d3( + ) a*( + a* b*( c ) ) ) ) # Detailed Reactions reaction [bind21 = 1.2e+06 /M/s ] e0 + t23 -> e7 reaction [branch-3way = 0.122307 /s ] e0 -> gate reaction [branch-3way = 41.6667 /s ] e5 -> e7 reaction [branch-3way = 41.6667 /s ] e5 -> e18 reaction [open = 306.345 /s ] e5 -> t23 + gate reaction [open = 306.345 /s ] e7 -> e0 + t23 reaction [branch-3way = 0.122307 /s ] e7 -> e5 reaction [branch-3way = 41.6667 /s ] e7 -> e12 + e13 reaction [branch-3way = 0.122307 /s ] e18 -> e5 reaction [branch-3way = 41.6667 /s ] e18 -> e12 + e13 reaction [branch-3way = 0.122307 /s ] e18 -> e22 + e21 reaction [branch-3way = 41.6667 /s ] e22 -> e27 reaction [branch-3way = 0.122307 /s ] e27 -> e22 reaction [branch-3way = 41.6667 /s ] gate -> e0 reaction [bind21 = 1.2e+06 /M/s ] t23 + gate -> e5 """) enum = Enumerator(complexes.values(), reactions) enum.release_cutoff = 7 enum.enumerate() self.assertEqual(sorted(enum.reactions), sorted(reactions))
def test_sarma_fig4_CRN(self): complexes = self.complexes reactions = self.reactions cplx = self.cplx rxn = self.rxn rs = self.rs rxn('top + bot -> e27 ', k=4.5e+06, rtype='bind21 ') rxn('com1 + e29 -> e33', k=1.5e+06, rtype='bind21 ') rxn('bot + com2 -> e29', k=4.5e+06, rtype='bind21 ') rxn('com1 + com2 -> e1', k=1.5e+06, rtype='bind21 ') rxn('e1 -> com1 + com2', k=21.7122, rtype='open ') rxn('e1 -> e6 + e7 ', k=9.52381, rtype='branch-3way') rxn('e1 -> e8 ', k=22.2222, rtype='branch-3way') rxn('e6 + bot -> e31 ', k=4.5e+06, rtype='bind21 ') rxn('e7 -> e15 ', k=22.2222, rtype='branch-3way') rxn('e8 -> e1 ', k=22.2222, rtype='branch-3way') rxn('e8 -> e6 + e15 ', k=9.52381, rtype='branch-3way') rxn('e8 -> e10 + e11 ', k=21.7122, rtype='open ') rxn('e10 -> e6 + e17 ', k=9.52381, rtype='branch-3way') rxn('e15 -> e7 ', k=22.2222, rtype='branch-3way') rxn('e15 -> e17 + e11 ', k=21.7122, rtype='open ') rxn('e17 + e11 -> e15 ', k=1.5e+06, rtype='bind21 ') rxn('e33 -> com1 + e29', k=21.7122, rtype='open ') rxn('e33 -> e37 ', k=22.2222, rtype='branch-3way') rxn('e33 -> e38 ', k=0.000623053, rtype='branch-4way') rxn('e37 -> e33 ', k=22.2222, rtype='branch-3way') rxn('e37 -> e43 ', k=0.000623053, rtype='branch-4way') rxn('e37 -> e58 + e11 ', k=21.7122, rtype='open ') rxn('e38 -> e31 + e7 ', k=16.6667, rtype='branch-3way') rxn('e38 -> e33 ', k=0.000623053, rtype='branch-4way') rxn('e38 -> e43 ', k=22.2222, rtype='branch-3way') rxn('e43 -> e47 + e11 ', k=21.7122, rtype='open ') rxn('e43 -> e31 + e15 ', k=16.6667, rtype='branch-3way') rxn('e43 -> e37 ', k=0.000623053, rtype='branch-4way') rxn('e43 -> e38 ', k=22.2222, rtype='branch-3way') rxn('e47 -> e31 + e17 ', k=16.6667, rtype='branch-3way') rxn('e47 -> e58 ', k=0.000623053, rtype='branch-4way') rxn('e58 -> e47 ', k=0.000623053, rtype='branch-4way') enum = Enumerator(complexes.values(), list(reactions)) enum.dry_run() enumRG = PepperCondensation(enum) enumRG.condense()
def test_named_complexes(self): complexes, reactions = read_pil(""" sequence t = GGAGCC sequence s = ATATAT sequence r = GCGCGC sequence d2 = GGCAAACAAG sequence d3 = CGGCAGAATT sequence a = CGCATTTGCC sequence b = TACCTTTTCC sequence c = CAAAGCCCTT A = t d2 s* d3 B = d2( d3( + ) s*( a* + a*( b*( c ) ) ) ) t* B2 = d2( d3( + ) s* a* + a*( b*( c ) ) s ) t* @ initial 0 M B3 = d2( d3( + ) s*( a*( + a* b*( c ) ) ) ) t* @ initial 0 M B4 = d2( d3( + ) s* a*( + a* b*( c ) ) s ) t* @ initial 0 M C = d2 d3( + ) s* a* @initial 0 M D = t( d2( s*( d3 + a*( b*( c ) ) ) ) ) @i 0 M E = d2 d3 @i 0 M F = t( d2( s*( d3( + ) s* a*( + a* b*( c ) ) ) ) ) @i 0 M G = t d2 s* d3( + ) s* a* @i 0 M """) A = complexes['A'] B = complexes['B'] F = complexes['F'] enum = Enumerator([A, B], named_complexes=[A, B, F]) enum.max_complex_count = 1000 enum.max_reaction_count = 5000 enum.enumerate() self.assertTrue( F in [rms.representative for rms in enum.resting_macrostates])
def test_interface_02(self): complexes, _ = read_pil(""" length a = 3 length n = 1 length b = 1 length c = 4 length ab = 4 X = a( b( c( + ) ) ) Y = ab( c( + ) ) Xf = a b( c( + ) ) a* Xff= a b c( + ) b* a* Xb = a( b( c + c* ) ) Y1 = ab c( + ) ab* Y2 = ab( c + c* ) """) X = complexes['X'] Y = complexes['Y'] Xf = complexes['Xf'] Xff = complexes['Xff'] Xb = complexes['Xb'] Y1 = complexes['Y1'] Y2 = complexes['Y2'] enum = Enumerator([X, Y], named_complexes=[X, Y, Xf, Xff, Xb, Y1, Y2]) enum.max_helix = False enum.dry_run() self.assertEqual(sorted(enum.complexes), sorted([X, Y])) self.assertEqual(sorted(enum.resting_complexes), sorted([X, Y])) self.assertEqual( sorted(r.representative for r in enum.resting_macrostates), sorted([X, Y])) enum.enumerate() assert len(list(enum.complexes)) == 16 with self.assertRaises(PeppercornUsageError) as e: enum.dry_run()
def test_cooperative_binding(self): complexes, reactions = read_pil(""" length a = 5 length x = 10 length y = 10 length b = 5 C = x( y( + b* ) ) a* L = a x R = y b T = x y LC = a( x + x( y( + b* ) ) ) CR = x( y( + y b( + ) ) ) a* LCR = a( x + x( y( + y b( + ) ) ) ) LCF = a( x( + x y( + b* ) ) ) CRF = x( y + y( b( + ) ) ) a* LCRF1 = a( x( + x y( + y b( + ) ) ) ) LCRF2 = a( x + x( y + y( b( + ) ) ) ) LR = a( x( + y( b( + ) ) ) ) """) C = complexes['C'] L = complexes['L'] R = complexes['R'] T = complexes['T'] LC = complexes['LC'] LCF = complexes['LCF'] CR = complexes['CR'] CRF = complexes['CRF'] LCRF1 = complexes['LCRF1'] LR = complexes['LR'] path1 = PepperReaction([L, C], [LC], 'bind21') path1r = PepperReaction([LC], [L, C], 'open') path2 = PepperReaction([LC], [LCF], 'branch-3way') path3 = PepperReaction([R, LCF], [LCRF1], 'bind21') path4 = PepperReaction([LCRF1], [LR, T], 'branch-3way') enum = Enumerator(list(complexes.values())) enum.k_fast = float('inf') enum.k_slow = 0 enum.max_helix = True enum.enumerate() self.assertEqual(len(list(enum.reactions)), 22)
def test_simple(self): complexes, reactions = read_pil(""" length a = 6 length a1 = 2 length a2 = 2 length a3 = 2 length b = 24 length b1 = 8 length b2 = 8 length b3 = 8 length c = 24 length c1 = 8 length c2 = 8 length c3 = 8 I = a b c C = b( c( + ) ) a* J = a( b c + b( c( + ) ) ) D = a( b( c( + ) ) ) cI = a1 a2 a3 b1 b2 b3 c1 c2 c3 cC = b1( b2( b3( c1( c2( c3( + ) ) ) ) ) ) a3* a2* a1* cJ = a1( a2( a3( b1 b2 b3 c1 c2 c3 + b1( b2( b3( c1( c2( c3( + ) ) ) ) ) ) ) ) ) cD = a1( a2( a3( b1( b2( b3( c1( c2( c3( + ) ) ) ) ) ) ) ) ) """) enum = Enumerator( [complexes['I'], complexes['C'], complexes['J'], complexes['D']], named_complexes=list(complexes.values())) enum.k_fast = 0 enum.k_slow = 0 enum.max_helix = True enum.enumerate() enum2 = Enumerator([ complexes['cI'], complexes['cC'], complexes['cJ'], complexes['cD'] ], named_complexes=list(complexes.values())) enum.k_fast = 0 enum2.k_fast = 0 enum2.k_slow = 0 enum2.max_helix = True enum2.enumerate() self.assertEqual(len(list(enum2.reactions)), len(list(enum.reactions)))
def test_max_helix_01(self): complexes, reactions = read_pil(""" length a = 15 length x = 15 length x1 = 15 length x2 = 15 length y = 15 length y1 = 15 length y2 = 15 length z = 15 length z1 = 15 length z2 = 15 # should be one reaction, is one A1 = x( y z + y( z( + ) ) ) A1_2 = x( y( z( + ) ) ) YZ = y z # should be one reactions, is one B1 = x1( x2( y1 y2 z1 z2 + y1( y2( z1( z2( + ) ) ) ) ) ) B1_2 = x1( x2( y1( y2( z1( z2( + ) ) ) ) ) ) YZ2 = y1 y2 z1 z2 # should be two reactions, is two A2 = x( y z + y( + z( + ) ) ) A2_1 = x( y( z + z( + ) ) ) #A2_2 = x( y( z( + ) ) ) # = A1_2 Y1 = y Z1 = z # should be two reactions, is two B2 = x1( x2( y1 y2 z1 z2 + y1( y2( + z1( z2( + ) ) ) ) ) ) B2_1 = x1( x2( y1( y2( z1 z2 + z1( z2( + ) ) ) ) ) ) Y2 = y1 y2 Z2 = z1 z2 # should be two reactions, is two C = x( y z + y( + a( + ) z( + ) ) ) C1 = x( y( z + a( + ) z( + ) ) ) r1 = a( + ) z """) A1 = complexes['A1'] A1_2 = complexes['A1_2'] YZ = complexes['YZ'] A2 = complexes['A2'] A2_1 = complexes['A2_1'] #A2_2 = complexes['A2_2'] Y1 = complexes['Y1'] Z1 = complexes['Z1'] enum = Enumerator([A1, A2]) enum.k_fast = 0 enum.k_slow = 0 enum.max_helix = True enum.enumerate() path1 = PepperReaction([A1], sorted([A1_2, YZ]), 'branch-3way') path2 = PepperReaction([A2], sorted([A2_1, Y1]), 'branch-3way') path3 = PepperReaction([A2_1], sorted([A1_2, Z1]), 'branch-3way') self.assertEqual(sorted(enum.reactions), sorted([path1, path2, path3])) B1 = complexes['B1'] B1_2 = complexes['B1_2'] YZ2 = complexes['YZ2'] B2 = complexes['B2'] B2_1 = complexes['B2_1'] Y2 = complexes['Y2'] Z2 = complexes['Z2'] enum = Enumerator([B1, B2]) enum.k_fast = 0 enum.k_slow = 0 enum.max_helix = True enum.enumerate() path1 = PepperReaction([B1], sorted([B1_2, YZ2]), 'branch-3way') path2 = PepperReaction([B2], sorted([B2_1, Y2]), 'branch-3way') path3 = PepperReaction([B2_1], sorted([B1_2, Z2]), 'branch-3way') self.assertEqual(sorted(enum.reactions), sorted([path1, path2, path3])) C = complexes['C'] enum = Enumerator([C]) enum.k_fast = 0 enum.k_slow = 0 enum.max_helix = True enum.enumerate() self.assertEqual(len(list(enum.reactions)), 2)
def test_sarma_fig4_v1(self): complexes, reactions = read_pil(""" # File generated by peppercorn-v0.5.0 # Domain Specifications length d1 = 15 length d2 = 15 length d3 = 5 length d4 = 15 length d5 = 5 length d6 = 15 length d7 = 5 # Resting-set Complexes bot = d1* com1 = d3*( d2*( d1*( d5 d6 + ) ) ) d4 com2 = d6( d7( + ) ) d5* d1 d2 d3 e6 = d1 d2 d3 d4 e11 = d6 d7 e17 = d7* d6*( d5*( d1( d2( d3( + ) ) ) ) ) e27 = d1*( + ) e29 = d1*( + d6( d7( + ) ) d5* ) d2 d3 e31 = d1*( + ) d2 d3 d4 top = d1 # Transient Complexes e1 = d6( d7( + ) ) d5*( d1 d2 d3 + d1( d2( d3( d4 + ) ) ) ) d6 e7 = d6( d7( + ) ) d5*( d1( d2( d3( + ) ) ) ) d6 e8 = d6 d7( + ) d6*( d5*( d1 d2 d3 + d1( d2( d3( d4 + ) ) ) ) ) e10 = d7* d6*( d5*( d1 d2 d3 + d1( d2( d3( d4 + ) ) ) ) ) e15 = d6 d7( + ) d6*( d5*( d1( d2( d3( + ) ) ) ) ) e33 = d6( d7( + ) ) d5*( d1( d2 d3 + ) + d1( d2( d3( d4 + ) ) ) ) d6 e37 = d6 d7( + ) d6*( d5*( d1( d2 d3 + ) + d1( d2( d3( d4 + ) ) ) ) ) e38 = d6( d7( + ) ) d5*( d1( d2 d3 + d1*( + ) d2( d3( d4 + ) ) ) ) d6 e43 = d6 d7( + ) d6*( d5*( d1( d2 d3 + d1*( + ) d2( d3( d4 + ) ) ) ) ) e47 = d7* d6*( d5*( d1( d2 d3 + d1*( + ) d2( d3( d4 + ) ) ) ) ) e58 = d7* d6*( d5*( d1( d2 d3 + ) + d1( d2( d3( d4 + ) ) ) ) ) # Detailed Reactions reaction [bind21 = 4.5e+06 /M/s ] bot + top -> e27 reaction [bind21 = 1.5e+06 /M/s ] com1 + e29 -> e33 reaction [bind21 = 4.5e+06 /M/s ] com2 + bot -> e29 reaction [bind21 = 1.5e+06 /M/s ] com2 + com1 -> e1 reaction [open = 21.7122 /s ] e1 -> com2 + com1 reaction [branch-3way = 9.52381 /s ] e1 -> e6 + e7 reaction [branch-3way = 22.2222 /s ] e1 -> e8 reaction [bind21 = 4.5e+06 /M/s ] e6 + bot -> e31 reaction [branch-3way = 22.2222 /s ] e7 -> e15 reaction [branch-3way = 22.2222 /s ] e8 -> e1 reaction [branch-3way = 9.52381 /s ] e8 -> e6 + e15 reaction [open = 21.7122 /s ] e8 -> e10 + e11 reaction [branch-3way = 9.52381 /s ] e10 -> e6 + e17 reaction [branch-3way = 22.2222 /s ] e15 -> e7 reaction [open = 21.7122 /s ] e15 -> e17 + e11 reaction [bind21 = 1.5e+06 /M/s ] e17 + e11 -> e15 reaction [open = 21.7122 /s ] e33 -> com1 + e29 reaction [branch-3way = 22.2222 /s ] e33 -> e37 reaction [branch-4way = 0.000623053 /s ] e33 -> e38 reaction [branch-3way = 22.2222 /s ] e37 -> e33 reaction [branch-4way = 0.000623053 /s ] e37 -> e43 reaction [open = 21.7122 /s ] e37 -> e58 + e11 reaction [branch-3way = 16.6667 /s ] e38 -> e7 + e31 reaction [branch-4way = 0.000623053 /s ] e38 -> e33 reaction [branch-3way = 22.2222 /s ] e38 -> e43 reaction [open = 21.7122 /s ] e43 -> e11 + e47 reaction [branch-3way = 16.6667 /s ] e43 -> e15 + e31 reaction [branch-4way = 0.000623053 /s ] e43 -> e37 reaction [branch-3way = 22.2222 /s ] e43 -> e38 reaction [branch-3way = 16.6667 /s ] e47 -> e17 + e31 reaction [branch-4way = 0.000623053 /s ] e47 -> e58 reaction [branch-4way = 0.000623053 /s ] e58 -> e47 """) enum = Enumerator(complexes.values(), reactions) #enum.enumerate() # or enum.dry_run() self.assertEqual(sorted(enum.reactions), sorted(reactions)) enumRG = PepperCondensation(enum) enumRG.condense()
def test_fate_example(self): # TODO: needs more testing, also remove the PREFIX part and replace with # non-auto-prefix complex names... PepperComplex.PREFIX = 'enum' complexes, reactions = read_pil(""" # File generated by peppercorn-v0.5.0 # Domain Specifications length a = 8 length b = 8 length c = 8 length d2 = 8 length d3 = 8 length t = 4 # Resting-set Complexes e0 = d2( d3( + ) a* + a*( b*( c ) ) ) t* e12 = d2 d3( + ) a* e13 = t( d2( d3 + a*( b*( c ) ) ) ) e21 = d2 d3 e22 = t( d2( d3( + ) a*( + a* b*( c ) ) ) ) e27 = t( d2( d3( + ) a* + a*( b*( c ) ) ) ) gate = d2( d3( + ) a*( + a* b*( c ) ) ) t* t23 = t d2 d3 # Transient Complexes e5 = t( d2 d3 + d2( d3( + ) a*( + a* b*( c ) ) ) ) e7 = t( d2 d3 + d2( d3( + ) a* + a*( b*( c ) ) ) ) e18 = t( d2( d3 + d2 d3( + ) a*( + a* b*( c ) ) ) ) # Detailed Reactions reaction [bind21 = 1.2e+06 /M/s ] e0 + t23 -> e7 reaction [branch-3way = 0.122307 /s ] e0 -> gate reaction [branch-3way = 41.6667 /s ] e5 -> e7 reaction [branch-3way = 41.6667 /s ] e5 -> e18 reaction [open = 306.345 /s ] e5 -> t23 + gate reaction [open = 306.345 /s ] e7 -> e0 + t23 reaction [branch-3way = 0.122307 /s ] e7 -> e5 reaction [branch-3way = 41.6667 /s ] e7 -> e12 + e13 reaction [branch-3way = 0.122307 /s ] e18 -> e5 reaction [branch-3way = 41.6667 /s ] e18 -> e12 + e13 reaction [branch-3way = 0.122307 /s ] e18 -> e22 + e21 reaction [branch-3way = 41.6667 /s ] e22 -> e27 reaction [branch-3way = 0.122307 /s ] e27 -> e22 reaction [branch-3way = 41.6667 /s ] gate -> e0 reaction [bind21 = 1.2e+06 /M/s ] t23 + gate -> e5 """) gate = complexes['gate'] t23 = complexes['t23'] enum = Enumerator(complexes.values()) enum.enumerate() # or enum.dry_run() self.assertEqual(sorted(enum.reactions), sorted(reactions)) """ # Resting sets state re0 = [e0, gate] state re12 = [e12] state re13 = [e13] state re21 = [e21] state re22 = [e22, e27] state rt23 = [t23] reaction [condensed = 287342 /M/s ] re0 + rt23 -> re13 + re12 reaction [condensed = 2.45499 /M/s ] re0 + rt23 -> re21 + re22 """ enumRG = PepperCondensation(enum) enumRG.condense() self.assertEqual(len(enumRG.resting_sets), 6) self.assertEqual(len(enumRG.condensed_reactions), 2) PepperComplex.PREFIX = 'e'
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)
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)
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)
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')