diff --git a/packages/apollo-mst/src/AnnotationFeatureModel.ts b/packages/apollo-mst/src/AnnotationFeatureModel.ts
index dc093d34f..cf5b07cff 100644
--- a/packages/apollo-mst/src/AnnotationFeatureModel.ts
+++ b/packages/apollo-mst/src/AnnotationFeatureModel.ts
@@ -1,4 +1,4 @@
-import { intersection2 } from '@jbrowse/core/util'
+import { getSession, intersection2 } from '@jbrowse/core/util'
import {
IAnyModelType,
IMSTMap,
@@ -109,7 +109,14 @@ export const AnnotationFeatureModel = types
return false
},
get cdsLocations(): { min: number; max: number; phase: 0 | 1 | 2 }[][] {
- if (self.type !== 'mRNA') {
+ // 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
+ const { apolloDataStore } = session
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
+ const { featureTypeOntology } = apolloDataStore.ontologyManager
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
+ if (!featureTypeOntology.isTypeOf(self.type, 'mRNA')) {
throw new Error(
'Only features of type "mRNA" or equivalent can calculate CDS locations',
)
@@ -119,7 +126,8 @@ export const AnnotationFeatureModel = types
throw new Error('no CDS or exons in mRNA')
}
const cdsChildren = [...children.values()].filter(
- (child) => child.type === 'CDS',
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
+ (child) => featureTypeOntology.isTypeOf(child.type, 'CDS'),
)
if (cdsChildren.length === 0) {
throw new Error('no CDS in mRNA')
@@ -130,7 +138,8 @@ export const AnnotationFeatureModel = types
const { max: cdsMax, min: cdsMin } = cds
const locs: { min: number; max: number }[] = []
for (const [, child] of children) {
- if (child.type !== 'exon') {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
+ if (!featureTypeOntology.isTypeOf(child.type, 'exon')) {
continue
}
const [start, end] = intersection2(
diff --git a/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/TranscriptBasic.tsx b/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/TranscriptBasic.tsx
index acc7db878..9b25f310a 100644
--- a/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/TranscriptBasic.tsx
+++ b/packages/jbrowse-plugin-apollo/src/FeatureDetailsWidget/TranscriptBasic.tsx
@@ -83,8 +83,11 @@ export const TranscriptBasicInformation = observer(
const { notify } = session as unknown as AbstractSessionModel
const currentAssembly = session.apolloDataStore.assemblies.get(assembly)
const refData = currentAssembly?.getByRefName(refName)
- const { changeManager } = session.apolloDataStore
-
+ const { changeManager, ontologyManager } = session.apolloDataStore
+ const { featureTypeOntology } = ontologyManager
+ if (!featureTypeOntology) {
+ throw new Error('featureTypeOntology is undefined')
+ }
function handleStartChange(
newStart: number,
featureId: string,
@@ -100,10 +103,14 @@ export const TranscriptBasicInformation = observer(
if (!subFeature?.children) {
return
}
+ if (!featureTypeOntology) {
+ throw new Error('featureTypeOntology is undefined')
+ }
// Let's check CDS start and end values. And possibly update those too
for (const child of subFeature.children) {
if (
- (child[1].type === 'CDS' || child[1].type === 'exon') &&
+ (featureTypeOntology.isTypeOf(child[1].type, 'CDS') ||
+ featureTypeOntology.isTypeOf(child[1].type, 'exon')) &&
child[1].min === oldStart
) {
const change = new LocationStartChange({
@@ -135,10 +142,14 @@ export const TranscriptBasicInformation = observer(
if (!subFeature?.children) {
return
}
+ if (!featureTypeOntology) {
+ throw new Error('featureTypeOntology is undefined')
+ }
// Let's check CDS start and end values. And possibly update those too
for (const child of subFeature.children) {
if (
- (child[1].type === 'CDS' || child[1].type === 'exon') &&
+ (featureTypeOntology.isTypeOf(child[1].type, 'CDS') ||
+ featureTypeOntology.isTypeOf(child[1].type, 'exon')) &&
child[1].max === oldEnd
) {
const change = new LocationEndChange({
@@ -160,7 +171,7 @@ export const TranscriptBasicInformation = observer(
const featureNew = feature
let exonsArray: ExonInfo[] = []
const traverse = (currentFeature: AnnotationFeature) => {
- if (currentFeature.type === 'exon') {
+ if (featureTypeOntology.isTypeOf(currentFeature.type, 'exon')) {
exonsArray.push({
min: currentFeature.min + 1,
max: currentFeature.max,
@@ -384,10 +395,10 @@ export const TranscriptBasicInformation = observer(
{transcriptItems.map((item, index) => (
- {item.type === 'three_prime_UTR'
+ {featureTypeOntology.isTypeOf(item.type, 'three_prime_UTR')
? '3 UTR'
: // eslint-disable-next-line unicorn/no-nested-ternary
- item.type === 'five_prime_UTR'
+ featureTypeOntology.isTypeOf(item.type, 'five_prime_UTR')
? '5 UTR'
: 'CDS'}
@@ -397,7 +408,7 @@ export const TranscriptBasicInformation = observer(
{
const CDSresult: CDSInfo[] = []
const traverse = (
@@ -36,9 +38,9 @@ const getCDSInfo = (
) => {
if (
isParentMRNA &&
- (currentFeature.type === 'CDS' ||
- currentFeature.type === 'three_prime_UTR' ||
- currentFeature.type === 'five_prime_UTR')
+ (featureTypeOntology.isTypeOf(currentFeature.type, 'CDS') ||
+ featureTypeOntology.isTypeOf(currentFeature.type, 'three_prime_UTR') ||
+ featureTypeOntology.isTypeOf(currentFeature.type, 'five_prime_UTR'))
) {
let startSeq = refData.getSequence(
Number(currentFeature.min) - 2,
@@ -149,14 +151,22 @@ export const TranscriptSequence = observer(function TranscriptSequence({
if (!refSeq) {
return null
}
- const transcriptItems = getCDSInfo(feature, refData)
+ const { featureTypeOntology } = session.apolloDataStore.ontologyManager
+ if (!featureTypeOntology) {
+ throw new Error('featureTypeOntology is undefined')
+ }
+ const transcriptItems = getCDSInfo(feature, refData, featureTypeOntology)
const { max, min } = feature
let sequence = ''
if (showSequence) {
- getSequenceAsString(min, max)
+ getSequenceAsString(min, max, featureTypeOntology)
}
- function getSequenceAsString(start: number, end: number): string {
+ function getSequenceAsString(
+ start: number,
+ end: number,
+ featureTypeOntology: OntologyRecord,
+ ): string {
sequence = refSeq?.getSequence(start, end) ?? ''
if (sequence === '') {
void session.apolloDataStore.loadRefSeq([
@@ -165,7 +175,7 @@ export const TranscriptSequence = observer(function TranscriptSequence({
} else {
sequence = formatSequence(sequence, refName, start, end)
}
- getSequenceAsTextSegment(selectedOption) // For color coded sequence
+ getSequenceAsTextSegment(selectedOption, featureTypeOntology) // For color coded sequence
return sequence
}
@@ -173,7 +183,10 @@ export const TranscriptSequence = observer(function TranscriptSequence({
setShowSequence(!showSequence)
}
- function getSequenceAsTextSegment(option: string) {
+ function getSequenceAsTextSegment(
+ option: string,
+ featureTypeOntology: OntologyRecord,
+ ) {
let seqData = ''
textSegments = []
if (!refData) {
@@ -183,7 +196,7 @@ export const TranscriptSequence = observer(function TranscriptSequence({
case 'CDS': {
textSegments.push({ text: `>${refName} : CDS\n`, color: 'black' })
for (const item of transcriptItems) {
- if (item.type === 'CDS') {
+ if (featureTypeOntology.isTypeOf(item.type, 'CDS')) {
const refSeq: string = refData.getSequence(
Number(item.min + 1),
Number(item.max),
@@ -198,16 +211,16 @@ export const TranscriptSequence = observer(function TranscriptSequence({
textSegments.push({ text: `>${refName} : cDNA\n`, color: 'black' })
for (const item of transcriptItems) {
if (
- item.type === 'CDS' ||
- item.type === 'three_prime_UTR' ||
- item.type === 'five_prime_UTR'
+ featureTypeOntology.isTypeOf(item.type, 'CDS') ||
+ featureTypeOntology.isTypeOf(item.type, 'three_prime_UTR') ||
+ featureTypeOntology.isTypeOf(item.type, 'five_prime_UTR')
) {
const refSeq: string = refData.getSequence(
Number(item.min + 1),
Number(item.max),
)
seqData += item.strand === -1 && refSeq ? revcom(refSeq) : refSeq
- if (item.type === 'CDS') {
+ if (featureTypeOntology.isTypeOf(item.type, 'CDS')) {
textSegments.push({ text: seqData, color: cdsColor })
} else {
textSegments.push({ text: seqData, color: utrColor })
@@ -239,9 +252,9 @@ export const TranscriptSequence = observer(function TranscriptSequence({
textSegments.push({ text: seqData, color: 'black' })
}
if (
- item.type === 'CDS' ||
- item.type === 'three_prime_UTR' ||
- item.type === 'five_prime_UTR'
+ featureTypeOntology.isTypeOf(item.type, 'CDS') ||
+ featureTypeOntology.isTypeOf(item.type, 'three_prime_UTR') ||
+ featureTypeOntology.isTypeOf(item.type, 'five_prime_UTR')
) {
const refSeq: string = refData.getSequence(
Number(item.min + 1),
@@ -274,10 +287,13 @@ export const TranscriptSequence = observer(function TranscriptSequence({
}
}
- function handleChangeSeqOption(e: SelectChangeEvent) {
+ function handleChangeSeqOption(
+ e: SelectChangeEvent,
+ featureTypeOntology: OntologyRecord,
+ ) {
const option = e.target.value
setSelectedOption(option)
- getSequenceAsTextSegment(option)
+ getSequenceAsTextSegment(option, featureTypeOntology)
}
// Function to copy text to clipboard
@@ -329,7 +345,9 @@ export const TranscriptSequence = observer(function TranscriptSequence({
{showSequence && (