jbrowse-plugin-msaview 2.6.2 → 2.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AddHighlightModel/MsaToGenomeHighlight.js +8 -9
- package/dist/LaunchMsaViewExtensionPoint/index.js +12 -5
- package/dist/MsaViewPanel/afterCreateAutoruns.d.ts +0 -2
- package/dist/MsaViewPanel/afterCreateAutoruns.js +8 -81
- package/dist/MsaViewPanel/model.d.ts +3 -28
- package/dist/MsaViewPanel/model.js +5 -103
- package/dist/MsaViewPanel/structureConnection.d.ts +0 -18
- package/dist/MsaViewPanel/types.d.ts +1 -4
- package/dist/jbrowse-plugin-msaview.umd.production.min.js +26 -26
- package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/AddHighlightModel/MsaToGenomeHighlight.tsx +8 -9
- package/src/LaunchMsaViewExtensionPoint/index.ts +12 -5
- package/src/MsaViewPanel/afterCreateAutoruns.ts +8 -109
- package/src/MsaViewPanel/model.ts +4 -135
- package/src/MsaViewPanel/structureConnection.ts +0 -17
- package/src/MsaViewPanel/types.ts +14 -9
- package/src/version.ts +1 -1
- package/dist/MsaViewPanel/components/ConnectStructureDialog.d.ts +0 -7
- package/dist/MsaViewPanel/components/ConnectStructureDialog.js +0 -60
- package/dist/MsaViewPanel/pairwiseAlignment.d.ts +0 -20
- package/dist/MsaViewPanel/pairwiseAlignment.js +0 -138
- package/dist/MsaViewPanel/pairwiseAlignment.test.d.ts +0 -1
- package/dist/MsaViewPanel/pairwiseAlignment.test.js +0 -111
- package/src/MsaViewPanel/components/ConnectStructureDialog.tsx +0 -154
- package/src/MsaViewPanel/pairwiseAlignment.test.ts +0 -140
- package/src/MsaViewPanel/pairwiseAlignment.ts +0 -182
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import BLOSUM62 from './blosum62'
|
|
2
|
-
|
|
3
|
-
function getScore(a: string, b: string) {
|
|
4
|
-
return BLOSUM62[a.toUpperCase()]?.[b.toUpperCase()] ?? -4
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const GAP_OPEN = -10
|
|
8
|
-
const GAP_EXTEND = -0.5
|
|
9
|
-
|
|
10
|
-
interface AlignmentResult {
|
|
11
|
-
alignedSeq1: string
|
|
12
|
-
alignedSeq2: string
|
|
13
|
-
score: number
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface AlignmentRow {
|
|
17
|
-
id: string
|
|
18
|
-
seq: string
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface PairwiseAlignment {
|
|
22
|
-
consensus: string
|
|
23
|
-
alns: readonly [AlignmentRow, AlignmentRow]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function needlemanWunsch(
|
|
27
|
-
seq1: string,
|
|
28
|
-
seq2: string,
|
|
29
|
-
gapOpen = GAP_OPEN,
|
|
30
|
-
gapExtend = GAP_EXTEND,
|
|
31
|
-
): AlignmentResult {
|
|
32
|
-
const m = seq1.length
|
|
33
|
-
const n = seq2.length
|
|
34
|
-
|
|
35
|
-
const M: number[][] = []
|
|
36
|
-
const Ix: number[][] = []
|
|
37
|
-
const Iy: number[][] = []
|
|
38
|
-
|
|
39
|
-
for (let i = 0; i <= m; i++) {
|
|
40
|
-
M[i] = []
|
|
41
|
-
Ix[i] = []
|
|
42
|
-
Iy[i] = []
|
|
43
|
-
for (let j = 0; j <= n; j++) {
|
|
44
|
-
M[i]![j] = -Infinity
|
|
45
|
-
Ix[i]![j] = -Infinity
|
|
46
|
-
Iy[i]![j] = -Infinity
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
M[0]![0] = 0
|
|
51
|
-
for (let i = 1; i <= m; i++) {
|
|
52
|
-
Ix[i]![0] = gapOpen + (i - 1) * gapExtend
|
|
53
|
-
}
|
|
54
|
-
for (let j = 1; j <= n; j++) {
|
|
55
|
-
Iy[0]![j] = gapOpen + (j - 1) * gapExtend
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
for (let i = 1; i <= m; i++) {
|
|
59
|
-
for (let j = 1; j <= n; j++) {
|
|
60
|
-
const matchScore = getScore(seq1[i - 1]!, seq2[j - 1]!)
|
|
61
|
-
|
|
62
|
-
M[i]![j] =
|
|
63
|
-
Math.max(M[i - 1]![j - 1]!, Ix[i - 1]![j - 1]!, Iy[i - 1]![j - 1]!) +
|
|
64
|
-
matchScore
|
|
65
|
-
|
|
66
|
-
Ix[i]![j] = Math.max(M[i - 1]![j]! + gapOpen, Ix[i - 1]![j]! + gapExtend)
|
|
67
|
-
Iy[i]![j] = Math.max(M[i]![j - 1]! + gapOpen, Iy[i]![j - 1]! + gapExtend)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
let alignedSeq1 = ''
|
|
72
|
-
let alignedSeq2 = ''
|
|
73
|
-
let i = m
|
|
74
|
-
let j = n
|
|
75
|
-
|
|
76
|
-
const mScore = M[m]![n]!
|
|
77
|
-
const ixScore = Ix[m]![n]!
|
|
78
|
-
const iyScore = Iy[m]![n]!
|
|
79
|
-
const score = Math.max(mScore, ixScore, iyScore)
|
|
80
|
-
let currentMatrix: 'M' | 'Ix' | 'Iy' =
|
|
81
|
-
score === mScore ? 'M' : score === ixScore ? 'Ix' : 'Iy'
|
|
82
|
-
|
|
83
|
-
while (i > 0 || j > 0) {
|
|
84
|
-
if (currentMatrix === 'M' && i > 0 && j > 0) {
|
|
85
|
-
alignedSeq1 = seq1[i - 1] + alignedSeq1
|
|
86
|
-
alignedSeq2 = seq2[j - 1] + alignedSeq2
|
|
87
|
-
|
|
88
|
-
const matchScore = getScore(seq1[i - 1]!, seq2[j - 1]!)
|
|
89
|
-
const prevM = M[i - 1]![j - 1]!
|
|
90
|
-
const prevIx = Ix[i - 1]![j - 1]!
|
|
91
|
-
const currentScore = M[i]![j]!
|
|
92
|
-
|
|
93
|
-
if (currentScore === prevM + matchScore) {
|
|
94
|
-
currentMatrix = 'M'
|
|
95
|
-
} else if (currentScore === prevIx + matchScore) {
|
|
96
|
-
currentMatrix = 'Ix'
|
|
97
|
-
} else {
|
|
98
|
-
currentMatrix = 'Iy'
|
|
99
|
-
}
|
|
100
|
-
i--
|
|
101
|
-
j--
|
|
102
|
-
} else if (currentMatrix === 'Ix' && i > 0) {
|
|
103
|
-
alignedSeq1 = seq1[i - 1] + alignedSeq1
|
|
104
|
-
alignedSeq2 = '-' + alignedSeq2
|
|
105
|
-
|
|
106
|
-
const ixScore = Ix[i]![j]!
|
|
107
|
-
const mScore = M[i - 1]![j]! + gapOpen
|
|
108
|
-
currentMatrix = ixScore === mScore ? 'M' : 'Ix'
|
|
109
|
-
i--
|
|
110
|
-
} else if (j > 0) {
|
|
111
|
-
alignedSeq1 = '-' + alignedSeq1
|
|
112
|
-
alignedSeq2 = seq2[j - 1] + alignedSeq2
|
|
113
|
-
|
|
114
|
-
const iyScore = Iy[i]![j]!
|
|
115
|
-
const mScore = M[i]![j - 1]! + gapOpen
|
|
116
|
-
currentMatrix = iyScore === mScore ? 'M' : 'Iy'
|
|
117
|
-
j--
|
|
118
|
-
} else {
|
|
119
|
-
break
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return { alignedSeq1, alignedSeq2, score }
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function buildConsensus(alignedSeq1: string, alignedSeq2: string) {
|
|
127
|
-
let consensus = ''
|
|
128
|
-
for (let i = 0; i < alignedSeq1.length; i++) {
|
|
129
|
-
const a = alignedSeq1[i]!
|
|
130
|
-
const b = alignedSeq2[i]!
|
|
131
|
-
const match = a !== '-' && b !== '-' && a.toUpperCase() === b.toUpperCase()
|
|
132
|
-
consensus += match ? '|' : ' '
|
|
133
|
-
}
|
|
134
|
-
return consensus
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export function runPairwiseAlignment(
|
|
138
|
-
seq1: string,
|
|
139
|
-
seq2: string,
|
|
140
|
-
): PairwiseAlignment {
|
|
141
|
-
const { alignedSeq1, alignedSeq2 } = needlemanWunsch(seq1, seq2)
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
consensus: buildConsensus(alignedSeq1, alignedSeq2),
|
|
145
|
-
alns: [
|
|
146
|
-
{ id: 'msa', seq: alignedSeq1 },
|
|
147
|
-
{ id: 'structure', seq: alignedSeq2 },
|
|
148
|
-
],
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export function buildAlignmentMaps(pairwiseAlignment: PairwiseAlignment) {
|
|
153
|
-
const seq1 = pairwiseAlignment.alns[0].seq
|
|
154
|
-
const seq2 = pairwiseAlignment.alns[1].seq
|
|
155
|
-
|
|
156
|
-
if (seq1.length !== seq2.length) {
|
|
157
|
-
throw new Error('Aligned sequences must have same length')
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
let pos1 = 0
|
|
161
|
-
let pos2 = 0
|
|
162
|
-
const seq1ToSeq2 = new Map<number, number>()
|
|
163
|
-
const seq2ToSeq1 = new Map<number, number>()
|
|
164
|
-
|
|
165
|
-
for (let i = 0; i < seq1.length; i++) {
|
|
166
|
-
const c1 = seq1[i]
|
|
167
|
-
const c2 = seq2[i]
|
|
168
|
-
|
|
169
|
-
if (c1 !== '-' && c2 !== '-') {
|
|
170
|
-
seq1ToSeq2.set(pos1, pos2)
|
|
171
|
-
seq2ToSeq1.set(pos2, pos1)
|
|
172
|
-
pos1++
|
|
173
|
-
pos2++
|
|
174
|
-
} else if (c1 === '-') {
|
|
175
|
-
pos2++
|
|
176
|
-
} else {
|
|
177
|
-
pos1++
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return { seq1ToSeq2, seq2ToSeq1 }
|
|
182
|
-
}
|