-
-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add optimization and translation functions for sequences #11
Changes from 4 commits
7378e85
fa76b55
1612107
99bc4ee
09782b0
b92ca4b
3ac819f
64a9fdc
db33d75
04a757b
96e63b9
9b737aa
3158fc3
a042748
c46a45f
7a713c6
26f5174
eb035aa
4fb3387
910c932
db0b4b8
e676dde
9e55a71
3c371b6
be485cf
86c71a9
c3594a3
37fcc12
e507f7d
b63a72b
754e77a
49ed9ee
fb8af83
87e2d57
0fbc267
1472d4d
36a7848
2ee4afa
816dd24
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package main | ||
|
||
import ( | ||
"math/rand" | ||
"time" | ||
|
||
weightedRand "github.com/mroth/weightedrand" | ||
) | ||
|
||
// Codon holds information for a codon triplet in a struct | ||
type Codon struct { | ||
Triplet string | ||
Occurrence int | ||
} | ||
|
||
// AminoAcid holds information for an amino acid and related codons in a struct in a struct | ||
type AminoAcid struct { | ||
Letter string | ||
Codons []Codon | ||
} | ||
|
||
// CodonTable holds information for a codon table. | ||
type CodonTable struct { | ||
StartCodons []string | ||
StopCodons []string | ||
AminoAcids []AminoAcid | ||
} | ||
|
||
// Generate map of amino acid -> codon chooser | ||
func (codonTable CodonTable) generateOptimizationTable() map[string]weightedRand.Chooser { | ||
rand.Seed(time.Now().UTC().UnixNano()) | ||
var optimizationMap = make(map[string]weightedRand.Chooser) | ||
for _, aminoAcid := range codonTable.AminoAcids { | ||
// Get list of triplets and their weights | ||
codonChoices := make([]weightedRand.Choice, len(aminoAcid.Codons)) | ||
totals := 0 | ||
for _, codon := range aminoAcid.Codons { | ||
codonChoices = append(codonChoices, weightedRand.Choice{Item: codon.Triplet, Weight: uint(codon.Occurrence)}) | ||
totals += codon.Occurrence | ||
} | ||
optimizationMap[aminoAcid.Letter] = weightedRand.NewChooser(codonChoices...) | ||
} | ||
return optimizationMap | ||
} | ||
|
||
// Optimize takes an amino acid sequence and CodonTable and returns an optimized codon sequence | ||
func Optimize(aminoAcids string, codonTable CodonTable) string { | ||
var codons string | ||
optimizationTable := codonTable.generateOptimizationTable() | ||
for _, aminoAcid := range aminoAcids { | ||
codons += optimizationTable[string(aminoAcid)].Pick().(string) | ||
} | ||
return codons | ||
} | ||
|
||
// Generate map of codons -> amino acid | ||
func (codonTable CodonTable) generateTranslationTable() map[string]string { | ||
var translationMap = make(map[string]string) | ||
for _, aminoAcid := range codonTable.AminoAcids { | ||
for _, codon := range aminoAcid.Codons { | ||
translationMap[codon.Triplet] = aminoAcid.Letter | ||
} | ||
} | ||
return translationMap | ||
} | ||
|
||
// Translate translates a codon sequence to an amino acid sequence | ||
func Translate(nucleotides string, codonTable CodonTable) string { | ||
var aminoAcids string | ||
translationTable := codonTable.generateTranslationTable() | ||
length := len(nucleotides) / 3 // Assumes input sequences are divisible by 3 | ||
for i := 0; length > i; i++ { | ||
aminoAcids += translationTable[nucleotides[i*3:(i+1)*3]] | ||
} | ||
return aminoAcids | ||
} | ||
|
||
// Function to generate default codon tables from NCBI https://www.ncbi.nlm.nih.gov/Taxonomy/Utils/wprintgc.cgi | ||
func generateCodonTable(aas, starts string) CodonTable { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does aas stand for here? Amino acid string? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It stands for amino acids. On the link, they just name it "AAs", so I just copied their nomenclature (also why starts is named starts) |
||
base1 := "TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG" | ||
base2 := "TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG" | ||
base3 := "TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG" | ||
// Add triplets to an amino acid -> triplet map, and if a possible start codon, add to start codon list | ||
var aminoAcidMap = make(map[rune][]Codon) | ||
var startCodons []string | ||
var stopCodons []string | ||
for i, aminoAcid := range aas { | ||
if _, ok := aminoAcidMap[aminoAcid]; ok == false { | ||
aminoAcidMap[aminoAcid] = []Codon{} | ||
} | ||
triplet := string([]byte{base1[i], base2[i], base3[i]}) | ||
aminoAcidMap[aminoAcid] = append(aminoAcidMap[aminoAcid], Codon{triplet, 0}) | ||
if starts[i] == 77 { // M rune | ||
startCodons = append(startCodons, triplet) | ||
} | ||
if starts[i] == 42 { // * rune | ||
stopCodons = append(stopCodons, triplet) | ||
} | ||
} | ||
// Convert amino acid -> triplet map to an amino acid list | ||
var aminoAcidSlice []AminoAcid | ||
for k, v := range aminoAcidMap { | ||
aminoAcidSlice = append(aminoAcidSlice, AminoAcid{string(k), v}) | ||
} | ||
return CodonTable{startCodons, stopCodons, aminoAcidSlice} | ||
} | ||
|
||
// DefaultCodonTables stores all codon tables published by NCBI https://www.ncbi.nlm.nih.gov/Taxonomy/Utils/wprintgc.cgi | ||
var DefaultCodonTables = map[int]CodonTable{ | ||
1: generateCodonTable("FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "---M------**--*----M---------------M----------------------------"), | ||
2: generateCodonTable("FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSS**VVVVAAAADDEEGGGG", "----------**--------------------MMMM----------**---M------------"), | ||
3: generateCodonTable("FFLLSSSSYY**CCWWTTTTPPPPHHQQRRRRIIMMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "----------**----------------------MM---------------M------------"), | ||
4: generateCodonTable("FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "--MM------**-------M------------MMMM---------------M------------"), | ||
5: generateCodonTable("FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSSSSVVVVAAAADDEEGGGG", "---M------**--------------------MMMM---------------M------------"), | ||
6: generateCodonTable("FFLLSSSSYYQQCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "--------------*--------------------M----------------------------"), | ||
9: generateCodonTable("FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNNKSSSSVVVVAAAADDEEGGGG", "----------**-----------------------M---------------M------------"), | ||
10: generateCodonTable("FFLLSSSSYY**CCCWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "----------**-----------------------M----------------------------"), | ||
11: generateCodonTable("FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "---M------**--*----M------------MMMM---------------M------------"), | ||
12: generateCodonTable("FFLLSSSSYY**CC*WLLLSPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "----------**--*----M---------------M----------------------------"), | ||
13: generateCodonTable("FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSSGGVVVVAAAADDEEGGGG", "---M------**----------------------MM---------------M------------"), | ||
14: generateCodonTable("FFLLSSSSYYY*CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNNKSSSSVVVVAAAADDEEGGGG", "-----------*-----------------------M----------------------------"), | ||
16: generateCodonTable("FFLLSSSSYY*LCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "----------*---*--------------------M----------------------------"), | ||
21: generateCodonTable("FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNNKSSSSVVVVAAAADDEEGGGG", "----------**-----------------------M---------------M------------"), | ||
22: generateCodonTable("FFLLSS*SYY*LCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "------*---*---*--------------------M----------------------------"), | ||
23: generateCodonTable("FF*LSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "--*-------**--*-----------------M--M---------------M------------"), | ||
24: generateCodonTable("FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSSKVVVVAAAADDEEGGGG", "---M------**-------M---------------M---------------M------------"), | ||
25: generateCodonTable("FFLLSSSSYY**CCGWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "---M------**-----------------------M---------------M------------"), | ||
26: generateCodonTable("FFLLSSSSYY**CC*WLLLAPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "----------**--*----M---------------M----------------------------"), | ||
27: generateCodonTable("FFLLSSSSYYQQCCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "--------------*--------------------M----------------------------"), | ||
28: generateCodonTable("FFLLSSSSYYQQCCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "----------**--*--------------------M----------------------------"), | ||
29: generateCodonTable("FFLLSSSSYYYYCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "--------------*--------------------M----------------------------"), | ||
30: generateCodonTable("FFLLSSSSYYEECC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "--------------*--------------------M----------------------------"), | ||
31: generateCodonTable("FFLLSSSSYYEECCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "----------**-----------------------M----------------------------"), | ||
33: generateCodonTable("FFLLSSSSYYY*CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSSKVVVVAAAADDEEGGGG", "---M-------*-------M---------------M---------------M------------")} | ||
|
||
//func main() { | ||
// rand.Seed(time.Now().UTC().UnixNano()) | ||
// codonTable := CodonTable{[]string{},[]string{},[]aminoAcid{{"M",[]Codon{{"ATG", 1}}},{"G",[]Codon{{"GGA", 1}}},{"*",[]Codon{{"TAA",1},{"TGA",1}}}}} | ||
// translation := Translate("ATGGGCTGA", DefaultCodonTables[1]) | ||
|
||
// fmt.Println(optimize(translation,codonTable)) | ||
//} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package main | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestTranslation(t *testing.T) { | ||
gfpTranslation := "MASKGEELFTGVVPILVELDGDVNGHKFSVSGEGEGDATYGKLTLKFICTTGKLPVPWPTLVTTFSYGVQCFSRYPDHMKRHDFFKSAMPEGYVQERTISFKDDGNYKTRAEVKFEGDTLVNRIELKGIDFKEDGNILGHKLEYNYNSHNVYITADKQKNGIKANFKIRHNIEDGSVQLADHYQQNTPIGDGPVLLPDNHYLSTQSALSKDPNEKRDHMVLLEFVTAAGITHGMDELYK*" | ||
gfpDnaSequence := "ATGGCTAGCAAAGGAGAAGAACTTTTCACTGGAGTTGTCCCAATTCTTGTTGAATTAGATGGTGATGTTAATGGGCACAAATTTTCTGTCAGTGGAGAGGGTGAAGGTGATGCTACATACGGAAAGCTTACCCTTAAATTTATTTGCACTACTGGAAAACTACCTGTTCCATGGCCAACACTTGTCACTACTTTCTCTTATGGTGTTCAATGCTTTTCCCGTTATCCGGATCATATGAAACGGCATGACTTTTTCAAGAGTGCCATGCCCGAAGGTTATGTACAGGAACGCACTATATCTTTCAAAGATGACGGGAACTACAAGACGCGTGCTGAAGTCAAGTTTGAAGGTGATACCCTTGTTAATCGTATCGAGTTAAAAGGTATTGATTTTAAAGAAGATGGAAACATTCTCGGACACAAACTCGAGTACAACTATAACTCACACAATGTATACATCACGGCAGACAAACAAAAGAATGGAATCAAAGCTAACTTCAAAATTCGCCACAACATTGAAGATGGATCCGTTCAACTAGCAGACCATTATCAACAAAATACTCCAATTGGCGATGGCCCTGTCCTTTTACCAGACAACCATTACCTGTCGACACAATCTGCCCTTTCGAAAGATCCCAACGAAAAGCGTGACCACATGGTCCTTCTTGAGTTTGTAACTGCTGCTGGGATTACACATGGCATGGATGAGCTCTACAAATAA" | ||
if got := Translate(gfpDnaSequence,DefaultCodonTables[11]); got != gfpTranslation { | ||
t.Errorf("TestTranslation has failed. Translate has returned %q, want %q", got, gfpTranslation) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I don't know go very well. But is this a
for loop
in afor loop
in amap
>.>