def main():
    domain_length = 15
    # energy_constraint = dc.NearestNeighborEnergyConstraint(low_energy=-9.2, high_energy=-7)
    numpy_constraints = [  # energy_constraint,
        nc.RunsOfBasesConstraint(['C', 'G'], 4),
        nc.RunsOfBasesConstraint(['A', 'T'], 4)
    ]
    domain_pool = nc.DomainPool(f'length-{domain_length} domains', domain_length,
                                numpy_constraints=numpy_constraints, replace_with_close_sequences=True)

    random_seed = 0
    strands = [nc.Strand([f'{i}' for i in range(1, 50)])]
    for strand in strands:
        for domain in strand.domains:
            domain.pool = domain_pool
    params = ns.SearchParameters(
        constraints=[nc.nupack_strand_complex_free_energy_constraint(
            threshold=-1.5, temperature=52, short_description='StrandSS', parallel=False)],
        out_directory='output/hamming_dist_test',
        # weigh_violations_equally=True
        report_only_violations=False,
        random_seed=random_seed,
        max_iterations=None)
    params.force_overwrite = True  # directly deletes output folder contents w/o user input
    # params.report_delay = 0.0

    design = nc.Design(strands)
    ns.search_for_dna_sequences(design, params)
def main() -> None:
    args: CLArgs = parse_command_line_arguments()

    design = create_design(width=args.width, height=args.height)
    thresholds = Thresholds()
    constraints = create_constraints(design, thresholds)
    params = ns.SearchParameters(
        constraints=constraints,
        out_directory=args.directory,
        restart=args.restart,
        random_seed=args.seed,
        log_time=True,
    )

    ns.search_for_dna_sequences(design, params)
def main() -> None:
    seesaw_gates = [
        *and_or_gate(
            integrating_gate_name=10, amplifying_gate_name=1, inputs=[21, 27]),
        *and_or_gate(
            integrating_gate_name=53, amplifying_gate_name=5, inputs=[18, 22]),
        reporter_gate(gate_name=6, input_=5),
        *and_or_gate(
            integrating_gate_name=20, amplifying_gate_name=8, inputs=[35, 38]),
        *and_or_gate(integrating_gate_name=26,
                     amplifying_gate_name=13,
                     inputs=[33, 37]),
        *and_or_gate(integrating_gate_name=34,
                     amplifying_gate_name=18,
                     inputs=[28, 33, 37]),
        *and_or_gate(integrating_gate_name=36,
                     amplifying_gate_name=21,
                     inputs=[29, 35, 38]),
        reporter_gate(gate_name=23, input_=1),
        reporter_gate(gate_name=24, input_=13),
        reporter_gate(gate_name=25, input_=8),
        *and_or_gate(integrating_gate_name=39,
                     amplifying_gate_name=22,
                     inputs=[29, 31]),
        *and_or_gate(integrating_gate_name=40,
                     amplifying_gate_name=27,
                     inputs=[30, 28]),
        *and_or_gate(integrating_gate_name=41,
                     amplifying_gate_name=28,
                     inputs=[46, 48]),
        *and_or_gate(integrating_gate_name=42,
                     amplifying_gate_name=29,
                     inputs=[45, 47]),
        *and_or_gate(integrating_gate_name=43,
                     amplifying_gate_name=30,
                     inputs=[33, 38]),
        *and_or_gate(integrating_gate_name=44,
                     amplifying_gate_name=31,
                     inputs=[35, 37]),
        input_gate(gate_name=33, input_=49),
        input_gate(gate_name=35, input_=50),
        input_gate(gate_name=37, input_=51),
        input_gate(gate_name=38, input_=52),
    ]

    seesaw_circuit = SeesawCircuit(seesaw_gates=seesaw_gates)
    strands = seesaw_circuit.strands
    non_fuel_strands = []
    for s in strands:
        if FUEL_DOMAIN not in s.domains:
            non_fuel_strands.append(s)

    # Uncomment below for debugging:
    # for s in sorted(strands, key=lambda s: s.name):
    #     print(s)

    # for c in seesaw_circuit.constraints:
    #     print(c)
    # exit(0)

    constraints: List[nc.Constraint] = [
        base_difference_constraint(recognition_domains),
        strand_substring_constraint(non_fuel_strands, ILLEGAL_SUBSTRINGS)
    ]
    constraints.extend(seesaw_circuit.constraints
                       )  # make mypy happy about the generics with List
    design = nc.Design(strands=strands)
    params = ns.SearchParameters(
        constraints=constraints,
        out_directory='output/square_root_circuit',
        # weigh_violations_equally=True,
        # restart=True
    )

    ns.search_for_dna_sequences(design, params)
