Skip to content

Commit

Permalink
Fix sequence type choice displaying wrong info (#4449)
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin authored Jun 17, 2024
1 parent fb6972c commit e38c299
Show file tree
Hide file tree
Showing 14 changed files with 217 additions and 134 deletions.
1 change: 0 additions & 1 deletion packages/core/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module.exports = {
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|ts|tsx)'],
staticDirs: ['../public'],
addons: ['@storybook/addon-essentials'],
framework: {
name: '@storybook/react-webpack5',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@ import { SequenceFeatureDetailsF } from './model'
import DLGAP3 from './test_data/DLGAP3'
import NCDN from './test_data/NCDN'

const f = {
start: 1200,
end: 1500,
refName: 'chr1',
strand: 1,
type: 'mRNA',
uniqueId: 'unique',
name: 'made_up',
subfeatures: [
{ refName: 'chr1', start: 1200, end: 1500, type: 'exon' },
{ refName: 'chr1', start: 1200, end: 1500, type: 'CDS' },
],
}

const readFasta = (filename: string) => {
return fs
.readFileSync(require.resolve(filename), 'utf8')
Expand Down Expand Up @@ -129,40 +143,15 @@ test('NCDN updownstream', () => {
)

const element = getByTestId('sequence_panel')

expect(element.textContent).toMatchSnapshot()

// expect(element.children[1].textContent).toEqual(
// 'AGTGGGCAACGCGGCGTGAGCAGCGGCCCGAGGCTCCCGGAGCATCGCGCTGGGAGAAGACTTCGCCGCTCGGGGCCGCAGCCTGGTGAGCTCAGCCCCCTTCGGGCCCTCCCCTGCATCCCAGCCGGGGCCTCTCCGAGCCGGCGCTGATCGATGCCGACACACCCCGGGGACCCTATCGCGACTCCATCGCGCCATATCGCGACACCATCGTGCCCTGTCGAGACTCCATTTTGTCACAGCCCTTTTCAATATATATCTTTTTTTTTTTTAATTTGCCCTGTCATCTTTGGGGGCTGTCTCCCATGTCGTGATTTTGACGTGATCTCTCCGTGACATCACCGCGCCATCGTGAAGTGTGATCTCATCGCCGCCCTGTCGTGACTTCATCA',
// )

// 3rd is a blank element, so go to 4th, not strictly needed for 3rd to be
// blank but helps test
// expect(element.children[3].textContent).toEqual(
// 'ATGTCGTGTTGTGACCTGGCTGCGGCGGGACAG',
// )
})

test('single exon cDNA should not have duplicate sequences', () => {
const seq = readFasta('./test_data/volvox.fa')
const model = SequenceFeatureDetailsF().create()
model.setMode('cdna')
const { getByTestId } = render(
<SequencePanel
model={model}
sequence={{ seq }}
feature={{
start: 1200,
end: 1500,
refName: 'chr1',
type: 'mRNA',
uniqueId: 'unique',
subfeatures: [
{ refName: 'chr1', start: 1200, end: 1500, type: 'exon' },
{ refName: 'chr1', start: 1200, end: 1500, type: 'CDS' },
],
}}
/>,
<SequencePanel model={model} sequence={{ seq }} feature={f} />,
)

const element = getByTestId('sequence_panel')
Expand All @@ -177,3 +166,29 @@ test('single exon cDNA should not have duplicate sequences', () => {
'ATGTCACCTCGGGTACTGCCTCTATTACAGAGGTATCTTAATGGCGCATCCAGCCTTGTGGCTGGGTCTACGTACGCGTGGGCACCATACGTATGTTGGCAGGAAAGGTCAATCATGCTTGTTTCCTCGTCGCAGAAACGTTCACACTATTGGCTCGCGGGATCGAACGGGCCTGATTATTTTTCCAGCTCCTGCGTTCCTATCACGCCAACTGTCGCTAATAAAATGTTATATAGAGATAACCCATTGCTATGCAAGGATGGAGAAACCGCTTCACAACACCCTAGAATTACTTCAGCA',
)
})

test('single exon cDNA display genomic coords', () => {
const seq = readFasta('./test_data/volvox.fa')
const model = SequenceFeatureDetailsF().create()
model.setMode('gene')
model.setShowCoordinates('genomic')
const { getByTestId } = render(
<SequencePanel model={model} sequence={{ seq }} feature={f} />,
)

const element = getByTestId('sequence_panel')
expect(element.textContent).toMatchSnapshot()
})

test('single exon cDNA display relative coords', () => {
const seq = readFasta('./test_data/volvox.fa')
const model = SequenceFeatureDetailsF().create()
model.setMode('gene')
model.setShowCoordinates('relative')
const { getByTestId } = render(
<SequencePanel model={model} sequence={{ seq }} feature={f} />,
)

const element = getByTestId('sequence_panel')
expect(element.textContent).toMatchSnapshot()
})
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { lazy, useRef, useState, Suspense } from 'react'
import React, { lazy, useRef, useState, Suspense, useEffect } from 'react'
import { Button, Typography } from '@mui/material'
import { observer } from 'mobx-react'

// locals
import { useFeatureSequence } from './hooks'
import { ErrorMessage, LoadingEllipses } from '../../ui'
import { SimpleFeatureSerialized, getSession } from '../../util'
import { SimpleFeatureSerialized } from '../../util'
import { BaseFeatureWidgetModel } from '../stateModelFactory'

// icons
Expand All @@ -29,74 +29,86 @@ const SequenceFeatureDetails = observer(function ({
const { upDownBp } = sequenceFeatureDetails
const seqPanelRef = useRef<HTMLDivElement>(null)

const [openInDialog, setOpenInDialog] = useState(false)
const [force, setForce] = useState(false)
const { sequence, error } = useFeatureSequence(
model,
feature,
upDownBp,
force,
)
useEffect(() => {
sequenceFeatureDetails.setFeature(feature)
}, [sequenceFeatureDetails, feature])

return (
<>
<div>
<SequenceTypeSelector
feature={feature}
model={sequenceFeatureDetails}
/>

<SequenceTypeSelector model={sequenceFeatureDetails} />
<SequenceFeatureMenu
ref={seqPanelRef}
model={sequenceFeatureDetails}
extraItems={[
{
label: 'Open in dialog',
onClick: () => {
getSession(model).queueDialog(handleClose => [
SequenceDialog,
{ model, feature, handleClose },
])
// this is given a setTimeout because it allows the menu to
// close before dialog opens
setTimeout(() => setOpenInDialog(true), 1)
},
},
]}
/>
</div>
<div>
{feature.type === 'gene' ? (
<Typography>
Note: inspect subfeature sequences for protein/CDS computations
</Typography>
) : null}
{error ? (
<ErrorMessage error={error} />
) : !sequence ? (
<LoadingEllipses />
) : sequence ? (
'error' in sequence ? (
<>
<Typography color="error">{sequence.error}</Typography>
<Button
variant="contained"
color="inherit"
onClick={() => setForce(true)}
>
Force load
</Button>
</>
{openInDialog ? (
<div>
Open in dialog...
<Suspense fallback={<LoadingEllipses />}>
<SequenceDialog
model={model}
feature={feature}
handleClose={() => setOpenInDialog(false)}
/>
</Suspense>
</div>
) : (
<div>
{feature.type === 'gene' ? (
<Typography>
Note: inspect subfeature sequences for protein/CDS computations
</Typography>
) : null}
{error ? (
<ErrorMessage error={error} />
) : !sequence ? (
<LoadingEllipses />
) : sequence ? (
'error' in sequence ? (
<>
<Typography color="error">{sequence.error}</Typography>
<Button
variant="contained"
color="inherit"
onClick={() => setForce(true)}
>
Force load
</Button>
</>
) : (
<Suspense fallback={<LoadingEllipses />}>
<SequencePanel
ref={seqPanelRef}
feature={feature}
sequence={sequence}
model={sequenceFeatureDetails}
/>
</Suspense>
)
) : (
<Suspense fallback={<LoadingEllipses />}>
<SequencePanel
ref={seqPanelRef}
feature={feature}
sequence={sequence}
model={sequenceFeatureDetails}
/>
</Suspense>
)
) : (
<Typography>No sequence found</Typography>
)}
</div>
<Typography>No sequence found</Typography>
)}
</div>
)}
</>
)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
defaultCodonTable,
generateCodonTable,
revcom,
toLocale,
} from '../../util'
import {
SeqState,
Expand Down Expand Up @@ -137,9 +138,9 @@ const SequencePanel = observer(
<div style={{ background: 'white' }}>
{`>${[
(feature.name || feature.id) + '-' + mode,
`${feature.refName}:${feature.start + 1}-${feature.end}(${getStrand(feature.strand as number)})`,
`${feature.refName}:${toLocale(feature.start + 1)}-${toLocale(feature.end)}(${getStrand(feature.strand as number)})`,
mode.endsWith('updownstream')
? `+/- ${model.upDownBp} up/downstream bp`
? `+/- ${toLocale(model.upDownBp)} up/downstream bp`
: '',
]
.filter(f => !!f)
Expand Down
Loading

0 comments on commit e38c299

Please sign in to comment.