Exemplo n.º 1
0
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_update_species(self):
        from biocrnpyler import CombinatorialPromoter, Protein, Species, Combinatorial_Cooperative_Binding, \
                                    DNAassembly,Transcription_MM, Translation_MM, Multimer, ComplexSpecies
        #make a complicated promoter
        newprom = CombinatorialPromoter("testprom",["treg1",Species("treg2",material_type="rna")],\
                                tx_capable_list = [["treg1","treg2"]],cooperativity={"testprom_treg2":1},leak=True)

        newdna = DNAassembly("testDNA", promoter=newprom)
        newdna.update_mechanisms(mechanisms={
            "transcription": Transcription_MM(),
            "translation": Translation_MM()
        })
        newdna.update_parameters(
            parameters={
                "cooperativity": 2,
                "kb": 100,
                "ku": 10,
                "ktx": .05,
                "ktl": .2,
                "kdeg": 2
            })
        newprom_spec = newprom.update_species()

        sp_treg1 = Species("treg1", material_type="protein")
        sp_treg2 = Species("treg2", material_type="rna")
        #mu_treg2 = Multimer(sp_treg2,2)

        sp_dna = Species("testDNA", material_type="dna")
        sp_rnap = Species("RNAP", material_type="protein")
        sp_rna = Species("testDNA", material_type="rna")
        cp_dna_rnap = ComplexSpecies([sp_dna, sp_rnap])
        cp_dna_treg1 = ComplexSpecies([sp_dna, sp_treg1, sp_treg1])
        cp_dna_treg2 = ComplexSpecies([sp_dna, sp_treg2])
        cp_dna_treg1_rnap = ComplexSpecies([cp_dna_treg1, sp_rnap])
        cp_dna_treg2_rnap = ComplexSpecies([cp_dna_treg2, sp_rnap])
        cp_dna_treg1_treg2 = ComplexSpecies(
            [sp_dna, sp_treg1, sp_treg1, sp_treg2])
        cp_dna_treg1_treg2_rnap = ComplexSpecies([cp_dna_treg1_treg2, sp_rnap])

        knownspecies = [sp_dna,sp_rnap,sp_rna,cp_dna_rnap,cp_dna_treg1,\
                            cp_dna_treg2,cp_dna_treg1_treg2,cp_dna_treg1_rnap, \
                                cp_dna_treg2_rnap,cp_dna_treg1_treg2_rnap]

        #these are the species that should come out
        test_set = set([str(a) for a in newprom_spec])
        mistake_found = False
        #we should have the correct length of species
        self.assertTrue(len(test_set) == len(knownspecies))
        for known_spec in knownspecies:
            #go through and check each species if it's in the set generated by the promoter
            if (str(known_spec) not in test_set):
                print("couldn't find " + str(known_spec))
                mistake_found = True
                break
        self.assertTrue(not mistake_found)
