Skip to content

Commit

Permalink
Merge branch 'main' into feedback-ontology-loading
Browse files Browse the repository at this point in the history
  • Loading branch information
dariober committed Nov 25, 2024
2 parents a4c195b + 1433542 commit bd97982
Show file tree
Hide file tree
Showing 10 changed files with 490 additions and 720 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ export class JBrowseService {
quaternary: {
main: '#571AA3',
},
framesCDS: [
null,
{ main: 'rgb(204,121,167)' },
{ main: 'rgb(230,159,0)' },
{ main: 'rgb(240,228,66)' },
{ main: 'rgb(86,180,233)' },
{ main: 'rgb(0,114,178)' },
{ main: 'rgb(0,158,115)' },
],
},
},
ApolloPlugin: {
Expand Down
95 changes: 83 additions & 12 deletions packages/apollo-mst/src/AnnotationFeatureModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ const LateAnnotationFeature = types.late(
(): IAnyModelType => AnnotationFeatureModel,
)

export interface TranscriptPartLocation {
min: number
max: number
}

export interface TranscriptPartNonCoding extends TranscriptPartLocation {
type: 'fivePrimeUTR' | 'threePrimeUTR' | 'intron'
}

export interface TranscriptPartCoding extends TranscriptPartLocation {
type: 'CDS'
phase: 0 | 1 | 2
}

export type TranscriptPart = TranscriptPartCoding | TranscriptPartNonCoding

type TranscriptParts = TranscriptPart[]

export const AnnotationFeatureModel = types
.model('AnnotationFeatureModel', {
_id: types.identifier,
Expand Down Expand Up @@ -108,7 +126,7 @@ export const AnnotationFeatureModel = types
}
return false
},
get cdsLocations(): { min: number; max: number; phase: 0 | 1 | 2 }[][] {
get transcriptParts(): TranscriptParts[] {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
const session = getSession(self) as any
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
Expand All @@ -132,42 +150,95 @@ export const AnnotationFeatureModel = types
if (cdsChildren.length === 0) {
throw new Error('no CDS in mRNA')
}
const cdsLocations: { min: number; max: number; phase: 0 | 1 | 2 }[][] =
[]
const transcriptParts: TranscriptParts[] = []
for (const cds of cdsChildren) {
const { max: cdsMax, min: cdsMin } = cds
const locs: { min: number; max: number }[] = []
const parts: TranscriptParts = []
let hasIntersected = false
const exonLocations: TranscriptPartLocation[] = []
for (const [, child] of children) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
if (!featureTypeOntology.isTypeOf(child.type, 'exon')) {
continue
if (featureTypeOntology.isTypeOf(child.type, 'exon')) {
exonLocations.push({ min: child.min, max: child.max })
}
}
exonLocations.sort(({ min: a }, { min: b }) => a - b)
for (const child of exonLocations) {
const lastPart = parts.at(-1)
if (lastPart) {
parts.push({ min: lastPart.max, max: child.min, type: 'intron' })
}
const [start, end] = intersection2(
cdsMin,
cdsMax,
child.min,
child.max,
)
let utrType: 'fivePrimeUTR' | 'threePrimeUTR'
if (hasIntersected) {
utrType = self.strand === 1 ? 'threePrimeUTR' : 'fivePrimeUTR'
} else {
utrType = self.strand === 1 ? 'fivePrimeUTR' : 'threePrimeUTR'
}
if (start !== undefined && end !== undefined) {
locs.push({ min: start, max: end })
hasIntersected = true
if (start === child.min && end === child.max) {
parts.push({ min: start, max: end, phase: 0, type: 'CDS' })
} else if (start === child.min) {
parts.push(
{ min: start, max: end, phase: 0, type: 'CDS' },
{ min: end, max: child.max, type: utrType },
)
} else if (end === child.max) {
parts.push(
{ min: child.min, max: start, type: utrType },
{ min: start, max: end, phase: 0, type: 'CDS' },
)
} else {
parts.push(
{ min: child.min, max: start, type: utrType },
{ min: start, max: end, phase: 0, type: 'CDS' },
{
min: end,
max: child.max,
type:
utrType === 'fivePrimeUTR'
? 'threePrimeUTR'
: 'fivePrimeUTR',
},
)
}
} else {
parts.push({ min: child.min, max: child.max, type: utrType })
}
}
locs.sort(({ min: a }, { min: b }) => a - b)
parts.sort(({ min: a }, { min: b }) => a - b)
if (self.strand === -1) {
locs.reverse()
parts.reverse()
}
let nextPhase: 0 | 1 | 2 = 0
const phasedLocs = locs.map((loc) => {
const phasedParts = parts.map((loc) => {
if (loc.type !== 'CDS') {
return loc
}
const phase = nextPhase
nextPhase = ((3 - ((loc.max - loc.min - phase + 3) % 3)) % 3) as
| 0
| 1
| 2
return { ...loc, phase }
})
cdsLocations.push(phasedLocs)
transcriptParts.push(phasedParts)
}
return cdsLocations
return transcriptParts
},
}))
.views((self) => ({
get cdsLocations(): TranscriptPartCoding[][] {
const { transcriptParts } = self
return transcriptParts.map((transcript) =>
transcript.filter((transcriptPart) => transcriptPart.type === 'CDS'),
)
},
}))
.actions((self) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,7 @@ export const Attributes = observer(function Attributes({

return (
<>
<Typography
style={{ display: 'inline', marginLeft: '15px' }}
variant="h5"
>
Attributes
</Typography>
<Typography variant="h5">Attributes</Typography>
<Grid container direction="column" spacing={1}>
{Object.entries(attributes).map(([key, value]) => {
if (key === '') {
Expand Down
Loading

0 comments on commit bd97982

Please sign in to comment.