Skip to content

Commit

Permalink
Fix for negative strand features
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Mar 4, 2021
1 parent c6583f9 commit 3be7cb3
Showing 1 changed file with 52 additions and 43 deletions.
95 changes: 52 additions & 43 deletions packages/core/BaseFeatureWidget/BaseFeatureDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
getSession,
defaultCodonTable,
generateCodonTable,
revcom,
} from '../util'
import { Feature } from '../util/simpleFeature'
import SanitizedHTML from '../ui/SanitizedHTML'
Expand Down Expand Up @@ -214,6 +215,17 @@ interface BaseProps extends BaseCardProps {
model?: any
}

function stitch(subfeats: any, feature: any, sequence: string) {
let chunks = subfeats.map((sub: any) => {
const chunk = sequence.slice(sub.start, sub.end)
return feature.strand === -1 ? revcom(chunk) : chunk
})
if (feature.strand === -1) {
chunks = chunks.reverse()
}
return chunks.join('')
}

// display the stitched-together sequence of a gene's CDS, cDNA, or protein
// sequence. this is a best effort and weird genomic phenomena could lead these
// to not be 100% accurate
Expand Down Expand Up @@ -262,6 +274,7 @@ function SequenceFeatureDetails(props: BaseProps) {

const text: React.ReactNode[] = []
if (sequence && feature) {
const { strand } = feature
const children = feature.subfeatures
.sort((a: any, b: any) => a.start - b.start)
.map((sub: any) => {
Expand All @@ -280,47 +293,46 @@ function SequenceFeatureDetails(props: BaseProps) {
const exons = children.filter((sub: any) => sub.type === 'exon')

if (mode === 'cds') {
cds.forEach((sub: any) => {
text.push(
<div
key={`cds-${feature.start}-${feature.end}`}
style={{
display: 'inline',
backgroundColor: cdsColor,
}}
>
{stitch(cds, feature, sequence)}
</div>,
)
} else if (mode === 'cdna') {
// if we have CDS, it is a real gene, color the difference between the
// start and end of the CDS as UTR and the rest as CDS
if (cds.length) {
text.push(
<div
key={`${sub.start}-${sub.end}`}
key="5prime_utr"
style={{
display: 'inline',
backgroundColor: cdsColor,
backgroundColor: utrColor,
}}
>
{sequence.slice(sub.start, sub.end)}
{feature.strand === -1
? revcom(sequence.slice(cds[cds.length - 1].end))
: sequence.slice(0, cds[0].start)}
</div>,
)
})
} else if (mode === 'cdna') {
// if we have CDS, it is a real gene, color the difference between the
// start and end of the CDS as UTR and the rest as CDS
if (cds.length) {

text.push(
<div
key="5prime_utr"
key={`cds-${feature.start}-${feature.end}`}
style={{
display: 'inline',
backgroundColor: utrColor,
backgroundColor: cdsColor,
}}
>
{sequence.slice(0, cds[0].start)}
{stitch(cds, feature, sequence)}
</div>,
)
cds.forEach((sub: any) => {
text.push(
<div
key={`${sub.start}-${sub.end}`}
style={{
display: 'inline',
backgroundColor: cdsColor,
}}
>
{sequence.slice(sub.start, sub.end)}
</div>,
)
})

text.push(
<div
Expand All @@ -330,31 +342,28 @@ function SequenceFeatureDetails(props: BaseProps) {
backgroundColor: utrColor,
}}
>
{sequence.slice(cds[cds.length - 1].end)}
{feature.strand === -1
? revcom(sequence.slice(0, cds[0].start))
: sequence.slice(cds[cds.length - 1].end)}
</div>,
)
}
// no CDS, probably a pseudogene, color whole thing as "UTR"
else {
exons.forEach((sub: any) => {
text.push(
<div
key={`${sub.start}-${sub.end}`}
style={{
display: 'inline',
backgroundColor: utrColor,
}}
>
{sequence.slice(sub.start, sub.end)}
</div>,
)
})
text.push(
<div
key={`cdna-${feature.start}-${feature.end}`}
style={{
display: 'inline',
backgroundColor: utrColor,
}}
>
{stitch(exons, feature, sequence)}
</div>,
)
}
} else if (mode === 'protein') {
let str = ''
cds.forEach((sub: any) => {
str += sequence.slice(sub.start, sub.end)
})
const str = stitch(cds, feature, sequence)
let protein = ''
for (let i = 0; i < str.length; i += 3) {
protein += codonTable[str.slice(i, i + 3)]
Expand Down

0 comments on commit 3be7cb3

Please sign in to comment.