Skip to content

Commit

Permalink
Add case for non-coding
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Apr 23, 2024
1 parent 1923aba commit 330454c
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { lazy, useRef, useState, Suspense } from 'react'
import {
Button,
FormControl,
IconButton,
MenuItem,
Select,
Typography,
Expand All @@ -15,15 +16,13 @@ import { useFeatureSequence } from './hooks'
import { ErrorMessage, LoadingEllipses } from '../../ui'
import { SimpleFeatureSerialized, getSession } from '../../util'
import { BaseFeatureWidgetModel } from '../stateModelFactory'
import CascadingMenuButton from '../../ui/CascadingMenuButton'

// icons
import MoreVert from '@mui/icons-material/MoreVert'
import Settings from '@mui/icons-material/Settings'

// lazies
const SequencePanel = lazy(() => import('./SequencePanel'))
const SettingsDialog = lazy(() => import('./dialogs/SettingsDialog'))
const HelpDialog = lazy(() => import('./dialogs/HelpDialog'))
const AdvancedSequenceDialog = lazy(
() => import('./dialogs/AdvancedSequenceDialog'),
)
Expand Down Expand Up @@ -67,7 +66,7 @@ const SequenceFeatureDetails = observer(function ({

return (
<>
<span>
<div>
<FormControl className={classes.formControl}>
<Select
size="small"
Expand Down Expand Up @@ -128,49 +127,43 @@ const SequenceFeatureDetails = observer(function ({
))}
</Select>
</FormControl>
<Button
className={classes.formControl}
variant="contained"
onClick={() => {
const ref = seqPanelRef.current
if (ref) {
copy(ref.textContent || '', { format: 'text/plain' })
}
}}
>
Copy plaintext
</Button>
<Button
className={classes.formControl}
variant="contained"
onClick={() => {
const ref = seqPanelRef.current
if (ref) {
copy(ref.innerHTML, { format: 'text/html' })
}
}}
>
Copy HTML
</Button>

<CascadingMenuButton
menuItems={[
{
label: 'Copy plaintext',
onClick: () => {
const ref = seqPanelRef.current
if (ref) {
copy(ref.textContent || '', { format: 'text/plain' })
}
},
},
{
label: 'Copy HTML',
onClick: () => {
const ref = seqPanelRef.current
if (ref) {
copy(ref.innerHTML, { format: 'text/html' })
}
},
},

{
label: 'Settings',
onClick: () =>
getSession(model).queueDialog(handleClose => [
SettingsDialog,
{ model: sequenceFeatureDetails, handleClose },
]),
},
{
label: 'Help',
onClick: () =>
getSession(model).queueDialog(handleClose => [
HelpDialog,
{ handleClose },
]),
},
]}
<IconButton
className={classes.formControl}
onClick={() =>
getSession(model).queueDialog(handleClose => [
SettingsDialog,
{ model: sequenceFeatureDetails, handleClose },
])
}
>
<MoreVert />
</CascadingMenuButton>
</span>
<Settings />
</IconButton>
</div>
<div>
{feature.type === 'gene' ? (
<Typography>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import React, { lazy, useState, Suspense } from 'react'
import { Button, FormControl } from '@mui/material'
import { Button, FormControl, IconButton } from '@mui/material'
import { observer } from 'mobx-react'
import { makeStyles } from 'tss-react/mui'

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

// icons
import Help from '@mui/icons-material/Help'

// lazies
const SequenceFeatureDetails = lazy(() => import('./SequenceFeatureDetails'))
const HelpDialog = lazy(() => import('./dialogs/HelpDialog'))

const useStyles = makeStyles()(theme => ({
formControl: {
Expand Down Expand Up @@ -39,9 +43,20 @@ const SequenceFeaturePanel = observer(function ({
<div className={classes.container}>
<FormControl className={classes.formControl}>
<Button variant="contained" onClick={() => setShown(!shown)}>
{shown ? 'Hide sequence' : 'Show sequence'}
{shown ? 'Hide feature sequence' : 'Show feature sequence'}
</Button>
</FormControl>

<IconButton
onClick={() =>
getSession(model).queueDialog(handleClose => [
HelpDialog,
{ handleClose },
])
}
>
<Help />
</IconButton>
{shown ? (
<Suspense fallback={<LoadingEllipses />}>
<SequenceFeatureDetails
Expand Down
93 changes: 47 additions & 46 deletions packages/core/BaseFeatureWidget/SequenceFeatureDetails/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,56 +21,57 @@ export function useFeatureSequence(
const [sequence, setSequence] = useState<SeqState | ErrorState>()
const [error, setError] = useState<unknown>()
useEffect(() => {
if (model) {
const { assemblyManager, rpcManager } = getSession(model)
const [assemblyName] = model.view?.assemblyNames || []
async function fetchSeq(start: number, end: number, refName: string) {
const assembly = await assemblyManager.waitForAssembly(assemblyName)
if (!assembly) {
throw new Error('assembly not found')
}
const sessionId = 'getSequence'
const feats = await rpcManager.call(sessionId, 'CoreGetFeatures', {
adapterConfig: getConf(assembly, ['sequence', 'adapter']),
sessionId,
regions: [
{
start,
end,
refName: assembly.getCanonicalRefName(refName),
assemblyName,
},
],
})

const [feat] = feats as Feature[]
return (feat?.get('seq') as string | undefined) || ''
if (!model) {
return
}
const { assemblyManager, rpcManager } = getSession(model)
const [assemblyName] = model.view?.assemblyNames || []
async function fetchSeq(start: number, end: number, refName: string) {
const assembly = await assemblyManager.waitForAssembly(assemblyName)
if (!assembly) {
throw new Error('assembly not found')
}
const sessionId = 'getSequence'
const feats = await rpcManager.call(sessionId, 'CoreGetFeatures', {
adapterConfig: getConf(assembly, ['sequence', 'adapter']),
sessionId,
regions: [
{
start,
end,
refName: assembly.getCanonicalRefName(refName),
assemblyName,
},
],
})

// eslint-disable-next-line @typescript-eslint/no-floating-promises
;(async () => {
try {
setError(undefined)
const { start, end, refName } = feature as CoordFeat
const [feat] = feats as Feature[]
return (feat?.get('seq') as string | undefined) || ''
}

if (!forceLoad && end - start > BPLIMIT) {
setSequence({
error: `Genomic sequence larger than ${BPLIMIT}bp, use "force load" button to display`,
})
} else {
const b = start - upDownBp
const e = end + upDownBp
const seq = await fetchSeq(start, end, refName)
const up = await fetchSeq(Math.max(0, b), start, refName)
const down = await fetchSeq(end, e, refName)
setSequence({ seq, upstream: up, downstream: down })
}
} catch (e) {
console.error(e)
setError(e)
// eslint-disable-next-line @typescript-eslint/no-floating-promises
;(async () => {
try {
setError(undefined)
const { start, end, refName } = feature as CoordFeat

if (!forceLoad && end - start > BPLIMIT) {
setSequence({
error: `Genomic sequence larger than ${BPLIMIT}bp, use "force load" button to display`,
})
} else {
const b = start - upDownBp
const e = end + upDownBp
const seq = await fetchSeq(start, end, refName)
const up = await fetchSeq(Math.max(0, b), start, refName)
const down = await fetchSeq(end, e, refName)
setSequence({ seq, upstream: up, downstream: down })
}
})()
}
} catch (e) {
console.error(e)
setError(e)
}
})()
}, [feature, model, upDownBp, forceLoad])
return { sequence, error }
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const CDNASequence = observer(function ({
model: SequenceFeatureDetailsModel
}) {
const { upperCaseCDS, intronBp } = model
const hasCds = cds.length > 0
const chunks = (
cds.length ? [...cds, ...utr].sort((a, b) => a.start - b.start) : exons
).filter(f => f.start !== f.end)
Expand All @@ -51,9 +52,11 @@ const CDNASequence = observer(function ({
background: chunk.type === 'CDS' ? cdsColor : utrColor,
}}
>
{chunk.type === 'CDS'
? toUpper(sequence.slice(chunk.start, chunk.end))
: toLower(sequence.slice(chunk.start, chunk.end))}
{hasCds
? chunk.type === 'CDS'
? toUpper(sequence.slice(chunk.start, chunk.end))
: toLower(sequence.slice(chunk.start, chunk.end))
: toUpper(sequence.slice(chunk.start, chunk.end))}
</span>
{includeIntrons && idx < chunks.length - 1 ? (
<span style={{ background: intronColor }}>
Expand Down

0 comments on commit 330454c

Please sign in to comment.