Skip to content

Commit cf75dc9

Browse files
authored
Py clone (#96)
Add cloning and fragmentation to python. Definitely should work to improve this over time, but this is good enough to get out there.
1 parent fd42347 commit cf75dc9

File tree

9 files changed

+601
-4
lines changed

9 files changed

+601
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
7676
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7777

7878
## [Unreleased]
79+
- Adds cloning and recursion functions to python. [#96](https://github.com/Koeng101/dnadesign/pull/96)
7980
- Adds recursive fragmentation. [#92](https://github.com/Koeng101/dnadesign/pull/92)
8081
- Updated megamash documentation to be more specific. [#91](https://github.com/Koeng101/dnadesign/pull/91)
8182
- Adds automatic python documentation generation. [#88](https://github.com/Koeng101/dnadesign/pull/88)

lib/clone/example_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"log"
66

77
"github.com/koeng101/dnadesign/lib/clone"
8-
"github.com/koeng101/dnadesign/lib/seqhash"
98
)
109

1110
func ExampleGoldenGate() {
@@ -24,6 +23,6 @@ func ExampleGoldenGate() {
2423
log.Fatalf("Failed to GoldenGate. Got error: %s", err)
2524
}
2625

27-
fmt.Println(seqhash.RotateSequence(plasmid))
28-
// Output: AAAAAAAGGATCTCAAGAAGGCCTACTATTAGCAACAACGATCCTTTGATCTTTTCTACGGGGTCTGACGCTCAGTGGAACGAAAACTCACGTTAAGGGATTTTGGTCATGAGATTATCAAAAAGGATCTTCACCTAGATCCTTTTAAATTAAAAATGAAGTTTTAAATCAATCTAAAGTATATATGAGTAAACTTGGTCTGACAGTTACCAATGCTTAATCAGTGAGGCACCTATCTCAGCGATCTGTCTATTTCGTTCATCCATAGTTGCCTGACTCCCCGTCGTGTAGATAACTACGATACGGGAGGGCTTACCATCTGGCCCCAGTGCTGCAATGATACCGCGAGAACCACGCTCACCGGCTCCAGATTTATCAGCAATAAACCAGCCAGCCGGAAGGGCCGAGCGCAGAAGTGGTCCTGCAACTTTATCCGCCTCCATCCAGTCTATTAATTGTTGCCGGGAAGCTAGAGTAAGTAGTTCGCCAGTTAATAGTTTGCGCAACGTTGTTGCCATTGCTACAGGCATCGTGGTGTCACGCTCGTCGTTTGGTATGGCTTCATTCAGCTCCGGTTCCCAACGATCAAGGCGAGTTACATGATCCCCCATGTTGTGCAAAAAAGCGGTTAGCTCCTTCGGTCCTCCGATCGTTGTCAGAAGTAAGTTGGCCGCAGTGTTATCACTCATGGTTATGGCAGCACTGCATAATTCTCTTACTGTCATGCCATCCGTAAGATGCTTTTCTGTGACTGGTGAGTACTCAACCAAGTCATTCTGAGAATAGTGTATGCGGCGACCGAGTTGCTCTTGCCCGGCGTCAATACGGGATAATACCGCGCCACATAGCAGAACTTTAAAAGTGCTCATCATTGGAAAACGTTCTTCGGGGCGAAAACTCTCAAGGATCTTACCGCTGTTGAGATCCAGTTCGATGTAACCCACTCGTGCACCCAACTGATCTTCAGCATCTTTTACTTTCACCAGCGTTTCTGGGTGAGCAAAAACAGGAAGGCAAAATGCCGCAAAAAAGGGAATAAGGGCGACACGGAAATGTTGAATACTCATACTCTTCCTTTTTCAATATTATTGAAGCATTTATCAGGGTTATTGTCTCATGAGCGGATACATATTTGAATGTATTTAGAAAAATAAACAAATAGGGGTTCCGCGCACCTGCACCAGTCAGTAAAACGACGGCCAGTAGTCAAAAGCCTCCGACCGGAGGCTTTTGACTTGGTTCAGGTGGAGTGGGAGAAACACGTGGCAAACATTCCGGTCTCAAATGGAAAAGAGCAACGAAACCAACGGCTACCTTGACAGCGCTCAAGCCGGCCCTGCAGCTGGCCCGGGCGCTCCGGGTACCGCCGCGGGTCGTGCACGTCGTTGCGCGGGCTTCCTGCGGCGCCAAGCGCTGGTGCTGCTCACGGTGTCTGGTGTTCTGGCAGGCGCCGGTTTGGGCGCGGCACTGCGTGGGCTCAGCCTGAGCCGCACCCAGGTCACCTACCTGGCCTTCCCCGGCGAGATGCTGCTCCGCATGCTGCGCATGATCATCCTGCCGCTGGTGGTCTGCAGCCTGGTGTCGGGCGCCGCCTCCCTCGATGCCAGCTGCCTCGGGCGTCTGGGCGGTATCGCTGTCGCCTACTTTGGCCTCACCACACTGAGTGCCTCGGCGCTCGCCGTGGCCTTGGCGTTCATCATCAAGCCAGGATCCGGTGCGCAGACCCTTCAGTCCAGCGACCTGGGGCTGGAGGACTCGGGGCCTCCTCCTGTCCCCAAAGAAACGGTGGACTCTTTCCTCGACCTGGCCAGAAACCTGTTTCCCTCCAATCTTGTGGTTGCAGCTTTCCGTACGTATGCAACCGATTATAAAGTCGTGACCCAGAACAGCAGCTCTGGAAATGTAACCCATGAAAAGATCCCCATAGGCACTGAGATAGAAGGGATGAACATTTTAGGATTGGTCCTGTTTGCTCTGGTGTTAGGAGTGGCCTTAAAGAAACTAGGCTCCGAAGGAGAGGACCTCATCCGTTTCTTCAATTCCCTCAACGAGGCGACGATGGTGCTGGTGTCCTGGATTATGTGGTACGTACCTGTGGGCATCATGTTCCTTGTTGGAAGCAAGATCGTGGAAATGAAAGACATCATCGTGCTGGTGACCAGCCTGGGGAAATACATCTTCGCATCTATATTGGGCCACGTCATTCATGGTGGTATCGTCCTGCCGCTGATTTATTTTGTTTTCACACGAAAAAACCCATTCAGATTCCTCCTGGGCCTCCTCGCCCCATTTGCGACAGCATTTGCTACGTGCTCCAGCTCAGCGACCCTTCCCTCTATGATGAAGTGCATTGAAGAGAACAATGGTGTGGACAAGAGGATCTCCAGGTTTATTCTCCCCATCGGGGCCACCGTGAACATGGACGGAGCAGCCATCTTCCAGTGTGTGGCCGCGGTGTTCATTGCGCAACTCAACAACGTAGAGCTCAACGCAGGACAGATTTTCACCATTCTAGTGACTGCCACAGCGTCCAGTGTTGGAGCAGCAGGCGTGCCAGCTGGAGGGGTCCTCACCATTGCCATTATCCTGGAGGCCATTGGGCTGCCTACTCATGATCTGCCTCTGATCCTGGCTGTGGACTGGATTGTGGACCGGACCACCACGGTGGTGAATGTGGAAGGGGATGCCCTGGGTGCAGGCATTCTCCACCACCTGAATCAGAAGGCAACAAAGAAAGGCGAGCAGGAACTTGCTGAGGTGAAAGTGGAAGCCATCCCCAACTGCAAGTCTGAGGAGGAAACCTCGCCCCTGGTGACACACCAGAACCCCGCTGGCCCCGTGGCCAGTGCCCCAGAACTGGAATCCAAGGAGTCGGTTCTGTGAAGAGCTTAGAGACCGACGACTGCCTAAGGACATTCGCTGAGGTGTCAATCGTCGGAGCCGCTGAGCAATAACTAGCATAACCCCTTGGGGCCTCTAAACGGGTCTTGAGGGGTTTTTTGCATGGTCATAGCTGTTTCCTGAGAGCTTGGCAGGTGATGACACACATTAACAAATTTCGTGAGGAGTCTCCAGAAGAATGCCATTAATTTCCATAGGCTCCGCCCCCCTGACGAGCATCACAAAAATCGACGCTCAAGTCAGAGGTGGCGAAACCCGACAGGACTATAAAGATACCAGGCGTTTCCCCCTGGAAGCTCCCTCGTGCGCTCTCCTGTTCCGACCCTGCCGCTTACCGGATACCTGTCCGCCTTTCTCCCTTCGGGAAGCGTGGCGCTTTCTCATAGCTCACGCTGTAGGTATCTCAGTTCGGTGTAGGTCGTTCGCTCCAAGCTGGGCTGTGTGCACGAACCCCCCGTTCAGCCCGACCGCTGCGCCTTATCCGGTAACTATCGTCTTGAGTCCAACCCGGTAAGACACGACTTATCGCCACTGGCAGCAGCCACTGGTAACAGGATTAGCAGAGCGAGGTATGTAGGCGGTGCTACAGAGTTCTTGAAGTGGTGGCCTAACTACGGCTACACTAGAAGAACAGTATTTGGTATCTGCGCTCTGCTGAAGCCAGTTACCTTCGGAAAAAGAGTTGGTAGCTCTTGATCCGGCAAACAAACCACCGCTGGTAGCGGTGGTTTTTTTGTTTGCAAGCAGCAGATTACGCGCAG
26+
fmt.Println(plasmid)
27+
// Output: GGAGAAACACGTGGCAAACATTCCGGTCTCAAATGGAAAAGAGCAACGAAACCAACGGCTACCTTGACAGCGCTCAAGCCGGCCCTGCAGCTGGCCCGGGCGCTCCGGGTACCGCCGCGGGTCGTGCACGTCGTTGCGCGGGCTTCCTGCGGCGCCAAGCGCTGGTGCTGCTCACGGTGTCTGGTGTTCTGGCAGGCGCCGGTTTGGGCGCGGCACTGCGTGGGCTCAGCCTGAGCCGCACCCAGGTCACCTACCTGGCCTTCCCCGGCGAGATGCTGCTCCGCATGCTGCGCATGATCATCCTGCCGCTGGTGGTCTGCAGCCTGGTGTCGGGCGCCGCCTCCCTCGATGCCAGCTGCCTCGGGCGTCTGGGCGGTATCGCTGTCGCCTACTTTGGCCTCACCACACTGAGTGCCTCGGCGCTCGCCGTGGCCTTGGCGTTCATCATCAAGCCAGGATCCGGTGCGCAGACCCTTCAGTCCAGCGACCTGGGGCTGGAGGACTCGGGGCCTCCTCCTGTCCCCAAAGAAACGGTGGACTCTTTCCTCGACCTGGCCAGAAACCTGTTTCCCTCCAATCTTGTGGTTGCAGCTTTCCGTACGTATGCAACCGATTATAAAGTCGTGACCCAGAACAGCAGCTCTGGAAATGTAACCCATGAAAAGATCCCCATAGGCACTGAGATAGAAGGGATGAACATTTTAGGATTGGTCCTGTTTGCTCTGGTGTTAGGAGTGGCCTTAAAGAAACTAGGCTCCGAAGGAGAGGACCTCATCCGTTTCTTCAATTCCCTCAACGAGGCGACGATGGTGCTGGTGTCCTGGATTATGTGGTACGTACCTGTGGGCATCATGTTCCTTGTTGGAAGCAAGATCGTGGAAATGAAAGACATCATCGTGCTGGTGACCAGCCTGGGGAAATACATCTTCGCATCTATATTGGGCCACGTCATTCATGGTGGTATCGTCCTGCCGCTGATTTATTTTGTTTTCACACGAAAAAACCCATTCAGATTCCTCCTGGGCCTCCTCGCCCCATTTGCGACAGCATTTGCTACGTGCTCCAGCTCAGCGACCCTTCCCTCTATGATGAAGTGCATTGAAGAGAACAATGGTGTGGACAAGAGGATCTCCAGGTTTATTCTCCCCATCGGGGCCACCGTGAACATGGACGGAGCAGCCATCTTCCAGTGTGTGGCCGCGGTGTTCATTGCGCAACTCAACAACGTAGAGCTCAACGCAGGACAGATTTTCACCATTCTAGTGACTGCCACAGCGTCCAGTGTTGGAGCAGCAGGCGTGCCAGCTGGAGGGGTCCTCACCATTGCCATTATCCTGGAGGCCATTGGGCTGCCTACTCATGATCTGCCTCTGATCCTGGCTGTGGACTGGATTGTGGACCGGACCACCACGGTGGTGAATGTGGAAGGGGATGCCCTGGGTGCAGGCATTCTCCACCACCTGAATCAGAAGGCAACAAAGAAAGGCGAGCAGGAACTTGCTGAGGTGAAAGTGGAAGCCATCCCCAACTGCAAGTCTGAGGAGGAAACCTCGCCCCTGGTGACACACCAGAACCCCGCTGGCCCCGTGGCCAGTGCCCCAGAACTGGAATCCAAGGAGTCGGTTCTGTGAAGAGCTTAGAGACCGACGACTGCCTAAGGACATTCGCTGAGGTGTCAATCGTCGGAGCCGCTGAGCAATAACTAGCATAACCCCTTGGGGCCTCTAAACGGGTCTTGAGGGGTTTTTTGCATGGTCATAGCTGTTTCCTGAGAGCTTGGCAGGTGATGACACACATTAACAAATTTCGTGAGGAGTCTCCAGAAGAATGCCATTAATTTCCATAGGCTCCGCCCCCCTGACGAGCATCACAAAAATCGACGCTCAAGTCAGAGGTGGCGAAACCCGACAGGACTATAAAGATACCAGGCGTTTCCCCCTGGAAGCTCCCTCGTGCGCTCTCCTGTTCCGACCCTGCCGCTTACCGGATACCTGTCCGCCTTTCTCCCTTCGGGAAGCGTGGCGCTTTCTCATAGCTCACGCTGTAGGTATCTCAGTTCGGTGTAGGTCGTTCGCTCCAAGCTGGGCTGTGTGCACGAACCCCCCGTTCAGCCCGACCGCTGCGCCTTATCCGGTAACTATCGTCTTGAGTCCAACCCGGTAAGACACGACTTATCGCCACTGGCAGCAGCCACTGGTAACAGGATTAGCAGAGCGAGGTATGTAGGCGGTGCTACAGAGTTCTTGAAGTGGTGGCCTAACTACGGCTACACTAGAAGAACAGTATTTGGTATCTGCGCTCTGCTGAAGCCAGTTACCTTCGGAAAAAGAGTTGGTAGCTCTTGATCCGGCAAACAAACCACCGCTGGTAGCGGTGGTTTTTTTGTTTGCAAGCAGCAGATTACGCGCAGAAAAAAAGGATCTCAAGAAGGCCTACTATTAGCAACAACGATCCTTTGATCTTTTCTACGGGGTCTGACGCTCAGTGGAACGAAAACTCACGTTAAGGGATTTTGGTCATGAGATTATCAAAAAGGATCTTCACCTAGATCCTTTTAAATTAAAAATGAAGTTTTAAATCAATCTAAAGTATATATGAGTAAACTTGGTCTGACAGTTACCAATGCTTAATCAGTGAGGCACCTATCTCAGCGATCTGTCTATTTCGTTCATCCATAGTTGCCTGACTCCCCGTCGTGTAGATAACTACGATACGGGAGGGCTTACCATCTGGCCCCAGTGCTGCAATGATACCGCGAGAACCACGCTCACCGGCTCCAGATTTATCAGCAATAAACCAGCCAGCCGGAAGGGCCGAGCGCAGAAGTGGTCCTGCAACTTTATCCGCCTCCATCCAGTCTATTAATTGTTGCCGGGAAGCTAGAGTAAGTAGTTCGCCAGTTAATAGTTTGCGCAACGTTGTTGCCATTGCTACAGGCATCGTGGTGTCACGCTCGTCGTTTGGTATGGCTTCATTCAGCTCCGGTTCCCAACGATCAAGGCGAGTTACATGATCCCCCATGTTGTGCAAAAAAGCGGTTAGCTCCTTCGGTCCTCCGATCGTTGTCAGAAGTAAGTTGGCCGCAGTGTTATCACTCATGGTTATGGCAGCACTGCATAATTCTCTTACTGTCATGCCATCCGTAAGATGCTTTTCTGTGACTGGTGAGTACTCAACCAAGTCATTCTGAGAATAGTGTATGCGGCGACCGAGTTGCTCTTGCCCGGCGTCAATACGGGATAATACCGCGCCACATAGCAGAACTTTAAAAGTGCTCATCATTGGAAAACGTTCTTCGGGGCGAAAACTCTCAAGGATCTTACCGCTGTTGAGATCCAGTTCGATGTAACCCACTCGTGCACCCAACTGATCTTCAGCATCTTTTACTTTCACCAGCGTTTCTGGGTGAGCAAAAACAGGAAGGCAAAATGCCGCAAAAAAGGGAATAAGGGCGACACGGAAATGTTGAATACTCATACTCTTCCTTTTTCAATATTATTGAAGCATTTATCAGGGTTATTGTCTCATGAGCGGATACATATTTGAATGTATTTAGAAAAATAAACAAATAGGGGTTCCGCGCACCTGCACCAGTCAGTAAAACGACGGCCAGTAGTCAAAAGCCTCCGACCGGAGGCTTTTGACTTGGTTCAGGTGGAGTG
2928
}

py/dnadesign/clone.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from typing import List, Optional
2+
from .cffi_bindings import ffi, lib
3+
4+
class Part:
5+
def __init__(self, sequence: str, circular: bool):
6+
self.sequence = sequence
7+
self.circular = circular
8+
9+
class Fragment:
10+
def __init__(self, sequence: str, forward_overhang: str, reverse_overhang: str):
11+
self.sequence = sequence
12+
self.forward_overhang = forward_overhang
13+
self.reverse_overhang = reverse_overhang
14+
15+
def _create_c_string(python_string: str):
16+
return ffi.new("char[]", python_string.encode('utf-8'))
17+
18+
def _create_c_part(part: Part):
19+
return {"sequence": _create_c_string(part.sequence), "circular": ffi.cast("int", int(part.circular))}
20+
21+
def _create_c_fragment(fragment: Fragment):
22+
return {
23+
"sequence": _create_c_string(fragment.sequence),
24+
"forward_overhang": _create_c_string(fragment.forward_overhang),
25+
"reverse_overhang": _create_c_string(fragment.reverse_overhang)
26+
}
27+
28+
def _fragment_from_c(c_fragment):
29+
return Fragment(
30+
ffi.string(c_fragment.sequence).decode('utf-8'),
31+
ffi.string(c_fragment.forward_overhang).decode('utf-8'),
32+
ffi.string(c_fragment.reverse_overhang).decode('utf-8')
33+
)
34+
35+
def cut_with_enzyme_by_name(part: Part, directional: bool, name: str, methylated: bool) -> List[Fragment]:
36+
c_part = ffi.new("Part*", _create_c_part(part))
37+
c_name = _create_c_string(name)
38+
c_directional = ffi.cast("int", int(directional))
39+
c_methylated = ffi.cast("int", int(methylated))
40+
41+
result = lib.CutWithEnzymeByName(c_part[0], c_directional, c_name, c_methylated)
42+
if result.error != ffi.NULL:
43+
raise Exception(ffi.string(result.error).decode('utf-8'))
44+
45+
fragments = [_fragment_from_c(result.fragments[i]) for i in range(result.size)]
46+
return fragments
47+
48+
def ligate(fragments: List[Fragment], circular: bool) -> str:
49+
c_fragments = ffi.new("Fragment[]", [_create_c_fragment(f) for f in fragments])
50+
c_fragment_count = ffi.cast("int", len(fragments))
51+
c_circular = ffi.cast("int", int(circular))
52+
53+
result = lib.Ligate(c_fragments, c_fragment_count, c_circular)
54+
if result.error != ffi.NULL:
55+
raise Exception(ffi.string(result.error).decode('utf-8'))
56+
57+
return ffi.string(result.ligation).decode('utf-8')
58+
59+
def golden_gate(sequences: List[Part], cutting_enzyme_name: str, methylated: bool) -> str:
60+
c_parts = ffi.new("Part[]", [_create_c_part(part) for part in sequences])
61+
c_sequence_count = ffi.cast("int", len(sequences))
62+
c_cutting_enzyme_name = _create_c_string(cutting_enzyme_name)
63+
c_methylated = ffi.cast("int", int(methylated))
64+
65+
result = lib.GoldenGate(c_parts, c_sequence_count, c_cutting_enzyme_name, c_methylated)
66+
if result.error != ffi.NULL:
67+
raise Exception(ffi.string(result.error).decode('utf-8'))
68+
69+
return ffi.string(result.ligation).decode('utf-8')

py/dnadesign/definitions.h

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,79 @@ typedef struct {
137137

138138
GenbankResult ParseGenbankFromCFile(void* cfile);
139139
GenbankResult ParseGenbankFromCString(char* cstring);
140+
141+
// Part, Fragment, and Assembly definitions
142+
typedef struct {
143+
char* sequence;
144+
int circular;
145+
} Part;
146+
147+
typedef struct {
148+
char* sequence;
149+
char* forward_overhang;
150+
char* reverse_overhang;
151+
} Fragment;
152+
153+
typedef struct {
154+
char* sequence;
155+
char** fragments;
156+
int fragmentCount;
157+
double efficiency;
158+
void* subAssemblies;
159+
int subAssemblyCount;
160+
} Assembly;
161+
162+
// New struct definitions for function outputs
163+
typedef struct {
164+
Fragment* fragments;
165+
int size;
166+
char* error;
167+
} FragmentResult;
168+
169+
typedef struct {
170+
char* ligation;
171+
int* ligationPattern;
172+
int ligationPatternSize;
173+
char* error;
174+
} LigationResult;
175+
176+
typedef struct {
177+
char** overhangs;
178+
double* efficiencies;
179+
int size;
180+
char* error;
181+
} OverhangResult;
182+
183+
typedef struct {
184+
char** fragments;
185+
int size;
186+
double efficiency;
187+
char* error;
188+
} FragmentSequenceResult;
189+
190+
typedef struct {
191+
Assembly* assembly;
192+
char* error;
193+
} RecursiveFragmentSequenceResult;
194+
195+
// Function declarations
196+
FragmentResult CutWithEnzymeByName(Part part, int directional, char* name,
197+
int methylated);
198+
LigationResult Ligate(Fragment* fragments, int fragmentCount, int circular);
199+
LigationResult GoldenGate(Part* sequences, int sequenceCount,
200+
char* cuttingEnzymeName, int methylated);
201+
double SetEfficiency(char** overhangs, int overhangCount);
202+
OverhangResult NextOverhangs(char** currentOverhangs, int overhangCount);
203+
char* NextOverhang(char** currentOverhangs, int overhangCount);
204+
FragmentSequenceResult FragmentSequence(char* sequence, int minFragmentSize,
205+
int maxFragmentSize,
206+
char** excludeOverhangs,
207+
int excludeOverhangCount);
208+
FragmentSequenceResult FragmentSequenceWithOverhangs(
209+
char* sequence, int minFragmentSize, int maxFragmentSize,
210+
char** excludeOverhangs, int excludeOverhangCount, char** includeOverhangs,
211+
int includeOverhangCount);
212+
RecursiveFragmentSequenceResult RecursiveFragmentSequence(
213+
char* sequence, int maxCodingSizeOligo, int* assemblyPattern,
214+
int patternCount, char** excludeOverhangs, int excludeCount,
215+
char** includeOverhangs, int includeCount);

py/dnadesign/fragment.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
from typing import List, Tuple
2+
from .cffi_bindings import ffi, lib
3+
4+
class Assembly:
5+
def __init__(self, sequence: str, fragments: List[str], efficiency: float, sub_assemblies: List['Assembly']):
6+
self.sequence = sequence
7+
self.fragments = fragments
8+
self.efficiency = efficiency
9+
self.sub_assemblies = sub_assemblies
10+
11+
def _create_c_string_array(python_strings: List[str]):
12+
c_strings = [ffi.new("char[]", s.encode('utf-8')) for s in python_strings]
13+
c_array = ffi.new("char *[]", c_strings)
14+
return c_array, c_strings # Return c_strings to keep them alive
15+
16+
def _c_string_array_to_python(c_array, size):
17+
return [ffi.string(c_array[i]).decode('utf-8') for i in range(size)]
18+
19+
def set_efficiency(overhangs: List[str]) -> float:
20+
c_overhangs, _ = _create_c_string_array(overhangs)
21+
return lib.SetEfficiency(c_overhangs, len(overhangs))
22+
23+
def next_overhangs(current_overhangs: List[str]) -> Tuple[List[str], List[float]]:
24+
c_overhangs, _ = _create_c_string_array(current_overhangs)
25+
result = lib.NextOverhangs(c_overhangs, len(current_overhangs))
26+
27+
if result.error != ffi.NULL:
28+
raise Exception(ffi.string(result.error).decode('utf-8'))
29+
30+
overhangs = _c_string_array_to_python(result.overhangs, result.size)
31+
efficiencies = [result.efficiencies[i] for i in range(result.size)]
32+
return overhangs, efficiencies
33+
34+
def next_overhang(current_overhangs: List[str]) -> str:
35+
c_overhangs, _ = _create_c_string_array(current_overhangs)
36+
result = lib.NextOverhang(c_overhangs, len(current_overhangs))
37+
return ffi.string(result).decode('utf-8')
38+
39+
def fragment(sequence: str, min_fragment_size: int, max_fragment_size: int, exclude_overhangs: List[str]) -> Tuple[List[str], float, str]:
40+
c_sequence = ffi.new("char[]", sequence.encode('utf-8'))
41+
c_exclude_overhangs, _ = _create_c_string_array(exclude_overhangs)
42+
43+
result = lib.FragmentSequence(c_sequence, min_fragment_size, max_fragment_size, c_exclude_overhangs, len(exclude_overhangs))
44+
45+
if result.error != ffi.NULL:
46+
error = ffi.string(result.error).decode('utf-8')
47+
return [], 0.0, error
48+
49+
fragments = _c_string_array_to_python(result.fragments, result.size)
50+
return fragments, result.efficiency, None
51+
52+
def fragment_with_overhangs(sequence: str, min_fragment_size: int, max_fragment_size: int,
53+
exclude_overhangs: List[str], include_overhangs: List[str]) -> Tuple[List[str], float, str]:
54+
c_sequence = ffi.new("char[]", sequence.encode('utf-8'))
55+
c_exclude_overhangs, _ = _create_c_string_array(exclude_overhangs)
56+
c_include_overhangs, _ = _create_c_string_array(include_overhangs)
57+
58+
result = lib.FragmentSequenceWithOverhangs(c_sequence, min_fragment_size, max_fragment_size,
59+
c_exclude_overhangs, len(exclude_overhangs),
60+
c_include_overhangs, len(include_overhangs))
61+
62+
if result.error != ffi.NULL:
63+
error = ffi.string(result.error).decode('utf-8')
64+
return [], 0.0, error
65+
66+
fragments = _c_string_array_to_python(result.fragments, result.size)
67+
return fragments, result.efficiency, None
68+
69+
def _assembly_from_c(c_assembly) -> Assembly:
70+
sequence = ffi.string(c_assembly.sequence).decode('utf-8')
71+
fragments = _c_string_array_to_python(c_assembly.fragments, c_assembly.fragmentCount)
72+
efficiency = c_assembly.efficiency
73+
sub_assemblies = [_assembly_from_c(c_assembly.subAssemblies[i]) for i in range(c_assembly.subAssemblyCount)]
74+
return Assembly(sequence, fragments, efficiency, sub_assemblies)
75+
76+
def recursive_fragment(sequence: str, max_coding_size_oligo: int, assembly_pattern: List[int],
77+
exclude_overhangs: List[str], include_overhangs: List[str]) -> Assembly:
78+
c_sequence = ffi.new("char[]", sequence.encode('utf-8'))
79+
c_assembly_pattern = ffi.new("int[]", assembly_pattern)
80+
c_exclude_overhangs, _ = _create_c_string_array(exclude_overhangs)
81+
c_include_overhangs, _ = _create_c_string_array(include_overhangs)
82+
83+
result = lib.RecursiveFragmentSequence(c_sequence, max_coding_size_oligo, c_assembly_pattern, len(assembly_pattern),
84+
c_exclude_overhangs, len(exclude_overhangs),
85+
c_include_overhangs, len(include_overhangs))
86+
87+
if result.error != ffi.NULL:
88+
raise Exception(ffi.string(result.error).decode('utf-8'))
89+
90+
return _assembly_from_c(result.assembly)

0 commit comments

Comments
 (0)