def test_combinatorial_DNAconstruct_in_Mixtures(): #Tests the construct [Promoter, Terminator] in many different mixtures try: for mclass, args in mixture_classes: #create the Mixture with parameters args["parameters"] = dict(parameters) m = mclass(**args) #Promoters and terminators are instances for p in promoters: for t in terminators: construct = DNA_construct([p, t]) m.add_component(construct) #Get the construct out of the Mixture construct = m.get_component(construct) crn = m.compile_crn() inputs, outputs = all_reaction_inputs_and_outputs(crn) #the DNA construct should be the input of a reaction assert construct.get_species() in inputs #the DNA_construct's promoter should produce a transcript assert construct[0].transcript in outputs except Exception as e: error_txt = f"Combinatorial compilation failed when DNA_constrct parts list was {[p, t]} in mixture {m}. \n Unexpected Error: {str(e)}" raise Exception(error_txt)
def test_promoter_terminator_DNAconstruct(): P = Promoter("pconst") #constitutive promoter T = Terminator("term") parameters = { "cooperativity": 2, "kb": 100, "ku": 10, "ktx": .05, "ktl": .2, "kdeg": 2, "kint": .05 } mechs = { "transcription": Transcription_MM(Species("RNAP", material_type="protein")) } #minimal RNA transcription x = DNA_construct([P, T], mechanisms=mechs, parameters=parameters) y = x.enumerate_components() assert (y[0] == x[0]) #correct promoter is returned assert ( x[0].transcript == y[1].get_species() ) #promoter in the DNA_construct has the correct transcript species assert (y[1].promoter == x[0] ) #rna is linked back to the DNA_construct's promoter assert (y[1].promoter == y[0] ) #correct promoter is returned by enumerate_constructs #"incoherent" transcription x = DNA_construct([[P, "reverse"], T], mechanisms=mechs, parameters=parameters) y = x.enumerate_components() assert (y == [x[0]]) #correct promoter is returned #transcription in reverse works as well x = DNA_construct([T, [P, "reverse"]], mechanisms=mechs, parameters=parameters) y = x.enumerate_components() assert (y[0] == x[1]) #correct promoter is returned assert ( x[1].transcript == y[1].get_species() ) #promoter in the DNA_construct has the correct transcript species assert (y[1].promoter == x[1] ) #rna is linked back to the DNA_construct's promoter assert (y[1].promoter == y[0] ) #correct promoter is returned by enumerate_constructs
def test_promoter_DNAconstruct(): P = Promoter("pconst") #constitutive promoter parameters = { "cooperativity": 2, "kb": 100, "ku": 10, "ktx": .05, "ktl": .2, "kdeg": 2, "kint": .05 } mechs = { "transcription": Transcription_MM(Species("RNAP", material_type="protein")) } x = DNA_construct([P], mechanisms=mechs, parameters=parameters) assert (not (P in x.parts_list)) #make sure P is copied assert (P in x) #testing "contains" function of Construct y = x.enumerate_components() assert ([x[0]] == y) assert (x[0].transcript is None) #works in reverse as well x = DNA_construct([[P, "reverse"]], mechanisms=mechs, parameters=parameters) assert (not (P in x.parts_list)) #make sure P is copied assert (P in x) #testing "contains" function of Construct y = x.enumerate_components() assert ([x[0]] == y) assert (x[0].transcript is None)
def test_combinatorial_enumeration_DNAconstruct(): P = Promoter("pconst") #constitutive promoter T = Terminator("term") parameters = { "cooperativity": 2, "kb": 100, "ku": 10, "ktx": .05, "ktl": .2, "kdeg": 2, "kint": .05 } mechs = { "transcription": Transcription_MM(Species("RNAP", material_type="protein")) } #circular construct x = DNA_construct([P, P, T], mechanisms=mechs, parameters=parameters, circular=True) y = x.combinatorial_enumeration() prom_positions = [] dna_species = {} for prom_comp in y: if (prom_comp.position not in dna_species): dna_species[prom_comp.position] = [prom_comp.dna_to_bind.parent] else: dna_species[prom_comp.position] += [prom_comp.dna_to_bind.parent] p1_bound = Complex( [x.get_species()[0], Species("RNAP", material_type="protein")]).parent p2_bound = Complex( [x.get_species()[1], Species("RNAP", material_type="protein")]).parent both_bound = Complex( [p1_bound[1], Species("RNAP", material_type="protein")]).parent assert (x.get_species() in dna_species[0] ) #unbound polymer found in combinatorial enumeration assert (p2_bound in dna_species[0] ) #proper bound polymer found in combinatorial enumeration assert (x.get_species() in dna_species[1] ) #unbound polymer found in combinatorial enumeration assert (p1_bound in dna_species[1] ) #proper bound polymer found in combinatorial enumeration assert ( both_bound not in dna_species[0] ) #dna with both promoters bound is not in combinatorial enumeration assert ( both_bound not in dna_species[1] ) #dna with both promoters bound is not in combinatorial enumeration assert (len(y) == 4)
def test_polymer_transformation(): prom = Promoter("p1") utr = RBS("utr") cds = CDS("GFP") cds2 = CDS("RFP") term = Terminator("t16") construct = DNA_construct([prom, utr, cds, term]) construct2 = DNA_construct([cds2]) dummy = Polymer_transformation.dummify(construct, "input1") assert (dummy.name == "input1") #dummy polymer has the right name assert (len(dummy.polymer) == len(construct) ) #dummy polymer has the right length assert ([a.direction for a in dummy] == [a.direction for a in construct] ) #dummy polymer monomers have the right direction assert ([a.position for a in dummy] == [a.position for a in construct] ) #dummy polymer monomers have the right position assert (isinstance(dummy, NamedPolymer) ) #make sure the output of dummify has the right type assert (isinstance(dummy, OrderedPolymer) ) #make sure the output of dummify has the right type dummy2 = Polymer_transformation.dummify(construct, "input2") transformation = Polymer_transformation( [dummy[0], [prom, "forward"], dummy2[0]], circular=True) assert (transformation.circular == True ) #make sure circular is set properly assert (len(transformation.parentsdict) == 2) #two parents! assert (transformation.create_polymer( [construct, construct2]) == DNA_construct([prom, prom, cds2], circular=True) ) #transformations are performed correctly assert (transformation.create_polymer( [construct2, construct]) == DNA_construct([cds2, prom, prom], circular=True)) assert ("(input1-0)(p1)(input2-0)" in str(transformation)) #contains vital information in the repr
def test_integrase_rule(): prom = Promoter("p1") utr = RBS("utr") cds = CDS("GFP") cds2 = CDS("RFP") term = Terminator("t16") ap = IntegraseSite("attP", "attP") ab = IntegraseSite("attB", "attB") aflp = IntegraseSite("FLP", "FLP") delete = DNA_construct([ab, cds, ap]) flip = DNA_construct([ab, cds, [ap, "reverse"]]) plasp = DNA_construct([cds, ap], circular=True) plasb = DNA_construct([cds, ab], circular=True) genp = DNA_construct([cds2, ap]) genb = DNA_construct([cds2, ab]) bxb1_rule = IntegraseRule(name="Bxb1", reactions={ ("attB", "attP"): "attL", ("attP", "attB"): "attR" }) assert (set(["attP", "attB", "attL", "attR"]) == set(bxb1_rule.attsites)) assert (set(["attP", "attB", "attL", "attR"]) == set(bxb1_rule.binds_to())) assert (bxb1_rule.integrase_species == Species("Bxb1", material_type="protein")) bxb1_enumerator = Integrase_Enumerator("Bxb1", int_mechanisms={"Bxb1": bxb1_rule}) flp_rule = IntegraseRule(name="FLP", reactions={("FLP", "FLP"): "FLP"}) bad_rule = IntegraseRule(name="Bxb1", reactions={("attB", "attP"): "attL"}) with pytest.raises(AssertionError): bxb1_rule.generate_products(delete[0], delete[2]) #must have the right integrase delete[0].update_integrase("Bxb1") delete[2].update_integrase("Bxb1") with pytest.raises(KeyError): bxb1_rule.generate_products(delete[0], delete[0]) #attP+attP is not possible with pytest.raises(KeyError): bad_rule.generate_products( delete[0], delete[2]) #attP->attB reaction is not possible with a bad rule aL = IntegraseSite("attL", "attL", integrase="Bxb1") aL.direction = "forward" aR = IntegraseSite("attR", "attR", integrase="Bxb1") aR.direction = "forward" productsites = bxb1_rule.generate_products(delete[0], delete[2]) testaL = copy.copy(aL) testaL.direction = "forward" testaL.position = 0 testaL.parent = delete testaR = copy.copy(aR) testaR.direction = "forward" testaR.position = 2 testaR.parent = delete assert ( productsites[0] == testaL ) #generated product sites have the right parent, position, and direction assert ( productsites[1] == testaR ) #generated product sites have the right parent, position, and direction ap = IntegraseSite("attP", "attP", integrase="Bxb1") ab = IntegraseSite("attB", "attB", integrase="Bxb1") delete = DNA_construct([ab, cds, ap]) flip = DNA_construct([ab, cds, [ap, "reverse"]], circular=True) flipr = flip.get_reversed() plasp = DNA_construct([cds, ap], circular=True) plasb = DNA_construct([cds, ab], circular=True) genp = DNA_construct([cds2, ap]) genb = DNA_construct([cds2, ab]) #testing the actual integration reactions #inversion new_constructs = bxb1_rule.integrate(flip[0], flip[2], also_inter=False) #sites forwards assert (len(new_constructs) == 1) #one product is made assert ([part.name for part in new_constructs[0]] == ["attL", "GFP", "attR"]) assert ([part.direction for part in new_constructs[0] ] == ["forward", "reverse", "reverse"]) new_constructs = bxb1_rule.integrate(flip[2], flip[0], also_inter=False) #sites reverse assert (len(new_constructs) == 1) #one product is made assert ([part.name for part in new_constructs[0]] == ["attL", "GFP", "attR"]) assert ([part.direction for part in new_constructs[0] ] == ["forward", "reverse", "reverse"]) new_constructs = bxb1_rule.integrate(flipr[2], flipr[0], also_inter=False) #sites forwards assert (len(new_constructs) == 1) #one product is made assert ([part.name for part in new_constructs[0]] == ["attR", "GFP", "attL"]) assert ([part.direction for part in new_constructs[0] ] == ["forward", "forward", "reverse"]) new_constructs = bxb1_rule.integrate( flip[0], flip[2], also_inter=True) #allow intermolecular reactions assert (len(new_constructs) == 2) #now, two products are made assert (sum([a.circular for a in new_constructs]) == 2) #all of them is circular for prod in new_constructs: if (len(prod) == 3): assert ([part.name for part in prod] == ["attL", "GFP", "attR"]) assert ([part.direction for part in prod] == ["forward", "reverse", "reverse"]) else: assert ([part.name for part in prod ] == ['attL', 'GFP', 'attB', 'attR', 'GFP', 'attP']) assert ([part.direction for part in prod] == [ "forward", "reverse", "reverse", "forward", "forward", "reverse" ]) #deletion new_constructs = bxb1_rule.integrate(delete[0], delete[2], also_inter=False) #sites forwards assert (len(new_constructs) == 2) #two product is made assert (sum([a.circular for a in new_constructs]) == 1) #one of them is circular for prod in new_constructs: if (prod.circular): assert ([part.name for part in prod] == ["attR", "GFP"]) assert ([part.direction for part in prod] == ["forward", "forward"]) else: assert ([part.name for part in prod] == ["attL"]) assert ([part.direction for part in prod] == ["forward"]) #now, what if we also calculate the intermolecular reactions? new_constructs = bxb1_rule.integrate(delete[2], delete[0], also_inter=True) #sites reverse assert (len(new_constructs) == 3) #four product is made assert (sum([a.circular for a in new_constructs]) == 1) #one of them is circular for prod in new_constructs: if (prod.circular): if (len(prod) == 2): print(prod) assert ([part.name for part in prod] == ["attR", "GFP"]) assert ([part.direction for part in prod] == ["forward", "forward"]) elif (len(prod) == 1): assert ([part.name for part in prod] == ["attL"]) assert ([part.direction for part in prod] == ["forward"]) elif (len(prod) == 5): assert ([part.name for part in prod ] == ["attB", "GFP", "attR", "GFP", "attP"]) assert ([part.direction for part in prod] == ["forward"] * 5) #integration new_constructs = bxb1_rule.integrate( plasp[1], plasb[1]) #two plasmids -> one plasmid p then b assert (len(new_constructs) == 1) #one product is made prod = new_constructs[0] assert ([part.name for part in prod] == ["GFP", "attR", "GFP", "attL"]) assert ([part.direction for part in prod] == ["forward", "forward", "forward", "forward"]) assert (new_constructs[0].circular) new_constructs = bxb1_rule.integrate( plasb[1], plasp[1]) #two plasmids -> one plasmid b then p assert (len(new_constructs) == 1) #one product is made prod = new_constructs[0] assert ([part.name for part in prod] == ["GFP", "attL", "GFP", "attR"]) assert ([part.direction for part in prod] == ["forward", "forward", "forward", "forward"]) assert (new_constructs[0].circular) bxb1_enumerator.reset([plasb, plasp]) assert (len(plasb[1].linked_sites) == 0 ) #linked sites are nonexistant if it is reset assert (len(plasp[1].linked_sites) == 0 ) #linked sites are nonexistant if it is reset #include result construct result_construct = DNA_construct([cds, aL, cds, aR], circular=True) new_constructs = bxb1_rule.integrate( plasb[1], plasp[1], existing_dna_constructs=[result_construct ]) #two plasmids -> one plasmid b then p assert (len(new_constructs) == 0 ) #no new products are made, only the existing one assert ( (plasp[1], True) in plasb[1].linked_sites) #proper reaction found inside integrase site assert ( (plasb[1], True) in plasp[1].linked_sites) #proper reaction found inside integrase site #including circularly permuted existing construct #reaction is: #[cds,ab] + [cds,ap] =[cds, aL, cds, aR] bxb1_enumerator.reset([plasb, plasp]) permuted_construct = DNA_construct([cds, aR, cds, aL], circular=True) new_constructs = bxb1_rule.integrate( plasb[1], plasp[1], existing_dna_constructs=[permuted_construct ]) #two plasmids -> one plasmid b then p assert (len(new_constructs) == 0 ) #no new products are made, only the existing one assert ( (plasp[1], True) in plasb[1].linked_sites) #proper reaction found inside integrase site assert ( (plasb[1], True) in plasp[1].linked_sites) #proper reaction found inside integrase site bxb1_enumerator.reset([plasb, plasp]) new_constructs = bxb1_rule.integrate(genb[1], plasp[1]) #linear with circular assert (len(new_constructs) == 1) #one product is made prod = new_constructs[0] assert ([part.name for part in prod] == ['RFP', 'attL', 'GFP', 'attR']) assert ([part.direction for part in prod] == ["forward", "forward", "forward", "forward"]) assert (not new_constructs[0].circular) #reverse integration bxb1_enumerator.reset([plasb, plasp]) new_constructs = bxb1_rule.integrate(plasp[1], genb[1]) #circular with linear assert (len(new_constructs) == 1) #one product is made prod = new_constructs[0] assert ([part.name for part in prod] == ['RFP', 'attL', 'GFP', 'attR']) assert ([part.direction for part in prod] == ["forward", "forward", "forward", "forward"]) assert (not new_constructs[0].circular) #recombination bxb1_enumerator.reset([plasb, plasp]) new_constructs = bxb1_rule.integrate(genp[1], genb[1]) #linear with linear assert (len(new_constructs) == 2) #two products assert (sum([a.circular for a in new_constructs]) == 0) #all products are linear for prod in new_constructs: assert ([part.name for part in prod] in [['RFP', 'attL'], ['RFP', 'attR']]) assert ([part.direction for part in prod] == ["forward", "forward"])
def test_compilation(): #Create an infinite polymer system and compile it at different recursion depths pconst = Promoter("pconst") #constitutive promoter gfp = CDS("GFP") rfp = CDS("RFP") t16 = Terminator("t16") #a terminator stops transcription #some parameters are useful also. note the "kint" parameter which determines the rate of recombination parameters = { "cooperativity": 2, "kb": 100, "ku": 10, "ktx": .05, "ktl": .2, "kdeg": 2, "kint": .05 } #here is where we define the integrase attachment sites attP = IntegraseSite( "attP", "attP", integrase="Bxb1" ) #the first argument is the name of this attachment site, the second argument is the type of attachment site it is ("attP", "attB", "attL" or "attR") and the integrase denotes which integrase binds to this site (default is "int1") attB = IntegraseSite( "attB", "attB", integrase="Bxb1" ) #we define two attachment sites, as one site doesn't do anything on its own besides bind integrases #Create an integrase enumerator bxb1_mechanism = IntegraseRule("Bxb1", reactions={ ("attB", "attP"): "attL", ("attP", "attB"): "attR" }) bxb1 = Integrase_Enumerator( "Bxb1", int_mechanisms={"Bxb1": bxb1_mechanism} ) #we must also define an integrase enumerator. The default integrase is always "int1", but here we are specifying "Bxb1" as the integrase. The Integrase enumerator gets a name, and the mechanism we defined above. #create DNA_constructs with integrase sites plasmid1_construct = DNA_construct([t16, attP, attB, gfp], circular=True) genome_construct = DNA_construct([pconst, attB, rfp]) #Create a Mixture myMixture = TxTlExtract(name="txtl", parameters=parameters, components=[plasmid1_construct, genome_construct], global_component_enumerators=[bxb1]) #Test Recursion Depth = 0 #Note compile directives are used to speed up the test myCRN0, comps0 = myMixture.compile_crn(recursion_depth=0, return_enumerated_components=True, initial_concentrations_at_end=True, copy_objects=False, add_reaction_species=False) assert len(comps0) == 14 assert len(myCRN0.species) == 14 assert len(myCRN0.reactions) == 12 #Test recursion depth = 1 myCRN1, comps1 = myMixture.compile_crn(recursion_depth=1, return_enumerated_components=True, initial_concentrations_at_end=True, copy_objects=False, add_reaction_species=False) assert len(comps1) == 85 assert len(myCRN1.species) == 52 assert len(myCRN1.reactions) == 97 #Recompiling at a different length doesn't change anything myCRN0b, comps0b = myMixture.compile_crn( recursion_depth=0, return_enumerated_components=True, initial_concentrations_at_end=True, copy_objects=False, add_reaction_species=False) assert len(comps0) == len(comps0b) assert myCRN0.species == myCRN0b.species assert all([r in myCRN0.reactions for r in myCRN0b.reactions]) and all( [r in myCRN0b.reactions for r in myCRN0.reactions])
def test_integrase_enumerator(): cds = CDS("GFP") cds2 = CDS("RFP") ap = IntegraseSite("attP", "attP", integrase="Bxb1") ab = IntegraseSite("attB", "attB", integrase="Bxb1") al = IntegraseSite("attL", "attL", integrase="Bxb1") ar = IntegraseSite("attR", "attR", integrase="Bxb1") flip = DNA_construct([ab, cds, [ap, "reverse"]]) plasp = DNA_construct([cds, ap], circular=True) plasb = DNA_construct([cds, ab], circular=True) genp = DNA_construct([cds2, ap]) genb = DNA_construct([cds2, ab]) bxb1_rule = IntegraseRule(name="Bxb1", reactions={ ("attB", "attP"): "attL", ("attP", "attB"): "attR" }) bxb1_enumerator = Integrase_Enumerator("Bxb1", int_mechanisms={"Bxb1": bxb1_rule}) int_dict = bxb1_enumerator.list_integrase(flip) assert ("Bxb1" in int_dict) #the correct integrase is listed assert (flip[0] in int_dict["Bxb1"]) #both sites are found in the dictionary assert (flip[2] in int_dict["Bxb1"]) #both sites are found in the dictionary x = bxb1_rule.integrate(flip[0], flip[2]) assert ((flip[2], False) in flip[0].linked_sites) #sites are properly integrated bxb1_enumerator.reset([flip]) assert (len(flip[0].linked_sites) == 0) assert (len(flip[2].linked_sites) == 0) permuted_plasp = DNA_construct([ap, cds], circular=True) assert (plasp != permuted_plasp) #normal equality doesn't cut it found, perm_func = bxb1_enumerator.find_dna_construct(plasp, [plasp]) assert ([perm_func(a) for a in range(len(plasp))] == [ (lambda a: (a, "f"))(a) for a in range(len(plasp)) ]) #1:1 find matching assert (found == plasp) #found the same construct we put in found, perm_func = bxb1_enumerator.find_dna_construct( plasp, [permuted_plasp]) assert ([perm_func(a) for a in range(len(plasp))] == [(1, "f"), (0, "f")]) #find permuted mapping assert (found == permuted_plasp) #found the same construct we put in assert (bxb1_enumerator.find_dna_construct(plasp, [plasb]) is None ) #we don't find anything reversed_plasp = DNA_construct([(ap, "reverse"), (cds, "reverse")], circular=True) reversed_permuted_plasp = DNA_construct([(cds, "reverse"), (ap, "reverse")], circular=True) found, perm_func = bxb1_enumerator.find_dna_construct( plasp, [reversed_plasp]) assert (found == reversed_plasp) #found the same construct we put in assert ([perm_func(a) for a in range(len(plasp))] == [(1, "r"), (0, "r")]) #find permuted mapping found, perm_func = bxb1_enumerator.find_dna_construct( plasp, [reversed_permuted_plasp]) assert (found == reversed_permuted_plasp ) #found the same construct we put in assert ([perm_func(a) for a in range(len(plasp))] == [(0, "r"), (1, "r")]) #find permuted mapping reversed_genp = DNA_construct([(ap, "reverse"), (cds2, "reverse")]) found, perm_func = bxb1_enumerator.find_dna_construct( genp, [reversed_genp]) assert (found == reversed_genp) #found the same construct we put in assert ([perm_func(a) for a in range(len(genp))] == [(1, "r"), (0, "r")]) #find permuted mapping plaspb = DNA_construct([cds, ar, cds, al], circular=True) x = bxb1_enumerator.enumerate_components([plasp, plasb]) assert (plaspb in x) #the proper construct is made y = bxb1_enumerator.enumerate_components([plasp, plasb], previously_enumerated=[plaspb]) assert ( y == [] ) #nothing new is made since the proper construct has been "previously enumerated" plaspb = DNA_construct([ar, cds, al, cds, ar, cds, ar, cds], circular=True) for i in range(1, len(plaspb)): #test all circular permutations of this repetitive plasmid. They should all yield the same hash! plasperm = plaspb.get_circularly_permuted(i) h1 = DNA_construct.omnihash(plaspb) h2 = DNA_construct.omnihash(plasperm) assert (h1[0] == h2[0])
def test_get_part_DNAconstruct(): P = Promoter("pconst") U = RBS("utr1") C = CDS("coolprot1") T = Terminator("T11") T2 = Terminator("iamsoterminator") parameters = { "cooperativity": 2, "kb": 100, "ku": 10, "ktx": .05, "ktl": .2, "kdeg": 2, "kint": .05 } mechs = { "transcription": Transcription_MM(Species("RNAP", material_type="protein")) } x = DNA_construct([P, U, C, T, T2], mechanisms=mechs, parameters=parameters) with pytest.raises( ValueError, match= r"get_component requires a single keyword. Recieved component=None, name=None, index=None." ): y = x.get_part() with pytest.raises(ValueError): y = x.get_part(part=P, index=3) with pytest.raises(ValueError): y = x.get_part(part="oogabooga") with pytest.raises(ValueError): y = x.get_part(part_type="oogabooga") with pytest.raises(ValueError): y = x.get_part(name=5) with pytest.raises(ValueError): y = x.get_part(index="oogabooga") assert (x.get_part(part_type=Promoter) == x[0]) assert (x.get_part(name="pconst") == x[0]) assert (x.get_part(index=2) == x[2]) assert (x.get_part(part=P) == x[0]) assert (len(x.get_part(part_type=Terminator)) == 2)
def test_circular_DNAconstruct(): P = Promoter("pconst") #constitutive promoter T = Terminator("term") parameters = { "cooperativity": 2, "kb": 100, "ku": 10, "ktx": .05, "ktl": .2, "kdeg": 2, "kint": .05 } mechs = { "transcription": Transcription_MM(Species("RNAP", material_type="protein")) } #circular construct x = DNA_construct([P, T], mechanisms=mechs, parameters=parameters, circular=True) y = x.enumerate_components() assert (y[0] == x[0]) #correct promoter is returned assert ( x[0].transcript == y[1].get_species() ) #promoter in the DNA_construct has the correct transcript species assert (y[1].promoter == x[0] ) #rna is linked back to the DNA_construct's promoter assert (y[1].promoter == y[0] ) #correct promoter is returned by enumerate_constructs x = DNA_construct([[P, "reverse"], T], mechanisms=mechs, parameters=parameters, circular=True) y = x.enumerate_components() assert (y[0] == x[0]) #correct promoter is returned assert ( x[0].transcript == y[1].get_species() ) #promoter in the DNA_construct has the correct transcript species assert (y[1].promoter == x[0] ) #rna is linked back to the DNA_construct's promoter assert (y[1].promoter == y[0] ) #correct promoter is returned by enumerate_constructs x = DNA_construct([ [P, "reverse"], [T, "reverse"], ], mechanisms=mechs, parameters=parameters, circular=True) y = x.enumerate_components() z = DNA_construct([T, P], mechanisms=mechs, parameters=parameters, circular=True) e = z.enumerate_components() assert (y[1] == e[1] ) #different DNA constructs lead to the same RNA construct assert (y[0] == x[0]) #correct promoter is working assert (e[0] == z[1]) #correct promoter is working
def test_CRNPlotter(): class dummy_renderer: class dummy_parts: def __init__(self): pass def __init__(self, scale=1, linewidth=2): self.linecolor = (0, 0, 0) pass def SBOL_part_renderers(self): return self.dummy_parts() def std_reg_renderers(self): return self.dummy_parts() def renderDNA(self, ax, designs, renderers, **keywords): ax.plot([0], [1]) return (0, 100) d_r = dummy_renderer() test_plotter = CRNPlotter(dna_renderer=dummy_renderer(), rna_renderer=dummy_renderer(), cmap=[0, 1, 2, 3, 4, 5, 6]) test_construct = DNA_construct( [Promoter("p1"), IntegraseSite("attP", "attP"), Terminator("t1")]) test_construct2 = DNA_construct( [RBS("utr1"), IntegraseSite("attB", "attB"), Terminator("t1")]) test_construct3 = DNA_construct([ IntegraseSite("attL", "attL"), IntegraseSite("attR", "attR"), CDS("o1") ]) ts1 = test_construct.get_species() test_species = Complex( [ts1[1], Species("integrase", material_type="protein")]).parent assert (test_plotter.part_dpl_dict == {}) assert (test_plotter.construct_dpl_dict == {}) assert (test_plotter.species_dpl_dict == {}) assert (test_plotter.species_image_dict == {}) test_plotter.make_dpls_from_construct(test_construct) assert (len(test_plotter.part_dpl_dict) == len(test_construct) ) #new parts are added to the dictionary assert (len(test_plotter.construct_dpl_dict) == 1 ) #the new construct is added #part added to part dict assert (test_plotter.part_dpl_dict[Promoter("p1")].get_dpl()[0]['type'] == "Promoter") #construct added to construct dict condpl = test_plotter.construct_dpl_dict[test_construct].get_dpl() #test that everything has the right type assert (condpl[0]['type'] == "Promoter") assert (condpl[1]['type'] == "RecombinaseSite") assert (condpl[2]['type'] == "Terminator") test_plotter.make_dpls_from_construct(test_construct2) assert (len(test_plotter.part_dpl_dict) == len(test_construct) + len(test_construct2) - 1) #new parts from the new construct are added but the terminator is the same so don't add that one assert (len(test_plotter.construct_dpl_dict) == 2 ) #now there are two constructs test_plotter.make_dpls_from_construct(test_construct3) #almost all new parts are added assert (len(test_plotter.part_dpl_dict) == len(test_construct) + len(test_construct2) + len(test_construct3) - 1) assert (len(test_plotter.construct_dpl_dict) == 3 ) #there are now 3 constructs! test_plotter.make_dpl_from_species( test_species) #making dpl from single species test_plotter.make_dpl_from_species( Species("integrase", material_type="protein")) assert (Species("integrase", material_type="protein") in test_plotter.species_dpl_dict) test_plotter.make_dpl_from_part( RegulatedPromoter("p1", regulators=["r1", "r2"])) assert (RegulatedPromoter("p1", regulators=["r1", "r2"]) in test_plotter.part_dpl_dict) #make a multipart promoter #normal promoter is a multipart with a promoter being first assert (test_plotter.part_dpl_dict[RegulatedPromoter( "p1", regulators=["r1", "r2"])].get_dpl()[0]["type"] == "Promoter") #try returning a reverse version of the same thing boundspec = test_plotter.make_dpl_from_species( Species("ooga", material_type="booga") ) #make a species to be bound to the promoter revpart = test_plotter.part_dpl_dict[RegulatedPromoter( "p1", regulators=["r1", "r2"])].get_directed( "reverse", bound=[boundspec]) #return reverse promoter with things bound assert (revpart.get_dpl()[0]["type"] == "Operator" ) #reverse promoter has operators on the left test_plotter.colordict = {"Promoter": "purple"} prom_dpl = test_plotter.make_dpl_from_part( Promoter("pconst")) #make a promoter part assert (prom_dpl.color == "purple") #found the proper color prom_dpl2 = test_plotter.make_dpl_from_part( Promoter("funkbeast")) #make a different promoter part assert (prom_dpl2.color == "purple") rnadpl = test_plotter.make_dpl_from_species( Species("testrna", material_type="rna")) assert (rnadpl.dpl_type == "NCRNA") #something is bound to the operator closest to the reversed promoter assert (revpart.parts_list[1].bound is not None) #construct having a multi-part promoter and a "user defined" part test_construct4 = DNA_construct( [RegulatedPromoter("p1", regulators=["r1", "r2"]), DNA_part("test")]) test_plotter.make_dpl_from_species(test_construct4.get_species()) assert (test_construct4.get_species() in test_plotter.species_dpl_dict) #construct is in the dictionary rna_construct = RNA_construct([RBS("ooga"), CDS("booga")]) condpl1 = test_plotter.make_dpls_from_construct(rna_construct) assert (condpl1.material_type == "rna") #material type is set correctly rna_construct2 = RNA_construct([RBS("ooga"), CDS("booga")]) condpl2 = test_plotter.make_dpls_from_construct(rna_construct2) assert (condpl2 == condpl1 ) #this construct is already in the dictionary! Just return it bound_construct = Complex([ test_construct4.get_species()[1], Species("integrase", material_type="protein") ]).parent #making a construct that is bound to something dpl_binders = test_plotter.make_dpl_from_species( bound_construct).get_dpl_binders() #return the things that are bound assert (dpl_binders[0][0]["type"] == "Binding") test_plotter.make_dpl_from_species( Complex([ Species("mydna", material_type="dna"), Species("integrase", material_type="protein") ])) #dpl made from a complex #make sure the part inside the construct made it into the species dict assert (Species("mydna", material_type="dna") in test_plotter.species_dpl_dict)
def test_combinatorial_DNAconstruct_RNAconstruct(): P = Promoter("pconst") #constitutive promoter U = RBS("rbs") C = CDS("gfp") T = Terminator("term") correct_order_list = [P, U, C, T] directions_list = ["forward", "reverse"] index_list = range(4) parameters = { "cooperativity": 2, "kb": 100, "ku": 10, "ktx": .05, "ktl": .2, "kdeg": 2, "kint": .05 } mechs = { "transcription": Transcription_MM(Species("RNAP", material_type="protein")), "translation": Translation_MM(Species("Ribo")) } iter_list = [] for order in permutations(correct_order_list): for i in range(4): for direction in directions_list: new_order = list(order) new_order[i] = [order[i], direction] iter_list += [new_order] try: for combination in iter_list: x = DNA_construct(combination, mechanisms=mechs, parameters=parameters) print(x) y = x.enumerate_components() z = [] #promoter at the beginning facing reverse doesn't make a transcript if ((isinstance(x[0], Promoter) and x[0].direction == "reverse")): assert (y == [x[0]]) #promoter at the end facing forward doesn't make a transcript elif ((isinstance(x[-1], Promoter) and x[-1].direction == "forward")): assert (y == [x[-1]]) #everything else should make one transcript else: assert (isinstance(y[1], RNA_construct)) for element in y: #find the RNA if (isinstance(element, RNA_construct)): rna_enumeration = element.enumerate_components() #reverse RBS does not function in RNA if any([ p.direction == 'reverse' for p in element if isinstance(p, RBS) ]): assert (len(rna_enumeration) == 0) elif (U in element): #if there is an RBS and it is not reverse, then it should be active assert (len(rna_enumeration) >= 1) else: #if there is no RBS in the RNA then the RNA cannot do anything assert (len(rna_enumeration) == 0) if (len(rna_enumeration) == 2): #if two things are returned, that means that a protein is made, and #this is only possible if there is an RBS and CDS in the forward #orientation assert (any([ p.direction == 'forward' for p in element if isinstance(p, RBS) ])) assert (any([ p.direction == 'forward' for p in element if isinstance(p, CDS) ])) except Exception as e: error_txt = f"Combinatorial enumerate_components failed when parts list was {combination}. \n Unexpected Error: {str(e)}" raise Exception(error_txt)