Skip to content

Commit

Permalink
Optimize reverse complement
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Nov 13, 2024
1 parent 24f972c commit 1297f63
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 108 deletions.
112 changes: 60 additions & 52 deletions packages/core/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -888,59 +888,67 @@ export const isElectron = /electron/i.test(
typeof navigator !== 'undefined' ? navigator.userAgent : '',
)

export function revcom(seqString: string) {
return reverse(complement(seqString))
}

export function reverse(seqString: string) {
return seqString.split('').reverse().join('')
}

export const complement = (() => {
const complementRegex = /[ACGT]/gi

// from bioperl: tr/acgtrymkswhbvdnxACGTRYMKSWHBVDNX/tgcayrkmswdvbhnxTGCAYRKMSWDVBHNX/
// generated with:
// perl -MJSON -E '@l = split "","acgtrymkswhbvdnxACGTRYMKSWHBVDNX"; print to_json({ map { my $in = $_; tr/acgtrymkswhbvdnxACGTRYMKSWHBVDNX/tgcayrkmswdvbhnxTGCAYRKMSWDVBHNX/; $in => $_ } @l})'
const complementTable = {
S: 'S',
w: 'w',
T: 'A',
r: 'y',
a: 't',
N: 'N',
K: 'M',
x: 'x',
d: 'h',
Y: 'R',
V: 'B',
y: 'r',
M: 'K',
h: 'd',
k: 'm',
C: 'G',
g: 'c',
t: 'a',
A: 'T',
n: 'n',
W: 'W',
X: 'X',
m: 'k',
v: 'b',
B: 'V',
s: 's',
H: 'D',
c: 'g',
D: 'H',
b: 'v',
R: 'Y',
G: 'C',
} as Record<string, string>

return (seqString: string) => {
return seqString.replaceAll(complementRegex, m => complementTable[m] || '')
// from bioperl: tr/acgtrymkswhbvdnxACGTRYMKSWHBVDNX/tgcayrkmswdvbhnxTGCAYRKMSWDVBHNX/
// generated with:
// perl -MJSON -E '@l = split "","acgtrymkswhbvdnxACGTRYMKSWHBVDNX"; print to_json({ map { my $in = $_; tr/acgtrymkswhbvdnxACGTRYMKSWHBVDNX/tgcayrkmswdvbhnxTGCAYRKMSWDVBHNX/; $in => $_ } @l})'
export const complementTable = {
S: 'S',
w: 'w',
T: 'A',
r: 'y',
a: 't',
N: 'N',
K: 'M',
x: 'x',
d: 'h',
Y: 'R',
V: 'B',
y: 'r',
M: 'K',
h: 'd',
k: 'm',
C: 'G',
g: 'c',
t: 'a',
A: 'T',
n: 'n',
W: 'W',
X: 'X',
m: 'k',
v: 'b',
B: 'V',
s: 's',
H: 'D',
c: 'g',
D: 'H',
b: 'v',
R: 'Y',
G: 'C',
} as Record<string, string>

export function revcom(str: string) {
let revcomped = ''
for (let i = str.length - 1; i >= 0; i--) {
revcomped += complementTable[str[i]!] ?? str[i]
}
})()
return revcomped
}

export function reverse(str: string) {
let reversed = ''
for (let i = str.length - 1; i >= 0; i--) {
reversed += str[i]!
}
return reversed
}

export function complement(str: string) {
let comp = ''
for (let i = 0; i < str.length; i++) {

Check failure on line 947 in packages/core/util/index.ts

View workflow job for this annotation

GitHub Actions / Lint, typecheck, test

Expected a `for-of` loop instead of a `for` loop with this simple iteration
comp += complementTable[str[i]!] ?? str[i]
}
return comp
}

// requires immediate execution in jest environment, because (hypothesis) it
// otherwise listens for prerendered_canvas but reads empty pixels, and doesn't
Expand Down
109 changes: 58 additions & 51 deletions plugins/alignments/src/LinearPileupDisplay/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,60 +337,67 @@ function stateModelFactory(configSchema: AnyConfigurationSchemaType) {
{
label: 'Modifications',
type: 'subMenu',
subMenu: [
{
label: 'All modifications',
onClick: () => {
self.setColorScheme({
type: 'modifications',
})
},
},
...self.visibleModificationTypes.map(key => ({
label: `Show only ${modificationData[key]?.name || key}`,
onClick: () => {
self.setColorScheme({
type: 'modifications',
modifications: {
isolatedModification: key,
subMenu: self.modificationsReady
? [
{
label: 'All modifications',
onClick: () => {
self.setColorScheme({
type: 'modifications',
})
},
})
},
})),
{ type: 'divider' },
{
label: 'All modifications (2-color)',
onClick: () => {
self.setColorScheme({
type: 'modifications',
modifications: {
twoColor: true,
},
...self.visibleModificationTypes.map(key => ({
label: `Show only ${modificationData[key]?.name || key}`,
onClick: () => {
self.setColorScheme({
type: 'modifications',
modifications: {
isolatedModification: key,
},
})
},
})
},
},
...self.visibleModificationTypes.map(key => ({
label: `Show only ${modificationData[key]?.name || key} (2-color)`,
onClick: () => {
self.setColorScheme({
type: 'modifications',
modifications: {
isolatedModification: key,
twoColor: true,
})),
{ type: 'divider' },
{
label: 'All modifications (<50% prob colored blue)',
onClick: () => {
self.setColorScheme({
type: 'modifications',
modifications: {
twoColor: true,
},
})
},
})
},
})),
{ type: 'divider' },
{
label: 'All reference CpGs',
onClick: () => {
self.setColorScheme({
type: 'methylation',
})
},
},
],
},
...self.visibleModificationTypes.map(key => ({
label: `Show only ${modificationData[key]?.name || key} (<50% prob colored blue)`,
onClick: () => {
self.setColorScheme({
type: 'modifications',
modifications: {
isolatedModification: key,
twoColor: true,
},
})
},
})),
{ type: 'divider' },
{
label: 'All reference CpGs',
onClick: () => {
self.setColorScheme({
type: 'methylation',
})
},
},
]
: [
{
label: 'Loading modifications...',
onClick: () => {},
},
],
},
{
label: 'Insert size',
Expand Down
2 changes: 1 addition & 1 deletion plugins/alignments/src/shared/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function hasPairedReads(features: ChainData) {
export function alphaColor(baseColor: string, p: number) {
return p !== 1
? colord(baseColor)
.alpha(p * p)
.alpha(p * p * p)
.toHslString()
: baseColor
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ exports[`renders with one feature reversed with a correct seq, zoomed in, should
x="19950"
y="70"
>
B
V
</text>
<rect
fill="#ff9800"
Expand Down Expand Up @@ -204,7 +204,7 @@ exports[`renders with one feature reversed with a correct seq, zoomed in, should
x="19910"
y="70"
>
D
H
</text>
<rect
fill="#aaa"
Expand Down Expand Up @@ -276,7 +276,7 @@ exports[`renders with one feature reversed with a correct seq, zoomed in, should
x="19830"
y="70"
>
H
D
</text>
<rect
fill="#aaa"
Expand Down
6 changes: 5 additions & 1 deletion test_data/config_demo.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"configuration": {},
"configuration": {
"rpc": {
"defaultDriver": "MainThreadRpcDriver"
}
},
"plugins": [
{
"name": "Biothings",
Expand Down

0 comments on commit 1297f63

Please sign in to comment.