Exemplo n.º 3
0
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_update_species(self):
        from biocrnpyler import CombinatorialPromoter, Protein, Species, Combinatorial_Cooperative_Binding, \
                                    DNAassembly,Transcription_MM, Translation_MM, Complex
        #make a complicated promoter
        newprom = CombinatorialPromoter("testprom",["treg1",Species("treg2",material_type="rna")],\
                                tx_capable_list = [["treg1","treg2"]],cooperativity={"testprom_treg2":1},leak=True)

        sp_rnap = Species("RNAP",material_type="protein")
        ribosome = Species("Ribo", material_type = "protein")

        newdna = DNAassembly("testDNA",promoter=newprom)
        newdna.add_mechanisms({"transcription":Transcription_MM(rnap = sp_rnap), "translation":Translation_MM(ribosome = ribosome)})
        newdna.update_parameters(parameters={"cooperativity":2,"kb":100, "ku":10, "ktx":.05, "ktl":.2, "kdeg":2})

        #Promoters are copied when added to DNAassemblies
        newprom_copy = newdna.promoter
        newprom_spec = newprom_copy.update_species()

        sp_treg1 = Species("treg1",material_type="protein")
        sp_treg2 = Species("treg2",material_type="rna")

        sp_dna = Species("testDNA",material_type="dna")
        
        sp_rna = Species("testDNA",material_type="rna")
        cp_dna_rnap = Complex([sp_dna,sp_rnap])
        cp_dna_treg1 = Complex([sp_dna,sp_treg1,sp_treg1])
        cp_dna_treg2 = Complex([sp_dna,sp_treg2])
        cp_dna_treg1_rnap = Complex([cp_dna_treg1,sp_rnap])
        cp_dna_treg2_rnap = Complex([cp_dna_treg2,sp_rnap])
        cp_dna_treg1_treg2 = Complex([sp_dna,sp_treg1,sp_treg1,sp_treg2])
        cp_dna_treg1_treg2_rnap = Complex([cp_dna_treg1_treg2,sp_rnap])

        knownspecies = [sp_dna,sp_rnap,sp_rna,cp_dna_rnap,cp_dna_treg1,\
                            cp_dna_treg2,cp_dna_treg1_treg2,cp_dna_treg1_rnap, \
                                cp_dna_treg2_rnap,cp_dna_treg1_treg2_rnap,sp_treg1,sp_treg2]

        #these are the species that should come out
        test_set = set([str(a) for a in newprom_spec])

        mistake_found = False
        error_txt = ""
        for known_spec in knownspecies:
            #go through and check each species if it's in the set generated by the promoter
            if(str(known_spec) not in test_set):
                error_txt += "\ncouldn't find "+str(known_spec)
                mistake_found = True
        
        if mistake_found:
            raise ValueError(f"Mistake found in Species output:{error_txt}. Returned Species: {test_set}.")
        #we should have the correct length of species
        self.assertTrue(len(test_set)==len(knownspecies))
        self.assertTrue(not mistake_found)
Exemplo n.º 5
0
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
Exemplo n.º 6
0
    def test_update_mechanisms(self):

        tx = Transcription_MM()
        tl = Translation_MM()
        deg = Degredation_mRNA_MM()

        test_mech = {tx.mechanism_type: tx, tl.mechanism_type: tl}

        default_test_mech = {deg.mechanism_type: deg}

        # test that component has no mechanism
        self.assertTrue(
            isinstance(self.component.mechanisms, dict)
            and len(self.component.mechanisms) == 0)
        self.component.update_mechanisms(mixture_mechanisms=test_mech)
        # test that the test_mech is registered as the only mechanism
        self.assertEqual(self.component.mechanisms, test_mech)

        self.component.default_mechanisms = default_test_mech
        self.component.update_mechanisms(mixture_mechanisms=test_mech)
        test_mech.update(default_test_mech)
        self.assertEqual(self.component.mechanisms, test_mech)

        # testing that the custom mechanism gets updated
        self.assertTrue(
            isinstance(self.component.custom_mechanisms, dict)
            and len(self.component.custom_mechanisms) == 0)
        self.component.update_mechanisms(mechanisms=test_mech)
        self.assertEqual(self.component.custom_mechanisms, test_mech)

        # testing that custom mechanism is protected by the overwrite_custom_mechanisms=False flag
        self.component.update_mechanisms(mechanisms=default_test_mech,
                                         overwrite_custom_mechanisms=False)
        self.assertEqual(self.component.custom_mechanisms, test_mech)

        # multiple mechanisms can be supplied with a list
        test_mech_list = list(test_mech.values())
        self.component.update_mechanisms(mechanisms=test_mech_list)
        self.assertEqual(self.component.custom_mechanisms, test_mech)

        # testing an invalid mechanism format
        with self.assertRaisesRegexp(
                ValueError,
                'Mechanisms must be passed as a list of instantiated objects or a '
                'dictionary {mechanism_type:mechanism instance}'):
            self.component.update_mechanisms(mechanisms=(tx, tl))
