-
Notifications
You must be signed in to change notification settings - Fork 1
/
kmer_catalogue.go
125 lines (109 loc) · 3.77 KB
/
kmer_catalogue.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* Copyright (C) 2019 Philipp Benner
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gonetics
/* -------------------------------------------------------------------------- */
//import "fmt"
/* -------------------------------------------------------------------------- */
type KmerCatalogue struct {
KmerEquivalenceRelation
elements []map[int][]string // map k-mer class ID (k,i) to class elements
idmap []map[string]int // map k-mer (class instances) to class ID (k,i)
}
/* -------------------------------------------------------------------------- */
func NewKmerCatalogue(n, m int, comp, rev, rc bool, maxAmbiguous []int, al ComplementableAlphabet) (*KmerCatalogue, error) {
if rel, err := NewKmerEquivalenceRelation(n, m, comp, rev, rc, maxAmbiguous, al); err != nil {
return nil, err
} else {
return newKmerCatalogue(rel), nil
}
}
func newKmerCatalogue(rel KmerEquivalenceRelation) *KmerCatalogue {
idmap := make([]map[string]int , rel.M-rel.N+1)
elements := make([]map[int][]string, rel.M-rel.N+1)
for k := rel.N; k <= rel.M; k++ {
idmap [k-rel.N] = make(map[string]int)
elements[k-rel.N] = make(map[int][]string)
}
r := KmerCatalogue{}
r.KmerEquivalenceRelation = rel
r.elements = elements
r.idmap = idmap
return &r
}
/* -------------------------------------------------------------------------- */
func (obj *KmerCatalogue) Clone() *KmerCatalogue {
r := KmerCatalogue{}
r.KmerEquivalenceRelation = obj.KmerEquivalenceRelation
r.idmap = make([]map[string]int , len(obj.idmap))
r.elements = make([]map[int][]string, len(obj.elements))
for i := 0; i < len(obj.idmap); i++ {
r.idmap[i] = make(map[string]int)
for k, v := range obj.idmap[i] {
r.idmap[i][k] = v
}
}
for i := 0; i < len(obj.elements); i++ {
r.elements[i] = make(map[int][]string)
for k, v := range obj.elements[i] {
r.elements[i][k] = v
}
}
return &r
}
/* -------------------------------------------------------------------------- */
func (obj *KmerCatalogue) AddKmerClass(kmer KmerClass) {
for _, s := range kmer.Elements {
obj.idmap[kmer.K-obj.N][s] = kmer.I
}
obj.elements[kmer.K-obj.N][kmer.I] = kmer.Elements
}
func (obj *KmerCatalogue) GetKmerClassIfPresent(kmer string) (KmerClass, bool) {
k := len(kmer)
if k < obj.N || k > obj.M {
panic("k-mer has invalid length")
}
if i, ok := obj.idmap[k-obj.N][kmer]; ok {
return NewKmerClass(k, i, obj.elements[k-obj.N][i]), true
} else {
return KmerClass{}, false
}
}
func (obj *KmerCatalogue) GetKmerClass(kmer string) KmerClass {
k := len(kmer)
if k < obj.N || k > obj.M {
panic("k-mer has invalid length")
}
if i, ok := obj.idmap[k-obj.N][kmer]; ok {
return NewKmerClass(k, i, obj.elements[k-obj.N][i])
} else {
r := obj.EquivalenceClass(kmer)
obj.AddKmerClass(r)
return r
}
}
func (obj *KmerCatalogue) GetKmerClassFromId(k, id int) KmerClass {
if elements, ok := obj.elements[k-obj.N][id]; ok {
return NewKmerClass(k, id, elements)
}
panic("k-mer name not found")
}
func (obj *KmerCatalogue) CatalogueSize() int {
r := 0
for i := 0; i < len(obj.elements); i++ {
r += len(obj.elements[i])
}
return r
}