@jbrowse/plugin-linear-comparative-view 2.6.1 → 2.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LGVSyntenyDisplay/configSchemaF.d.ts +1 -3
- package/dist/LGVSyntenyDisplay/configSchemaF.js +0 -1
- package/dist/LGVSyntenyDisplay/index.js +0 -1
- package/dist/LGVSyntenyDisplay/model.d.ts +17 -76
- package/dist/LGVSyntenyDisplay/model.js +22 -4
- package/dist/LaunchLinearSyntenyView.js +0 -1
- package/dist/LinearComparativeDisplay/configSchemaF.js +0 -1
- package/dist/LinearComparativeDisplay/index.js +0 -1
- package/dist/LinearComparativeDisplay/stateModelFactory.js +0 -1
- package/dist/LinearComparativeView/components/Header.js +11 -2
- package/dist/LinearComparativeView/components/LinearComparativeView.js +0 -1
- package/dist/LinearComparativeView/components/Rubberband.js +11 -33
- package/dist/LinearComparativeView/components/VerticalGuide.d.ts +8 -0
- package/dist/LinearComparativeView/components/VerticalGuide.js +33 -0
- package/dist/LinearComparativeView/index.js +0 -1
- package/dist/LinearComparativeView/model.d.ts +9 -15
- package/dist/LinearComparativeView/model.js +0 -1
- package/dist/LinearReadVsRef/LinearReadVsRef.js +0 -1
- package/dist/LinearReadVsRef/index.js +0 -1
- package/dist/LinearSyntenyDisplay/afterAttach.js +0 -1
- package/dist/LinearSyntenyDisplay/components/Component.js +0 -1
- package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +0 -1
- package/dist/LinearSyntenyDisplay/components/SyntenyTooltip.js +0 -1
- package/dist/LinearSyntenyDisplay/components/util.js +0 -1
- package/dist/LinearSyntenyDisplay/configSchemaF.js +0 -1
- package/dist/LinearSyntenyDisplay/drawSynteny.js +0 -1
- package/dist/LinearSyntenyDisplay/index.js +0 -1
- package/dist/LinearSyntenyDisplay/model.js +0 -1
- package/dist/LinearSyntenyView/components/ExportSvgDialog.js +0 -1
- package/dist/LinearSyntenyView/components/Icons.js +0 -1
- package/dist/LinearSyntenyView/components/ImportCustomTrack.js +0 -1
- package/dist/LinearSyntenyView/components/ImportForm.js +0 -1
- package/dist/LinearSyntenyView/components/ImportSyntenyTrackSelector.js +0 -1
- package/dist/LinearSyntenyView/components/LinearSyntenyView.js +0 -1
- package/dist/LinearSyntenyView/index.js +0 -1
- package/dist/LinearSyntenyView/model.d.ts +9 -9
- package/dist/LinearSyntenyView/model.js +0 -1
- package/dist/LinearSyntenyView/svgcomponents/SVGBackground.js +2 -2
- package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +0 -1
- package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.js +0 -1
- package/dist/SyntenyFeatureDetail/index.js +0 -1
- package/dist/SyntenyTrack/configSchema.js +0 -1
- package/dist/SyntenyTrack/index.js +0 -1
- package/dist/index.js +0 -1
- package/dist/util.js +0 -1
- package/esm/LGVSyntenyDisplay/configSchemaF.d.ts +1 -3
- package/esm/LGVSyntenyDisplay/configSchemaF.js +0 -1
- package/esm/LGVSyntenyDisplay/index.js +0 -1
- package/esm/LGVSyntenyDisplay/model.d.ts +17 -76
- package/esm/LGVSyntenyDisplay/model.js +23 -5
- package/esm/LaunchLinearSyntenyView.js +0 -1
- package/esm/LinearComparativeDisplay/configSchemaF.js +0 -1
- package/esm/LinearComparativeDisplay/index.js +0 -1
- package/esm/LinearComparativeDisplay/stateModelFactory.js +0 -1
- package/esm/LinearComparativeView/components/Header.js +11 -2
- package/esm/LinearComparativeView/components/LinearComparativeView.js +0 -1
- package/esm/LinearComparativeView/components/Rubberband.js +8 -33
- package/esm/LinearComparativeView/components/VerticalGuide.d.ts +8 -0
- package/esm/LinearComparativeView/components/VerticalGuide.js +28 -0
- package/esm/LinearComparativeView/index.js +0 -1
- package/esm/LinearComparativeView/model.d.ts +9 -15
- package/esm/LinearComparativeView/model.js +0 -1
- package/esm/LinearReadVsRef/LinearReadVsRef.js +0 -1
- package/esm/LinearReadVsRef/index.js +0 -1
- package/esm/LinearSyntenyDisplay/afterAttach.js +0 -1
- package/esm/LinearSyntenyDisplay/components/Component.js +0 -1
- package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +0 -1
- package/esm/LinearSyntenyDisplay/components/SyntenyTooltip.js +0 -1
- package/esm/LinearSyntenyDisplay/components/util.js +0 -1
- package/esm/LinearSyntenyDisplay/configSchemaF.js +0 -1
- package/esm/LinearSyntenyDisplay/drawSynteny.js +0 -1
- package/esm/LinearSyntenyDisplay/index.js +0 -1
- package/esm/LinearSyntenyDisplay/model.js +0 -1
- package/esm/LinearSyntenyView/components/ExportSvgDialog.js +0 -1
- package/esm/LinearSyntenyView/components/Icons.js +0 -1
- package/esm/LinearSyntenyView/components/ImportCustomTrack.js +0 -1
- package/esm/LinearSyntenyView/components/ImportForm.js +0 -1
- package/esm/LinearSyntenyView/components/ImportSyntenyTrackSelector.js +0 -1
- package/esm/LinearSyntenyView/components/LinearSyntenyView.js +0 -1
- package/esm/LinearSyntenyView/index.js +0 -1
- package/esm/LinearSyntenyView/model.d.ts +9 -9
- package/esm/LinearSyntenyView/model.js +0 -1
- package/esm/LinearSyntenyView/svgcomponents/SVGBackground.js +2 -2
- package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +0 -1
- package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.js +0 -1
- package/esm/SyntenyFeatureDetail/index.js +0 -1
- package/esm/SyntenyTrack/configSchema.js +0 -1
- package/esm/SyntenyTrack/index.js +0 -1
- package/esm/index.js +0 -1
- package/esm/util.js +0 -1
- package/package.json +4 -4
- package/dist/LGVSyntenyDisplay/configSchemaF.js.map +0 -1
- package/dist/LGVSyntenyDisplay/index.js.map +0 -1
- package/dist/LGVSyntenyDisplay/model.js.map +0 -1
- package/dist/LaunchLinearSyntenyView.js.map +0 -1
- package/dist/LinearComparativeDisplay/configSchemaF.js.map +0 -1
- package/dist/LinearComparativeDisplay/index.js.map +0 -1
- package/dist/LinearComparativeDisplay/stateModelFactory.js.map +0 -1
- package/dist/LinearComparativeView/components/Header.js.map +0 -1
- package/dist/LinearComparativeView/components/LinearComparativeView.js.map +0 -1
- package/dist/LinearComparativeView/components/Rubberband.js.map +0 -1
- package/dist/LinearComparativeView/index.js.map +0 -1
- package/dist/LinearComparativeView/model.js.map +0 -1
- package/dist/LinearReadVsRef/LinearReadVsRef.js.map +0 -1
- package/dist/LinearReadVsRef/index.js.map +0 -1
- package/dist/LinearSyntenyDisplay/afterAttach.js.map +0 -1
- package/dist/LinearSyntenyDisplay/components/Component.js.map +0 -1
- package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js.map +0 -1
- package/dist/LinearSyntenyDisplay/components/SyntenyTooltip.js.map +0 -1
- package/dist/LinearSyntenyDisplay/components/util.js.map +0 -1
- package/dist/LinearSyntenyDisplay/configSchemaF.js.map +0 -1
- package/dist/LinearSyntenyDisplay/drawSynteny.js.map +0 -1
- package/dist/LinearSyntenyDisplay/index.js.map +0 -1
- package/dist/LinearSyntenyDisplay/model.js.map +0 -1
- package/dist/LinearSyntenyView/components/ExportSvgDialog.js.map +0 -1
- package/dist/LinearSyntenyView/components/Icons.js.map +0 -1
- package/dist/LinearSyntenyView/components/ImportCustomTrack.js.map +0 -1
- package/dist/LinearSyntenyView/components/ImportForm.js.map +0 -1
- package/dist/LinearSyntenyView/components/ImportSyntenyTrackSelector.js.map +0 -1
- package/dist/LinearSyntenyView/components/LinearSyntenyView.js.map +0 -1
- package/dist/LinearSyntenyView/index.js.map +0 -1
- package/dist/LinearSyntenyView/model.js.map +0 -1
- package/dist/LinearSyntenyView/svgcomponents/SVGBackground.js.map +0 -1
- package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js.map +0 -1
- package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.js.map +0 -1
- package/dist/SyntenyFeatureDetail/index.js.map +0 -1
- package/dist/SyntenyTrack/configSchema.js.map +0 -1
- package/dist/SyntenyTrack/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/util.js.map +0 -1
- package/esm/LGVSyntenyDisplay/configSchemaF.js.map +0 -1
- package/esm/LGVSyntenyDisplay/index.js.map +0 -1
- package/esm/LGVSyntenyDisplay/model.js.map +0 -1
- package/esm/LaunchLinearSyntenyView.js.map +0 -1
- package/esm/LinearComparativeDisplay/configSchemaF.js.map +0 -1
- package/esm/LinearComparativeDisplay/index.js.map +0 -1
- package/esm/LinearComparativeDisplay/stateModelFactory.js.map +0 -1
- package/esm/LinearComparativeView/components/Header.js.map +0 -1
- package/esm/LinearComparativeView/components/LinearComparativeView.js.map +0 -1
- package/esm/LinearComparativeView/components/Rubberband.js.map +0 -1
- package/esm/LinearComparativeView/index.js.map +0 -1
- package/esm/LinearComparativeView/model.js.map +0 -1
- package/esm/LinearReadVsRef/LinearReadVsRef.js.map +0 -1
- package/esm/LinearReadVsRef/index.js.map +0 -1
- package/esm/LinearSyntenyDisplay/afterAttach.js.map +0 -1
- package/esm/LinearSyntenyDisplay/components/Component.js.map +0 -1
- package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js.map +0 -1
- package/esm/LinearSyntenyDisplay/components/SyntenyTooltip.js.map +0 -1
- package/esm/LinearSyntenyDisplay/components/util.js.map +0 -1
- package/esm/LinearSyntenyDisplay/configSchemaF.js.map +0 -1
- package/esm/LinearSyntenyDisplay/drawSynteny.js.map +0 -1
- package/esm/LinearSyntenyDisplay/index.js.map +0 -1
- package/esm/LinearSyntenyDisplay/model.js.map +0 -1
- package/esm/LinearSyntenyView/components/ExportSvgDialog.js.map +0 -1
- package/esm/LinearSyntenyView/components/Icons.js.map +0 -1
- package/esm/LinearSyntenyView/components/ImportCustomTrack.js.map +0 -1
- package/esm/LinearSyntenyView/components/ImportForm.js.map +0 -1
- package/esm/LinearSyntenyView/components/ImportSyntenyTrackSelector.js.map +0 -1
- package/esm/LinearSyntenyView/components/LinearSyntenyView.js.map +0 -1
- package/esm/LinearSyntenyView/index.js.map +0 -1
- package/esm/LinearSyntenyView/model.js.map +0 -1
- package/esm/LinearSyntenyView/svgcomponents/SVGBackground.js.map +0 -1
- package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js.map +0 -1
- package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.js.map +0 -1
- package/esm/SyntenyFeatureDetail/index.js.map +0 -1
- package/esm/SyntenyTrack/configSchema.js.map +0 -1
- package/esm/SyntenyTrack/index.js.map +0 -1
- package/esm/index.js.map +0 -1
- package/esm/util.js.map +0 -1
- package/src/LGVSyntenyDisplay/configSchemaF.ts +0 -22
- package/src/LGVSyntenyDisplay/index.ts +0 -20
- package/src/LGVSyntenyDisplay/model.ts +0 -177
- package/src/LaunchLinearSyntenyView.ts +0 -86
- package/src/LinearComparativeDisplay/configSchemaF.ts +0 -22
- package/src/LinearComparativeDisplay/index.ts +0 -21
- package/src/LinearComparativeDisplay/stateModelFactory.ts +0 -212
- package/src/LinearComparativeView/components/Header.tsx +0 -103
- package/src/LinearComparativeView/components/LinearComparativeView.tsx +0 -152
- package/src/LinearComparativeView/components/Rubberband.tsx +0 -329
- package/src/LinearComparativeView/index.ts +0 -15
- package/src/LinearComparativeView/model.ts +0 -395
- package/src/LinearReadVsRef/LinearReadVsRef.tsx +0 -360
- package/src/LinearReadVsRef/index.ts +0 -58
- package/src/LinearSyntenyDisplay/afterAttach.ts +0 -149
- package/src/LinearSyntenyDisplay/components/Component.tsx +0 -75
- package/src/LinearSyntenyDisplay/components/LinearSyntenyRendering.tsx +0 -200
- package/src/LinearSyntenyDisplay/components/SyntenyTooltip.tsx +0 -82
- package/src/LinearSyntenyDisplay/components/util.ts +0 -142
- package/src/LinearSyntenyDisplay/configSchemaF.ts +0 -38
- package/src/LinearSyntenyDisplay/drawSynteny.ts +0 -266
- package/src/LinearSyntenyDisplay/index.ts +0 -21
- package/src/LinearSyntenyDisplay/model.ts +0 -187
- package/src/LinearSyntenyView/components/ExportSvgDialog.tsx +0 -148
- package/src/LinearSyntenyView/components/Icons.tsx +0 -24
- package/src/LinearSyntenyView/components/ImportCustomTrack.tsx +0 -262
- package/src/LinearSyntenyView/components/ImportForm.tsx +0 -221
- package/src/LinearSyntenyView/components/ImportSyntenyTrackSelector.tsx +0 -82
- package/src/LinearSyntenyView/components/LinearSyntenyView.tsx +0 -20
- package/src/LinearSyntenyView/index.ts +0 -15
- package/src/LinearSyntenyView/model.test.ts +0 -1605
- package/src/LinearSyntenyView/model.ts +0 -169
- package/src/LinearSyntenyView/svgcomponents/SVGBackground.tsx +0 -21
- package/src/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.tsx +0 -176
- package/src/SyntenyFeatureDetail/SyntenyFeatureDetail.tsx +0 -64
- package/src/SyntenyFeatureDetail/index.ts +0 -36
- package/src/SyntenyTrack/configSchema.ts +0 -23
- package/src/SyntenyTrack/index.tsx +0 -15
- package/src/index.tsx +0 -42
- package/src/util.ts +0 -124
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react'
|
|
2
|
-
import {
|
|
3
|
-
Button,
|
|
4
|
-
CircularProgress,
|
|
5
|
-
DialogActions,
|
|
6
|
-
DialogContent,
|
|
7
|
-
TextField,
|
|
8
|
-
Typography,
|
|
9
|
-
} from '@mui/material'
|
|
10
|
-
import { Dialog } from '@jbrowse/core/ui'
|
|
11
|
-
import { makeStyles } from 'tss-react/mui'
|
|
12
|
-
import { getConf } from '@jbrowse/core/configuration'
|
|
13
|
-
import { getRpcSessionId } from '@jbrowse/core/util/tracks'
|
|
14
|
-
import {
|
|
15
|
-
getSession,
|
|
16
|
-
getContainingView,
|
|
17
|
-
gatherOverlaps,
|
|
18
|
-
Feature,
|
|
19
|
-
} from '@jbrowse/core/util'
|
|
20
|
-
|
|
21
|
-
// locals
|
|
22
|
-
import { MismatchParser } from '@jbrowse/plugin-alignments'
|
|
23
|
-
const { featurizeSA, getClip, getLength, getLengthSansClipping, getTag } =
|
|
24
|
-
MismatchParser
|
|
25
|
-
|
|
26
|
-
interface ReducedFeature {
|
|
27
|
-
refName: string
|
|
28
|
-
start: number
|
|
29
|
-
clipPos: number
|
|
30
|
-
end: number
|
|
31
|
-
strand: number
|
|
32
|
-
seqLength: number
|
|
33
|
-
syntenyId?: number
|
|
34
|
-
uniqueId: string
|
|
35
|
-
mate: {
|
|
36
|
-
refName: string
|
|
37
|
-
start: number
|
|
38
|
-
end: number
|
|
39
|
-
syntenyId?: number
|
|
40
|
-
uniqueId?: string
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const useStyles = makeStyles()({
|
|
45
|
-
root: {
|
|
46
|
-
width: 300,
|
|
47
|
-
},
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
export default function ReadVsRefDialog({
|
|
51
|
-
track,
|
|
52
|
-
feature: preFeature,
|
|
53
|
-
handleClose,
|
|
54
|
-
}: {
|
|
55
|
-
feature: Feature
|
|
56
|
-
handleClose: () => void
|
|
57
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
58
|
-
track: any
|
|
59
|
-
}) {
|
|
60
|
-
const { classes } = useStyles()
|
|
61
|
-
|
|
62
|
-
// window size stored as string, because it corresponds to a textfield which
|
|
63
|
-
// is parsed as number on submit
|
|
64
|
-
const [windowSizeText, setWindowSize] = useState('0')
|
|
65
|
-
const [error, setError] = useState<unknown>()
|
|
66
|
-
const [primaryFeature, setPrimaryFeature] = useState<Feature>()
|
|
67
|
-
const windowSize = +windowSizeText
|
|
68
|
-
|
|
69
|
-
// we need to fetch the primary alignment if the selected feature is 2048.
|
|
70
|
-
// this should be the first in the list of the SA tag
|
|
71
|
-
useEffect(() => {
|
|
72
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
73
|
-
;(async () => {
|
|
74
|
-
setError(undefined)
|
|
75
|
-
try {
|
|
76
|
-
if (preFeature.get('flags') & 2048) {
|
|
77
|
-
const SA: string = getTag(preFeature, 'SA') || ''
|
|
78
|
-
const primaryAln = SA.split(';')[0]
|
|
79
|
-
const [saRef, saStart] = primaryAln.split(',')
|
|
80
|
-
const { rpcManager } = getSession(track)
|
|
81
|
-
const adapterConfig = getConf(track, 'adapter')
|
|
82
|
-
const sessionId = getRpcSessionId(track)
|
|
83
|
-
|
|
84
|
-
const feats = (await rpcManager.call(sessionId, 'CoreGetFeatures', {
|
|
85
|
-
adapterConfig,
|
|
86
|
-
sessionId,
|
|
87
|
-
regions: [
|
|
88
|
-
{
|
|
89
|
-
refName: saRef,
|
|
90
|
-
start: +saStart - 1,
|
|
91
|
-
end: +saStart,
|
|
92
|
-
},
|
|
93
|
-
],
|
|
94
|
-
})) as Feature[]
|
|
95
|
-
|
|
96
|
-
const result = feats.find(
|
|
97
|
-
f =>
|
|
98
|
-
f.get('name') === preFeature.get('name') &&
|
|
99
|
-
!(f.get('flags') & 2048) &&
|
|
100
|
-
!(f.get('flags') & 256),
|
|
101
|
-
)
|
|
102
|
-
if (result) {
|
|
103
|
-
setPrimaryFeature(result)
|
|
104
|
-
} else {
|
|
105
|
-
throw new Error('primary feature not found')
|
|
106
|
-
}
|
|
107
|
-
} else {
|
|
108
|
-
setPrimaryFeature(preFeature)
|
|
109
|
-
}
|
|
110
|
-
} catch (e) {
|
|
111
|
-
console.error(e)
|
|
112
|
-
setError(e)
|
|
113
|
-
}
|
|
114
|
-
})()
|
|
115
|
-
}, [preFeature, track])
|
|
116
|
-
|
|
117
|
-
function onSubmit() {
|
|
118
|
-
try {
|
|
119
|
-
if (!primaryFeature) {
|
|
120
|
-
return
|
|
121
|
-
}
|
|
122
|
-
const feature = primaryFeature
|
|
123
|
-
const session = getSession(track)
|
|
124
|
-
const view = getContainingView(track)
|
|
125
|
-
const cigar = feature.get('CIGAR') as string
|
|
126
|
-
const flags = feature.get('flags') as number
|
|
127
|
-
const origStrand = feature.get('strand') as number
|
|
128
|
-
const SA = (getTag(feature, 'SA') as string) || ''
|
|
129
|
-
const readName = feature.get('name') as string
|
|
130
|
-
const clipPos = getClip(cigar, 1)
|
|
131
|
-
|
|
132
|
-
const readAssembly = `${readName}_assembly_${Date.now()}`
|
|
133
|
-
const [trackAssembly] = getConf(track, 'assemblyNames')
|
|
134
|
-
const assemblyNames = [trackAssembly, readAssembly]
|
|
135
|
-
const trackId = `track-${Date.now()}`
|
|
136
|
-
const trackName = `${readName}_vs_${trackAssembly}`
|
|
137
|
-
|
|
138
|
-
// get the canonical refname for the read because if the
|
|
139
|
-
// read.get('refName') is chr1 and the actual fasta refName is 1 then no
|
|
140
|
-
// tracks can be opened on the top panel of the linear read vs ref
|
|
141
|
-
const { assemblyManager } = session
|
|
142
|
-
const assembly = assemblyManager.get(trackAssembly)
|
|
143
|
-
if (!assembly) {
|
|
144
|
-
throw new Error('assembly not found')
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const suppAlns = featurizeSA(SA, feature.id(), origStrand, readName, true)
|
|
148
|
-
|
|
149
|
-
const feat = feature.toJSON()
|
|
150
|
-
feat.clipPos = clipPos
|
|
151
|
-
feat.strand = 1
|
|
152
|
-
|
|
153
|
-
feat.mate = {
|
|
154
|
-
refName: readName,
|
|
155
|
-
start: clipPos,
|
|
156
|
-
end: clipPos + getLengthSansClipping(cigar),
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// if secondary alignment or supplementary, calculate length from SA[0]'s
|
|
160
|
-
// CIGAR which is the primary alignments. otherwise it is the primary
|
|
161
|
-
// alignment just use seq.length if primary alignment
|
|
162
|
-
const totalLength =
|
|
163
|
-
flags & 2048 ? getLength(suppAlns[0].CIGAR) : getLength(cigar)
|
|
164
|
-
|
|
165
|
-
const features = [feat, ...suppAlns] as ReducedFeature[]
|
|
166
|
-
|
|
167
|
-
features.forEach((f, idx) => {
|
|
168
|
-
f.refName = assembly?.getCanonicalRefName(f.refName) || f.refName
|
|
169
|
-
f.syntenyId = idx
|
|
170
|
-
f.mate.syntenyId = idx
|
|
171
|
-
f.mate.uniqueId = `${f.uniqueId}_mate`
|
|
172
|
-
})
|
|
173
|
-
features.sort((a, b) => a.clipPos - b.clipPos)
|
|
174
|
-
|
|
175
|
-
const featSeq = feature.get('seq') as string | undefined
|
|
176
|
-
|
|
177
|
-
// the config feature store includes synthetic mate features
|
|
178
|
-
// mapped to the read assembly
|
|
179
|
-
const configFeatureStore = [...features, ...features.map(f => f.mate)]
|
|
180
|
-
const expand = 2 * windowSize
|
|
181
|
-
const refLen = features.reduce((a, f) => a + f.end - f.start + expand, 0)
|
|
182
|
-
|
|
183
|
-
const seqTrackId = `${readName}_${Date.now()}`
|
|
184
|
-
const sequenceTrackConf = getConf(assembly, 'sequence')
|
|
185
|
-
const lgvRegions = gatherOverlaps(
|
|
186
|
-
features.map(f => ({
|
|
187
|
-
...f,
|
|
188
|
-
start: Math.max(0, f.start - windowSize),
|
|
189
|
-
end: f.end + windowSize,
|
|
190
|
-
assemblyName: trackAssembly,
|
|
191
|
-
})),
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
session.addTemporaryAssembly({
|
|
195
|
-
name: `${readAssembly}`,
|
|
196
|
-
sequence: {
|
|
197
|
-
type: 'ReferenceSequenceTrack',
|
|
198
|
-
name: `Read sequence`,
|
|
199
|
-
trackId: seqTrackId,
|
|
200
|
-
assemblyNames: [readAssembly],
|
|
201
|
-
adapter: {
|
|
202
|
-
type: 'FromConfigSequenceAdapter',
|
|
203
|
-
noAssemblyManager: true,
|
|
204
|
-
features: [
|
|
205
|
-
{
|
|
206
|
-
start: 0,
|
|
207
|
-
end: totalLength,
|
|
208
|
-
seq: featSeq || '', // can be empty if user clicks secondary read
|
|
209
|
-
refName: readName,
|
|
210
|
-
uniqueId: `${Math.random()}`,
|
|
211
|
-
},
|
|
212
|
-
],
|
|
213
|
-
},
|
|
214
|
-
},
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
session.addView('LinearSyntenyView', {
|
|
218
|
-
type: 'LinearSyntenyView',
|
|
219
|
-
views: [
|
|
220
|
-
{
|
|
221
|
-
type: 'LinearGenomeView',
|
|
222
|
-
hideHeader: true,
|
|
223
|
-
offsetPx: 0,
|
|
224
|
-
bpPerPx: refLen / view.width,
|
|
225
|
-
displayedRegions: lgvRegions,
|
|
226
|
-
tracks: [
|
|
227
|
-
{
|
|
228
|
-
id: `${Math.random()}`,
|
|
229
|
-
type: 'ReferenceSequenceTrack',
|
|
230
|
-
assemblyNames: [trackAssembly],
|
|
231
|
-
configuration: sequenceTrackConf.trackId,
|
|
232
|
-
displays: [
|
|
233
|
-
{
|
|
234
|
-
id: `${Math.random()}`,
|
|
235
|
-
type: 'LinearReferenceSequenceDisplay',
|
|
236
|
-
showReverse: true,
|
|
237
|
-
showTranslation: false,
|
|
238
|
-
height: 35,
|
|
239
|
-
configuration: `${seqTrackId}-LinearReferenceSequenceDisplay`,
|
|
240
|
-
},
|
|
241
|
-
],
|
|
242
|
-
},
|
|
243
|
-
],
|
|
244
|
-
},
|
|
245
|
-
{
|
|
246
|
-
type: 'LinearGenomeView',
|
|
247
|
-
hideHeader: true,
|
|
248
|
-
offsetPx: 0,
|
|
249
|
-
bpPerPx: totalLength / view.width,
|
|
250
|
-
displayedRegions: [
|
|
251
|
-
{
|
|
252
|
-
assemblyName: readAssembly,
|
|
253
|
-
start: 0,
|
|
254
|
-
end: totalLength,
|
|
255
|
-
refName: readName,
|
|
256
|
-
},
|
|
257
|
-
],
|
|
258
|
-
tracks: [
|
|
259
|
-
{
|
|
260
|
-
id: `${Math.random()}`,
|
|
261
|
-
type: 'ReferenceSequenceTrack',
|
|
262
|
-
configuration: seqTrackId,
|
|
263
|
-
displays: [
|
|
264
|
-
{
|
|
265
|
-
id: `${Math.random()}`,
|
|
266
|
-
type: 'LinearReferenceSequenceDisplay',
|
|
267
|
-
showReverse: true,
|
|
268
|
-
showTranslation: false,
|
|
269
|
-
height: 35,
|
|
270
|
-
configuration: `${seqTrackId}-LinearReferenceSequenceDisplay`,
|
|
271
|
-
},
|
|
272
|
-
],
|
|
273
|
-
},
|
|
274
|
-
],
|
|
275
|
-
},
|
|
276
|
-
],
|
|
277
|
-
viewTrackConfigs: [
|
|
278
|
-
{
|
|
279
|
-
type: 'SyntenyTrack',
|
|
280
|
-
assemblyNames,
|
|
281
|
-
adapter: {
|
|
282
|
-
type: 'FromConfigAdapter',
|
|
283
|
-
features: configFeatureStore,
|
|
284
|
-
},
|
|
285
|
-
trackId,
|
|
286
|
-
name: trackName,
|
|
287
|
-
},
|
|
288
|
-
],
|
|
289
|
-
tracks: [
|
|
290
|
-
{
|
|
291
|
-
configuration: trackId,
|
|
292
|
-
type: 'SyntenyTrack',
|
|
293
|
-
displays: [
|
|
294
|
-
{
|
|
295
|
-
type: 'LinearSyntenyDisplay',
|
|
296
|
-
configuration: `${trackId}-LinearSyntenyDisplay`,
|
|
297
|
-
},
|
|
298
|
-
],
|
|
299
|
-
},
|
|
300
|
-
],
|
|
301
|
-
displayName: `${readName} vs ${trackAssembly}`,
|
|
302
|
-
})
|
|
303
|
-
handleClose()
|
|
304
|
-
} catch (e) {
|
|
305
|
-
console.error(e)
|
|
306
|
-
setError(e)
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
return (
|
|
311
|
-
<Dialog open onClose={handleClose} title="Set window size">
|
|
312
|
-
<DialogContent>
|
|
313
|
-
{error ? (
|
|
314
|
-
<Typography color="error">{`${error}`}</Typography>
|
|
315
|
-
) : !primaryFeature ? (
|
|
316
|
-
<div>
|
|
317
|
-
<Typography>
|
|
318
|
-
To accurately perform comparison we are fetching the primary
|
|
319
|
-
alignment. Loading primary feature...
|
|
320
|
-
</Typography>
|
|
321
|
-
<CircularProgress />
|
|
322
|
-
</div>
|
|
323
|
-
) : (
|
|
324
|
-
<div className={classes.root}>
|
|
325
|
-
{primaryFeature.get('flags') & 256 ? (
|
|
326
|
-
<Typography style={{ color: 'orange' }}>
|
|
327
|
-
Note: You selected a secondary alignment (which generally does
|
|
328
|
-
not have SA tags or SEQ fields) so do a full reconstruction of
|
|
329
|
-
the alignment
|
|
330
|
-
</Typography>
|
|
331
|
-
) : null}
|
|
332
|
-
<Typography>
|
|
333
|
-
Show an extra window size around each part of the split alignment.
|
|
334
|
-
Using a larger value can allow you to see more genomic context.
|
|
335
|
-
</Typography>
|
|
336
|
-
|
|
337
|
-
<TextField
|
|
338
|
-
value={windowSize}
|
|
339
|
-
onChange={event => setWindowSize(event.target.value)}
|
|
340
|
-
label="Set window size"
|
|
341
|
-
/>
|
|
342
|
-
</div>
|
|
343
|
-
)}
|
|
344
|
-
</DialogContent>
|
|
345
|
-
<DialogActions>
|
|
346
|
-
<Button variant="contained" color="secondary" onClick={handleClose}>
|
|
347
|
-
Cancel
|
|
348
|
-
</Button>
|
|
349
|
-
<Button
|
|
350
|
-
disabled={!primaryFeature}
|
|
351
|
-
variant="contained"
|
|
352
|
-
color="primary"
|
|
353
|
-
onClick={onSubmit}
|
|
354
|
-
>
|
|
355
|
-
Submit
|
|
356
|
-
</Button>
|
|
357
|
-
</DialogActions>
|
|
358
|
-
</Dialog>
|
|
359
|
-
)
|
|
360
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import PluginManager from '@jbrowse/core/PluginManager'
|
|
2
|
-
import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'
|
|
3
|
-
import { PluggableElementType } from '@jbrowse/core/pluggableElementTypes'
|
|
4
|
-
import { getSession, getContainingTrack } from '@jbrowse/core/util'
|
|
5
|
-
|
|
6
|
-
// icons
|
|
7
|
-
import AddIcon from '@mui/icons-material/Add'
|
|
8
|
-
|
|
9
|
-
// locals
|
|
10
|
-
import ReadVsRefDialog from './LinearReadVsRef'
|
|
11
|
-
|
|
12
|
-
function isDisplay(elt: { name: string }): elt is DisplayType {
|
|
13
|
-
return elt.name === 'LinearPileupDisplay'
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export default function (pm: PluginManager) {
|
|
17
|
-
pm.addToExtensionPoint(
|
|
18
|
-
'Core-extendPluggableElement',
|
|
19
|
-
(pluggableElement: PluggableElementType) => {
|
|
20
|
-
if (!isDisplay(pluggableElement)) {
|
|
21
|
-
return pluggableElement
|
|
22
|
-
}
|
|
23
|
-
pluggableElement.stateModel = pluggableElement.stateModel.extend(self => {
|
|
24
|
-
const superContextMenuItems = self.contextMenuItems
|
|
25
|
-
return {
|
|
26
|
-
views: {
|
|
27
|
-
contextMenuItems() {
|
|
28
|
-
const feature = self.contextMenuFeature
|
|
29
|
-
const track = getContainingTrack(self)
|
|
30
|
-
return [
|
|
31
|
-
...superContextMenuItems(),
|
|
32
|
-
...(feature
|
|
33
|
-
? [
|
|
34
|
-
{
|
|
35
|
-
label: 'Linear read vs ref',
|
|
36
|
-
icon: AddIcon,
|
|
37
|
-
onClick: () => {
|
|
38
|
-
getSession(self).queueDialog(handleClose => [
|
|
39
|
-
ReadVsRefDialog,
|
|
40
|
-
{
|
|
41
|
-
track,
|
|
42
|
-
feature,
|
|
43
|
-
handleClose,
|
|
44
|
-
},
|
|
45
|
-
])
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
]
|
|
49
|
-
: []),
|
|
50
|
-
]
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
}
|
|
54
|
-
})
|
|
55
|
-
return pluggableElement
|
|
56
|
-
},
|
|
57
|
-
)
|
|
58
|
-
}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { addDisposer, getSnapshot } from 'mobx-state-tree'
|
|
2
|
-
|
|
3
|
-
import { Feature, getContainingView, getSession } from '@jbrowse/core/util'
|
|
4
|
-
import { bpToPx } from '@jbrowse/core/util/Base1DUtils'
|
|
5
|
-
import { MismatchParser } from '@jbrowse/plugin-alignments'
|
|
6
|
-
import { reaction, autorun } from 'mobx'
|
|
7
|
-
|
|
8
|
-
// locals
|
|
9
|
-
import { LinearSyntenyViewModel } from '../LinearSyntenyView/model'
|
|
10
|
-
import { drawMouseoverSynteny, drawRef } from './drawSynteny'
|
|
11
|
-
import { LinearSyntenyDisplayModel } from './model'
|
|
12
|
-
|
|
13
|
-
interface Pos {
|
|
14
|
-
offsetPx: number
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface FeatPos {
|
|
18
|
-
p11: Pos
|
|
19
|
-
p12: Pos
|
|
20
|
-
p21: Pos
|
|
21
|
-
p22: Pos
|
|
22
|
-
f: Feature
|
|
23
|
-
cigar: string[]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
type LSV = LinearSyntenyViewModel
|
|
27
|
-
|
|
28
|
-
export function doAfterAttach(self: LinearSyntenyDisplayModel) {
|
|
29
|
-
addDisposer(
|
|
30
|
-
self,
|
|
31
|
-
autorun(() => {
|
|
32
|
-
const view = getContainingView(self)
|
|
33
|
-
if (!view.initialized) {
|
|
34
|
-
return
|
|
35
|
-
}
|
|
36
|
-
const ctx1 = self.mainCanvas?.getContext('2d')
|
|
37
|
-
const ctx3 = self.cigarClickMapCanvas?.getContext('2d')
|
|
38
|
-
if (!ctx1 || !ctx3) {
|
|
39
|
-
return
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const height = view.middleComparativeHeight
|
|
43
|
-
const width = view.width
|
|
44
|
-
ctx1.clearRect(0, 0, width, height)
|
|
45
|
-
ctx3.clearRect(0, 0, width, height)
|
|
46
|
-
drawRef(self, ctx1, ctx3)
|
|
47
|
-
}),
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
addDisposer(
|
|
51
|
-
self,
|
|
52
|
-
autorun(() => {
|
|
53
|
-
const view = getContainingView(self)
|
|
54
|
-
if (!view.initialized) {
|
|
55
|
-
return
|
|
56
|
-
}
|
|
57
|
-
drawMouseoverSynteny(self)
|
|
58
|
-
}),
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
// this attempts to reduce recalculation of feature positions drawn by
|
|
62
|
-
// the synteny view
|
|
63
|
-
//
|
|
64
|
-
// uses a reaction to say "we know the positions don't change in any
|
|
65
|
-
// relevant way unless bpPerPx changes or displayedRegions changes"
|
|
66
|
-
addDisposer(
|
|
67
|
-
self,
|
|
68
|
-
reaction(
|
|
69
|
-
() => {
|
|
70
|
-
const view = getContainingView(self) as LSV
|
|
71
|
-
return {
|
|
72
|
-
bpPerPx: view.views.map(v => v.bpPerPx),
|
|
73
|
-
|
|
74
|
-
// stringifying 'deeply' accesses the displayed regions, see
|
|
75
|
-
// issue #3456
|
|
76
|
-
displayedRegions: JSON.stringify(
|
|
77
|
-
view.views.map(v => v.displayedRegions),
|
|
78
|
-
),
|
|
79
|
-
features: self.features,
|
|
80
|
-
initialized: view.initialized,
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
({ initialized }) => {
|
|
84
|
-
if (!initialized) {
|
|
85
|
-
return
|
|
86
|
-
}
|
|
87
|
-
const { assemblyManager } = getSession(self)
|
|
88
|
-
const view = getContainingView(self) as LSV
|
|
89
|
-
const viewSnaps = view.views.map(view => ({
|
|
90
|
-
...getSnapshot(view),
|
|
91
|
-
width: view.width,
|
|
92
|
-
staticBlocks: view.staticBlocks,
|
|
93
|
-
interRegionPaddingWidth: view.interRegionPaddingWidth,
|
|
94
|
-
minimumBlockWidth: view.minimumBlockWidth,
|
|
95
|
-
}))
|
|
96
|
-
|
|
97
|
-
const map = [] as FeatPos[]
|
|
98
|
-
const feats = self.features || []
|
|
99
|
-
|
|
100
|
-
for (let i = 0; i < feats.length; i++) {
|
|
101
|
-
const f = feats[i]
|
|
102
|
-
const mate = f.get('mate')
|
|
103
|
-
let f1s = f.get('start')
|
|
104
|
-
let f1e = f.get('end')
|
|
105
|
-
const f2s = mate.start
|
|
106
|
-
const f2e = mate.end
|
|
107
|
-
|
|
108
|
-
if (f.get('strand') === -1) {
|
|
109
|
-
;[f1e, f1s] = [f1s, f1e]
|
|
110
|
-
}
|
|
111
|
-
const a1 = assemblyManager?.get(f.get('assemblyName'))
|
|
112
|
-
const a2 = assemblyManager?.get(mate.assemblyName)
|
|
113
|
-
const r1 = f.get('refName')
|
|
114
|
-
const r2 = mate.refName
|
|
115
|
-
const ref1 = a1?.getCanonicalRefName(r1) || r1
|
|
116
|
-
const ref2 = a2?.getCanonicalRefName(r2) || r2
|
|
117
|
-
const v1 = viewSnaps[0]
|
|
118
|
-
const v2 = viewSnaps[1]
|
|
119
|
-
const p11 = bpToPx({ self: v1, refName: ref1, coord: f1s })
|
|
120
|
-
const p12 = bpToPx({ self: v1, refName: ref1, coord: f1e })
|
|
121
|
-
const p21 = bpToPx({ self: v2, refName: ref2, coord: f2s })
|
|
122
|
-
const p22 = bpToPx({ self: v2, refName: ref2, coord: f2e })
|
|
123
|
-
|
|
124
|
-
if (
|
|
125
|
-
p11 === undefined ||
|
|
126
|
-
p12 === undefined ||
|
|
127
|
-
p21 === undefined ||
|
|
128
|
-
p22 === undefined
|
|
129
|
-
) {
|
|
130
|
-
continue
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const cigar = f.get('CIGAR') as string | undefined
|
|
134
|
-
map.push({
|
|
135
|
-
p11,
|
|
136
|
-
p12,
|
|
137
|
-
p21,
|
|
138
|
-
p22,
|
|
139
|
-
f,
|
|
140
|
-
cigar: MismatchParser.parseCigar(cigar),
|
|
141
|
-
})
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
self.setFeatPositions(map)
|
|
145
|
-
},
|
|
146
|
-
{ fireImmediately: true },
|
|
147
|
-
),
|
|
148
|
-
)
|
|
149
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react'
|
|
2
|
-
import { makeStyles } from 'tss-react/mui'
|
|
3
|
-
import { observer } from 'mobx-react'
|
|
4
|
-
import { LoadingEllipses } from '@jbrowse/core/ui'
|
|
5
|
-
|
|
6
|
-
// locals
|
|
7
|
-
import LinearSyntenyRendering from './LinearSyntenyRendering'
|
|
8
|
-
import { LinearSyntenyDisplayModel } from '../model'
|
|
9
|
-
|
|
10
|
-
const useStyles = makeStyles()(theme => {
|
|
11
|
-
const bg = theme.palette.action.disabledBackground
|
|
12
|
-
return {
|
|
13
|
-
loading: {
|
|
14
|
-
paddingLeft: '0.6em',
|
|
15
|
-
backgroundColor: theme.palette.background.default,
|
|
16
|
-
backgroundImage: `repeating-linear-gradient(45deg, transparent, transparent 5px, ${bg} 5px, ${bg} 10px)`,
|
|
17
|
-
textAlign: 'center',
|
|
18
|
-
},
|
|
19
|
-
blockMessage: {
|
|
20
|
-
background: '#f1f1f1',
|
|
21
|
-
padding: 10,
|
|
22
|
-
},
|
|
23
|
-
blockError: {
|
|
24
|
-
background: '#f1f1f1',
|
|
25
|
-
padding: 10,
|
|
26
|
-
color: 'red',
|
|
27
|
-
},
|
|
28
|
-
}
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
function LoadingMessage() {
|
|
32
|
-
// only show the loading message after 300ms to prevent excessive flickering
|
|
33
|
-
const [shown, setShown] = useState(false)
|
|
34
|
-
const { classes } = useStyles()
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
const timeout = setTimeout(() => setShown(true), 300)
|
|
37
|
-
return () => clearTimeout(timeout)
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
return shown ? (
|
|
41
|
-
<div className={classes.loading}>
|
|
42
|
-
<LoadingEllipses />
|
|
43
|
-
</div>
|
|
44
|
-
) : null
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function BlockMessage({ messageText }: { messageText: string }) {
|
|
48
|
-
const { classes } = useStyles()
|
|
49
|
-
return <div className={classes.blockMessage}>{messageText}</div>
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function BlockError({ error }: { error: unknown }) {
|
|
53
|
-
const { classes } = useStyles()
|
|
54
|
-
return <div className={classes.blockError}>{`${error}`}</div>
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const ServerSideRenderedBlockContent = observer(function ({
|
|
58
|
-
model,
|
|
59
|
-
}: {
|
|
60
|
-
model: LinearSyntenyDisplayModel
|
|
61
|
-
}) {
|
|
62
|
-
if (model.error) {
|
|
63
|
-
return <BlockError error={model.error} />
|
|
64
|
-
}
|
|
65
|
-
if (model.message) {
|
|
66
|
-
return <BlockMessage messageText={model.message} />
|
|
67
|
-
}
|
|
68
|
-
if (!model.features) {
|
|
69
|
-
return <LoadingMessage />
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return <LinearSyntenyRendering model={model} />
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
export default ServerSideRenderedBlockContent
|