Exemplo n.º 7
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)
Exemplo n.º 8
0
    def test_get_parameter(self):

        # testing an invalid parameter
        with self.assertRaisesRegexp(
                ValueError, 'No parameters can be found that match the'):
            self.component.get_parameter(param_name='kb')

        # Create Param Dict
        kb, ku, ktx, ktl, kdeg, cooperativity = 100, 10, 3, 2, 1, 1
        p_id = 'p10'

        parameters = {
            "kb": kb,
            "ku": ku,
            "ktx": ktx,
            "ktl": ktl,
            "kdeg": kdeg,
            "cooperativity": cooperativity,
            # default params
            ("transcription", "ktx"): ktx,
            ("transcription", p_id, 'ku'): ku
        }

        one_param = {"kb": kb}
        self.component.update_parameters(mixture_parameters={},
                                         parameters=one_param)
        # testing that one_param was registered
        self.assertEqual(self.component.get_parameter(param_name="kb"),
                         one_param["kb"])
        # update the component parameters
        self.component.update_parameters(parameters=parameters)
        # testing the different parameter definitions
        tx = Transcription_MM()
        self.assertEqual(
            self.component.get_parameter(mechanism=tx, param_name='ktx'), ktx)

        self.assertEqual(
            self.component.get_parameter(mechanism=tx,
                                         part_id=p_id,
                                         param_name='ku'), ku)
    def test_update_reactions(self):
        """this function tests the CombinatorialPromoter for the ability to make
        reactions with the proper inputs and outputs."""
        from biocrnpyler import CombinatorialPromoter, Protein, Species, Combinatorial_Cooperative_Binding, \
                                    DNAassembly,Transcription_MM, Translation_MM, Complex, ParameterKey
        
        #make a relatively simple combinatorial promoter
        parameters={"cooperativity":2,"kb":100, "ku":10, "ktx":.05, 
        ParameterKey(mechanism = None, part_id = "testprom_leak", name = "ktx"):.01, 
        ParameterKey(mechanism = None, part_id = "testprom_leak", name = "ku"):50,
        ParameterKey(mechanism = None, part_id = "testprom_treg1_treg2_RNAP", name = "ku"):5}

        newprom = CombinatorialPromoter("testprom",["treg1","treg2"],tx_capable_list=[["treg2","treg1"]], leak = True, parameters = parameters)
        #you have to put it into an assembly
        newdna = DNAassembly("testDNA",promoter=newprom)
        #adding mechanisms because there is no mixture. I believe this is what the mixture does
        sp_rnap = Species("RNAP",material_type="protein")
        ribosome = Species("Ribo", material_type = "protein")

        newdna.add_mechanisms({"transcription":Transcription_MM(rnap = sp_rnap), "translation":Translation_MM(ribosome = ribosome)})
        #you have to do update_species first
        newprom_copy = newdna.promoter #Promoters are copied when added to DNAassemblies
        newprom_spec = newprom_copy.update_species()
        #now the test... does it produce the right reactions??
        newprom_rxns = newprom_copy.update_reactions()
        #here i am generating the species manually
        sp_dna = Species("testDNA",material_type="dna")
        sp_rna = Species("testDNA",material_type="rna")
        sp_treg1 = Species("treg1",material_type="protein")
        sp_treg2 = Species("treg2",material_type="protein")
        #now the complexes
        
        sp_dna_treg1 = Complex([sp_dna,sp_treg1,sp_treg1])
        sp_dna_treg2 = Complex([sp_dna,sp_treg2,sp_treg2])
        sp_dna_treg1_treg2 = Complex([sp_dna,sp_treg2,sp_treg2,sp_treg1,sp_treg1])
        sp_dna_rnap = Complex([sp_dna,sp_rnap])
        sp_dna_treg1_rnap = Complex([sp_dna_treg1,sp_rnap])
        sp_dna_treg2_rnap = Complex([sp_dna_treg2,sp_rnap])
        sp_dna_treg1_treg2_rnap = Complex([sp_dna_treg1_treg2,sp_rnap])
        #print('\n\n'.join([str(a) for a in newprom_rxns]))
        #now, we generate the reaction input outputs manually
        r0 = [set([sp_rnap,sp_dna]),set([sp_dna_rnap]),100,50] #RNAP binding to DNA
        r1 = [set([sp_dna_rnap]),set([sp_dna,sp_rna,sp_rnap]),.01,None] #leaky transcription
        r2 = [set([sp_dna,sp_treg1]),set([sp_dna_treg1]),100,10] #treg1 binding
        r3 = [set([sp_dna_treg1,sp_rnap]),set([sp_dna_treg1_rnap]),100,50] #rnap binding to treg1 bound dna
        r4 = [set([sp_dna_treg1_rnap]),set([sp_dna_treg1,sp_rnap,sp_rna]),.01,None] #leaky tx from single regulator
        r5 = [set([sp_dna_treg2_rnap]),set([sp_dna_treg2,sp_rnap,sp_rna]),.01,None] #leaky tx from single regulator
        r6 = [set([sp_dna_treg1_treg2_rnap]),set([sp_dna_treg1_treg2,sp_rnap,sp_rna]),.05,None] #ktx for regular tx
        r7 = [set([sp_dna_treg2,sp_rnap]),set([sp_dna_treg2_rnap]),100,50] #rnap binding to treg2 bound dna
        r8 = [set([sp_dna,sp_treg2]),set([sp_dna_treg2]),100,10] #treg2 binding
        r9 = [set([sp_dna_treg1,sp_treg2]),set([sp_dna_treg1_treg2]),100,10] #treg2 binding to dna that already has treg1
        r10 = [set([sp_dna_treg2,sp_treg1]),set([sp_dna_treg1_treg2]),100,10] #treg1 binding to dna that already has treg2
        r11 = [set([sp_dna_treg1_treg2,sp_rnap]),set([sp_dna_treg1_treg2_rnap]),100,5] #rnap binding to full complex
        truthlist = [r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11]
        #print('\n\n'.join([str(a) for a in newprom_rxns]))
        for rxn in newprom_rxns:
            in_outs = [set([i.species for i in rxn.inputs]), set([o.species for o in rxn.outputs])]
            correctPick = False
            for rset in truthlist:
                #go through all the reactions and make sure that
                #they have the correct inputs, outputs, and constants.
                if(rset[0]==in_outs[0] and rset[1] == in_outs[1]):
                    self.assertTrue(rxn.propensity_type.k_forward == rset[2])
                    self.assertTrue(rxn.propensity_type.k_reverse == rset[3])
                    correctPick = True
                    break

            self.assertTrue(correctPick)
        #12 reactions must be generated
        self.assertTrue(len(newprom_rxns)==len(truthlist))
        #then we should also test what happens if you say that nothing can transcribe:
        newprom2 = CombinatorialPromoter("testprom",["treg1"], parameters = parameters,tx_capable_list = [],leak=False,\
                        mechanisms={"transcription":Transcription_MM(rnap = sp_rnap), "translation":Translation_MM(ribosome = ribosome)})
        newdna2 = DNAassembly("testDNA",promoter=newprom2)
        #adding mechanisms because there is no mixture. I believe this is what the mixture does
        sp_rnap = Species("RNAP",material_type="protein")
        ribosome = Species("Ribo", material_type = "protein")
        self.assertWarnsRegex(UserWarning, 'nothing can transcribe',newdna2.update_reactions)