def main() -> None:
    args: CLArgs = parse_command_line_arguments()

    # domain lengths
    #  9: =========
    # 10: ==========
    # 11: ===========
    # 12: ============
    #
    #             /=========--============>
    #             |    n3*         e3*
    #             |        strand 2
    #             |    e1*          n2*
    #             \===========--==========]
    # /==========--===========>/==========--===========>
    # |     n1         e1      |    n2          e2
    # |        strand 0        |        strand 1
    # |     w1           s1    |     w2           s2
    # \============--=========]\============--=========]
    #               /=========--============>
    #               |    s1*         w2*
    #               |        strand 3
    #               |    w4*          s4*
    #               \===========--==========]

    initial_design = nc.Design()

    strand0: nc.Strand[str] = initial_design.add_strand(
        ['s1', 'w1', 'n1', 'e1'], name='strand 0')
    strand1: nc.Strand[str] = initial_design.add_strand(
        ['s2', 'w2', 'n2', 'e2'], name='strand 1')
    strand2: nc.Strand[None] = initial_design.add_strand(
        ['n2*', 'e1*', 'n3*', 'e3*'], name='strand 2')
    strand3: nc.Strand[str] = initial_design.add_strand(
        ['s4*', 'w4*', 's1*', 'w2*'], name='strand 3')

    if args.initial_design_filename is not None:
        with open(args.initial_design_filename, 'r') as file:
            design_json_str: str = file.read()
        design = nc.Design.from_json(design_json_str)
    else:
        design = initial_design

    numpy_constraints = [
        nc.NearestNeighborEnergyConstraint(-9.5, -9.0, 52.0),
        nc.BaseCountConstraint(base='G', high_count=1),
        nc.RunsOfBasesConstraint(['C', 'G'], 4),
        nc.RunsOfBasesConstraint(['A', 'T'], 4),
    ]

    lengths = [9, 10, 11, 12]
    domain_pools = {
        length: nc.DomainPool(f'length-{length} domains',
                              length,
                              numpy_constraints=numpy_constraints)
        for length in lengths
    }

    for strand in [strand0, strand1]:
        strand.domains[0].pool = domain_pools[lengths[0]]
        strand.domains[1].pool = domain_pools[lengths[3]]
        strand.domains[2].pool = domain_pools[lengths[1]]
        strand.domains[3].pool = domain_pools[lengths[2]]

    strand2.domains[2].pool = domain_pools[lengths[0]]
    strand2.domains[3].pool = domain_pools[lengths[3]]
    strand3.domains[0].pool = domain_pools[lengths[1]]
    strand3.domains[1].pool = domain_pools[lengths[2]]

    strand_pairs_no_comp_constraint = nc.rna_duplex_strand_pairs_constraint(
        threshold=-1.0,
        temperature=52,
        short_description='StrandPairNoCompl',
        pairs=((strand0, strand1), (strand2, strand3)))
    strand_pairs_comp_constraint = nc.rna_duplex_strand_pairs_constraint(
        threshold=-7.0,
        temperature=52,
        short_description='StrandPairCompl',
        pairs=[(strand0, strand2), (strand0, strand3), (strand1, strand2),
               (strand1, strand3)])
    strand_individual_ss_constraint = nc.nupack_strand_complex_free_energy_constraint(
        threshold=-0.0, temperature=52, short_description='StrandSS')

    params = ns.SearchParameters(
        constraints=[
            strand_pairs_no_comp_constraint,
            strand_pairs_comp_constraint,
            strand_individual_ss_constraint,
            # dc.domains_not_substrings_of_each_other_domain_pair_constraint(),
        ],
        # weigh_violations_equally=True,
        out_directory=args.directory,
        restart=args.restart,
        # force_overwrite=True,
        report_only_violations=False,
        random_seed=1,
    )

    ns.search_for_dna_sequences(design=design, params=params)
