Skip to content

Commit 15cd727

Browse files
Koeng101TimothyStiles
andauthored
Get next overhang (#215)
* Moved synthesis to fixer and wrote fragment * Added NextOverhang Co-authored-by: Tim <TimothyStiles@users.noreply.github.com>
1 parent 902f46d commit 15cd727

File tree

2 files changed

+78
-10
lines changed

2 files changed

+78
-10
lines changed

synthesis/fragment/example_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@ func Example_basic() {
1616
// Output: [ATGACCATGATTACGCCAAGCTTGCATGCCTGCAGGTCGACTCTAGAGGATCCCCGGGTACCGAGCTCGAATTCACTGGCCGTCGTTTTACAACGTCGTGACTGG CTGGGAAAACCCTGGCGTTACCCAACTTAATCGCCTTGCAGCACATCCCCCTTTCGCCAGCTGGCGTAATAGCGAAGAGGCCCGCACCGATCGCCCTTCCCAACA AACAGTTGCGCAGCCTGAATGGCGAATGGCGCCTGATGCGGTATTTTCTCCTTACGCATCTGTGCG TGCGGTATTTCACACCGCATATGGTGCACTCTCAGTACAATCTGCTCTGATGCCGCATAG]
1717
}
1818

19+
// This example shows how to generate a new overhang onto a list of overhangs.
20+
func ExampleNextOverhang() {
21+
primerOverhangs := []string{"ATAA"}
22+
primerOverhangs = append(primerOverhangs, fragment.NextOverhang(primerOverhangs))
23+
primerOverhangs = append(primerOverhangs, fragment.NextOverhang(primerOverhangs))
24+
primerOverhangs = append(primerOverhangs, fragment.NextOverhang(primerOverhangs))
25+
26+
fmt.Println(primerOverhangs)
27+
// Output: [ATAA AAAT AATA AAGA]
28+
}
29+
1930
func ExampleFragment() {
2031
lacZ := "ATGACCATGATTACGCCAAGCTTGCATGCCTGCAGGTCGACTCTAGAGGATCCCCGGGTACCGAGCTCGAATTCACTGGCCGTCGTTTTACAACGTCGTGACTGGGAAAACCCTGGCGTTACCCAACTTAATCGCCTTGCAGCACATCCCCCTTTCGCCAGCTGGCGTAATAGCGAAGAGGCCCGCACCGATCGCCCTTCCCAACAGTTGCGCAGCCTGAATGGCGAATGGCGCCTGATGCGGTATTTTCTCCTTACGCATCTGTGCGGTATTTCACACCGCATATGGTGCACTCTCAGTACAATCTGCTCTGATGCCGCATAG"
2132
fragments, efficiency, _ := fragment.Fragment(lacZ, 95, 105)

synthesis/fragment/fragment.go

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ package fragment
1313

1414
import (
1515
"fmt"
16+
"github.com/TimothyStiles/poly/checks"
1617
"github.com/TimothyStiles/poly/transform"
1718
"strings"
1819
)
@@ -34,6 +35,63 @@ func SetEfficiency(overhangs []string) float64 {
3435
return efficiency
3536
}
3637

38+
// NextOverhangs gets a list of possible next overhangs to use for an overhang
39+
// list, along with their efficiencies. This can be used for more optimal
40+
// fragmentation of sequences with potential degeneracy.
41+
func NextOverhangs(currentOverhangs []string) ([]string, []float64) {
42+
currentOverhangMap := make(map[string]bool)
43+
for _, overhang := range currentOverhangs {
44+
currentOverhangMap[overhang] = true
45+
}
46+
47+
// These 4 for loops generate all combinations of 4 base pairs
48+
// checking all 256 4mer combinations for palindromes. Palindromes
49+
// can cause problems in large combinatorial reactions, so are
50+
// removed here.
51+
bases := []rune{'A', 'T', 'G', 'C'}
52+
var overhangsToTest []string
53+
for _, base1 := range bases {
54+
for _, base2 := range bases {
55+
for _, base3 := range bases {
56+
for _, base4 := range bases {
57+
newOverhang := string([]rune{base1, base2, base3, base4})
58+
_, ok := currentOverhangMap[newOverhang]
59+
if !ok {
60+
if !checks.IsPalindromic(newOverhang) {
61+
overhangsToTest = append(overhangsToTest, newOverhang)
62+
}
63+
}
64+
}
65+
}
66+
}
67+
}
68+
69+
var efficiencies []float64
70+
for _, overhang := range overhangsToTest {
71+
efficiencies = append(efficiencies, SetEfficiency(append(currentOverhangs, overhang)))
72+
}
73+
return overhangsToTest, efficiencies
74+
}
75+
76+
// NextOverhang gets next most efficient overhang to use for a given set of
77+
// overhangs. This is useful for when developing a new set of standard
78+
// overhangs. Note: NextOverhang is biased towards high AT overhangs, but this
79+
// will not affect fidelity at all.
80+
func NextOverhang(currentOverhangs []string) string {
81+
overhangsToTest, efficiencies := NextOverhangs(currentOverhangs)
82+
var efficiency float64
83+
var newOverhang string
84+
maxEfficiency := float64(0)
85+
for i, overhang := range overhangsToTest {
86+
efficiency = efficiencies[i]
87+
if efficiency > maxEfficiency {
88+
maxEfficiency = efficiency
89+
newOverhang = overhang
90+
}
91+
}
92+
return newOverhang
93+
}
94+
3795
// optimizeOverhangIteration takes in a sequence and optimally fragments it.
3896
func optimizeOverhangIteration(sequence string, minFragmentSize int, maxFragmentSize int, existingFragments []string, existingOverhangs []string) ([]string, float64, error) {
3997
// If the sequence is smaller than maxFragment size, stop iteration.
@@ -66,10 +124,6 @@ func optimizeOverhangIteration(sequence string, minFragmentSize int, maxFragment
66124
maxFragmentSizeBuffer = maxFragmentSize
67125
}
68126
minFragmentSize = maxFragmentSizeBuffer - maxAndMinDifference
69-
// Basic check for minimal size
70-
if minFragmentSize < 12 {
71-
minFragmentSize = 12
72-
}
73127
maxFragmentSize = maxFragmentSizeBuffer // buffer is needed equations above pass.
74128
}
75129

@@ -90,13 +144,16 @@ func optimizeOverhangIteration(sequence string, minFragmentSize int, maxFragment
90144
}
91145
}
92146
if !alreadyExists {
93-
// Get this overhang set's efficiency
94-
setEfficiency := SetEfficiency(append(existingOverhangs, overhangToTest))
147+
// See if this overhang is a palindrome
148+
if !checks.IsPalindromic(overhangToTest) {
149+
// Get this overhang set's efficiency
150+
setEfficiency := SetEfficiency(append(existingOverhangs, overhangToTest))
95151

96-
// If this overhang is more efficient than any other found so far, set it as the best!
97-
if setEfficiency > bestOverhangEfficiency {
98-
bestOverhangEfficiency = setEfficiency
99-
bestOverhangPosition = overhangPosition
152+
// If this overhang is more efficient than any other found so far, set it as the best!
153+
if setEfficiency > bestOverhangEfficiency {
154+
bestOverhangEfficiency = setEfficiency
155+
bestOverhangPosition = overhangPosition
156+
}
100157
}
101158
}
102159
}

0 commit comments

Comments
 (0)