Exemplo n.º 10
0
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
Exemplo n.º 11
0
    def test_update_reactions(self):
        """this function tests the CombinatorialPromoter for the ability to make
        reactions with the proper inputs and outputs."""
        from biocrnpyler import CombinatorialPromoter, Protein, Species, Combinatorial_Cooperative_Binding, \
                                    DNAassembly,Transcription_MM, Translation_MM, ComplexSpecies, Multimer

        #make a relatively simple combinatorial promoter
        newprom = CombinatorialPromoter("testprom", ["treg1", "treg2"],
                                        tx_capable_list=[["treg2", "treg1"]],
                                        leak=True)
        #you have to put it into an assembly
        newdna = DNAassembly("testDNA", promoter=newprom)
        #adding mechanisms because there is no mixture. I believe this is what the mixture does
        newdna.update_mechanisms(mechanisms={
            "transcription": Transcription_MM(),
            "translation": Translation_MM()
        })
        newdna.update_parameters(parameters={"cooperativity":2,"kb":100, "ku":10, "ktx":.05, ("testprom_leak","ktx"):.01,\
                                                                ("testprom_leak","ku"):50,("testprom_treg1_treg2_RNAP","ku"):5})
        #you have to do update_species first
        newprom_spec = newprom.update_species()
        #now the test... does it produce the right reactions??
        newprom_rxns = newprom.update_reactions()
        #here i am generating the species manually
        sp_dna = Species("testDNA", material_type="dna")
        sp_rna = Species("testDNA", material_type="rna")
        sp_treg1 = Species("treg1", material_type="protein")
        sp_treg2 = Species("treg2", material_type="protein")
        sp_rnap = Species("RNAP", material_type="protein")
        #now the complexes

        sp_dna_treg1 = ComplexSpecies([sp_dna, sp_treg1, sp_treg1])
        sp_dna_treg2 = ComplexSpecies([sp_dna, sp_treg2, sp_treg2])
        sp_dna_treg1_treg2 = ComplexSpecies(
            [sp_dna, sp_treg2, sp_treg2, sp_treg1, sp_treg1])
        sp_dna_rnap = ComplexSpecies([sp_dna, sp_rnap])
        sp_dna_treg1_rnap = ComplexSpecies([sp_dna_treg1, sp_rnap])
        sp_dna_treg2_rnap = ComplexSpecies([sp_dna_treg2, sp_rnap])
        sp_dna_treg1_treg2_rnap = ComplexSpecies([sp_dna_treg1_treg2, sp_rnap])
        #print('\n\n'.join([str(a) for a in newprom_rxns]))
        #now, we generate the reaction input outputs manually
        r0 = [set([sp_rnap, sp_dna]),
              set([sp_dna_rnap]), 100, 50]  #RNAP binding to DNA
        r1 = [set([sp_dna_rnap]),
              set([sp_dna, sp_rna, sp_rnap]), .01, 0]  #leaky transcription
        r2 = [set([sp_dna, sp_treg1]),
              set([sp_dna_treg1]), 100, 10]  #treg1 binding
        r3 = [set([sp_dna_treg1, sp_rnap]),
              set([sp_dna_treg1_rnap]), 100,
              50]  #rnap binding to treg1 bound dna
        r4 = [
            set([sp_dna_treg1_rnap]),
            set([sp_dna_treg1, sp_rnap, sp_rna]), .01, 0
        ]  #leaky tx from single regulator
        r5 = [
            set([sp_dna_treg2_rnap]),
            set([sp_dna_treg2, sp_rnap, sp_rna]), .01, 0
        ]  #leaky tx from single regulator
        r6 = [
            set([sp_dna_treg1_treg2_rnap]),
            set([sp_dna_treg1_treg2, sp_rnap, sp_rna]), .05, 0
        ]  #ktx for regular tx
        r7 = [set([sp_dna_treg2, sp_rnap]),
              set([sp_dna_treg2_rnap]), 100,
              50]  #rnap binding to treg2 bound dna
        r8 = [set([sp_dna, sp_treg2]),
              set([sp_dna_treg2]), 100, 10]  #treg2 binding
        r9 = [
            set([sp_dna_treg1, sp_treg2]),
            set([sp_dna_treg1_treg2]), 100, 10
        ]  #treg2 binding to dna that already has treg1
        r10 = [
            set([sp_dna_treg2, sp_treg1]),
            set([sp_dna_treg1_treg2]), 100, 10
        ]  #treg1 binding to dna that already has treg2
        r11 = [
            set([sp_dna_treg1_treg2, sp_rnap]),
            set([sp_dna_treg1_treg2_rnap]), 100, 5
        ]  #rnap binding to full complex
        truthlist = [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11]
        #print('\n\n'.join([str(a) for a in newprom_rxns]))
        for rxn in newprom_rxns:
            in_outs = [set(rxn.inputs), set(rxn.outputs)]
            correctPick = False
            for rset in truthlist:
                #go through all the reactions and make sure that
                #they have the correct inputs, outputs, and constants.
                if (rset[0] == in_outs[0] and rset[1] == in_outs[1]):
                    self.assertTrue(rxn.k == rset[2])
                    self.assertTrue(rxn.k_r == rset[3])
                    correctPick = True
                    break

            self.assertTrue(correctPick)
        #12 reactions must be generated
        self.assertTrue(len(newprom_rxns) == len(truthlist))
        #TODO: tests below this are questionable
        #then we should also test what happens if you say that nothing can transcribe:
        newprom2 = CombinatorialPromoter("testprom",
                                         ["treg1"])  #,tx_capable_list = [])
        newdna2 = DNAassembly("testDNA", promoter=newprom2)
        #adding mechanisms because there is no mixture. I believe this is what the mixture does
        newdna2.update_mechanisms(mechanisms={
            "transcription": Transcription_MM(),
            "translation": Translation_MM()
        })
        newdna2.update_parameters(parameters={
            "cooperativity": 2,
            "kb": 100,
            "ku": 10,
            "ktx": .05
        })
        with self.assertWarns(UserWarning):
            #TODO fix this with a warning detection system that actually checks for the proper warning
            newprom_rxns = newprom2.update_reactions()
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)