def main() -> None:
    args: CLArgs = parse_command_line_arguments()

    # dc.logger.setLevel(logging.DEBUG)
    nc.logger.setLevel(logging.INFO)

    random_seed = 1

    # many 4-domain strands with no common domains, 4 domains each, every domain length = 10
    # just for testing parallel processing

    # num_strands = 3
    # num_strands = 5
    # num_strands = 10
    # num_strands = 50
    num_strands = 100
    # num_strands = 355

    design = nc.Design()
    #                     si         wi         ni         ei
    # strand i is    [----------|----------|----------|---------->
    for i in range(num_strands):
        design.add_strand([f's{i}', f'w{i}', f'n{i}', f'e{i}'])

    some_fixed = False
    # some_fixed = True
    if some_fixed:
        # fix all domains of strand 0 and one domain of strand 1
        for domain in design.strands[0].domains:
            domain.set_fixed_sequence('ACGTACGTAC')
        design.strands[1].domains[0].set_fixed_sequence('ACGTACGTAC')

    parallel = False
    # parallel = True

    numpy_constraints: List[NumpyConstraint] = [
        nc.NearestNeighborEnergyConstraint(-9.3, -9.0, 52.0),
        # nc.BaseCountConstraint(base='G', high_count=1),
        # nc.BaseEndConstraint(bases=('C', 'G')),
        # nc.RunsOfBasesConstraint(['C', 'G'], 4),
        # nc.RunsOfBasesConstraint(['A', 'T'], 4),
        # nc.BaseEndConstraint(bases=('A', 'T')),
        # nc.BaseEndConstraint(bases=('C', 'G'), distance_from_end=1),
        # nc.BaseAtPositionConstraint(bases='T', position=3),
        # nc.ForbiddenSubstringConstraint(['GGGG', 'CCCC']),
        # nc.RestrictBasesConstraint(bases=['A', 'T', 'C']),
    ]

    # def nupack_binding_energy_in_bounds(seq: str) -> bool:
    #     energy = dv.binding_complement(seq, 52)
    #     nc.logger.debug(f'nupack complement binding energy = {energy}')
    #     return -11 < energy < -9
    #
    # # list of functions:
    # sequence_constraints: List[SequenceConstraint] = [
    #     # nupack_binding_energy_in_bounds,
    # ]

    replace_with_close_sequences = True
    # replace_with_close_sequences = False
    domain_pool_10 = nc.DomainPool(
        f'length-10_domains',
        10,
        numpy_constraints=numpy_constraints,
        replace_with_close_sequences=replace_with_close_sequences,
    )
    domain_pool_11 = nc.DomainPool(
        f'length-11_domains',
        11,
        numpy_constraints=numpy_constraints,
        replace_with_close_sequences=replace_with_close_sequences,
    )

    if some_fixed:
        for strand in design.strands[
                1:]:  # skip all domains on strand 0 since all its domains are fixed
            for domain in strand.domains[:2]:
                if domain.name != 's1':  # skip for s1 since that domain is fixed
                    domain.pool = domain_pool_10
            for domain in strand.domains[2:]:
                domain.pool = domain_pool_11
    else:
        for strand in design.strands:
            for domain in strand.domains[:2]:
                domain.pool = domain_pool_10
            for domain in strand.domains[2:]:
                domain.pool = domain_pool_11

    # have to set nupack_complex_secondary_structure_constraint after DomainPools are set,
    # so that we know the domain lengths
    strand_complexes = [
        nc.Complex(strand) for i, strand in enumerate(design.strands[2:])
    ]
    strand_base_pair_prob_constraint = nc.nupack_complex_base_pair_probability_constraint(
        strand_complexes=strand_complexes)

    domain_nupack_ss_constraint = nc.nupack_domain_complex_free_energy_constraint(
        threshold=-0.0, temperature=52, short_description='DomainSS')

    domain_pairs_rna_duplex_constraint = nc.rna_duplex_domain_pairs_constraint(
        threshold=-2.0, temperature=52, short_description='DomainPairRNA')

    domain_pair_nupack_constraint = nc.nupack_domain_pair_constraint(
        threshold=-0.5,
        temperature=52,
        short_description='DomainPairNUPACK',
        parallel=parallel)

    strand_pairs_rna_duplex_constraint = nc.rna_duplex_strand_pairs_constraint(
        threshold=-1.0,
        temperature=52,
        short_description='StrandPairRNA',
        parallel=parallel)

    strand_individual_ss_constraint = nc.nupack_strand_complex_free_energy_constraint(
        threshold=-1.0,
        temperature=52,
        short_description='StrandSS',
        parallel=parallel)

    strand_individual_ss_constraint2 = nc.nupack_strand_complex_free_energy_constraint(
        threshold=-1.0,
        temperature=52,
        short_description='StrandSS2',
        parallel=parallel)

    strand_pair_nupack_constraint = nc.nupack_strand_pairs_constraint(
        threshold=3.0,
        temperature=52,
        short_description='StrandPairNUPACK',
        parallel=parallel,
        weight=0.1)

    params = ns.SearchParameters(
        constraints=[
            # domain_nupack_ss_constraint,
            # strand_individual_ss_constraint,
            # strand_individual_ss_constraint2,
            strand_pairs_rna_duplex_constraint,
            # strand_pair_nupack_constraint,
            # domain_pair_nupack_constraint,
            # domain_pairs_rna_duplex_constraint,
            # strand_base_pair_prob_constraint,
            # nc.domains_not_substrings_of_each_other_constraint(),
        ],
        out_directory=args.directory,
        restart=args.restart,
        random_seed=random_seed,
        max_iterations=None,
        save_sequences_for_all_updates=True,
        save_report_for_all_updates=True,
        save_design_for_all_updates=True,
        force_overwrite=True,
        scrolling_output=False,
        # report_only_violations=False,
    )
    ns.search_for_dna_sequences(design, params)
Exemple #6
0
def four_g_constraint_summary(strand: nc.Strand):
    violation_str = "" if 'GGGG' not in strand.sequence() else "** violation**"
    return f"{strand.name}: {strand.sequence()}{violation_str}"


four_g_constraint = nc.StrandConstraint(description="4GConstraint",
                                        short_description="4GConstraint",
                                        evaluate=four_g_constraint_evaluate,
                                        strands=tuple(strands), )

# Constraints
constraints = [
    g_5_s_5_6_complex_constraint,
    g_5_s_2_5_complex_constraint,
    t_2_5_w_5_complex_constraint,
    waste_2_5_complex_constraint,
    reporter_6_complex_constraint,
    f_waste_6_complex_constraint,
]
constraints.append(four_g_constraint)

seesaw_design = nc.Design(strands=strands)

params = ns.SearchParameters(  # weigh_violations_equally=True,
    constraints=constraints,
    # report_delay=0.0,
    out_directory='output/seesaw_gate',
    report_only_violations=False, )

ns.search_for_dna_sequences(design=seesaw_design, params=params)