Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix sequence type choice displaying wrong info #4449

Merged
merged 4 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading