jbrowse-plugin-mafviewer 1.0.6 → 1.1.1
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/README.md +71 -22
- package/dist/BgzipTaffyAdapter/BgzipTaffyAdapter.d.ts +20 -0
- package/dist/BgzipTaffyAdapter/BgzipTaffyAdapter.js +197 -0
- package/dist/BgzipTaffyAdapter/BgzipTaffyAdapter.js.map +1 -0
- package/dist/BgzipTaffyAdapter/configSchema.d.ts +44 -0
- package/dist/BgzipTaffyAdapter/configSchema.js +53 -0
- package/dist/BgzipTaffyAdapter/configSchema.js.map +1 -0
- package/dist/BgzipTaffyAdapter/index.d.ts +2 -0
- package/dist/BgzipTaffyAdapter/index.js +11 -0
- package/dist/BgzipTaffyAdapter/index.js.map +1 -0
- package/dist/BgzipTaffyAdapter/rowInstructions.d.ts +35 -0
- package/dist/BgzipTaffyAdapter/rowInstructions.js +55 -0
- package/dist/BgzipTaffyAdapter/rowInstructions.js.map +1 -0
- package/dist/BgzipTaffyAdapter/types.d.ts +13 -0
- package/dist/BgzipTaffyAdapter/types.js +2 -0
- package/dist/BgzipTaffyAdapter/types.js.map +1 -0
- package/dist/BgzipTaffyAdapter/virtualOffset.d.ts +8 -0
- package/dist/BgzipTaffyAdapter/virtualOffset.js +23 -0
- package/dist/BgzipTaffyAdapter/virtualOffset.js.map +1 -0
- package/dist/BigMafAdapter/BigMafAdapter.d.ts +17 -0
- package/dist/BigMafAdapter/BigMafAdapter.js +92 -0
- package/dist/BigMafAdapter/BigMafAdapter.js.map +1 -0
- package/dist/BigMafAdapter/configSchema.d.ts +32 -0
- package/dist/BigMafAdapter/configSchema.js +39 -0
- package/dist/BigMafAdapter/configSchema.js.map +1 -0
- package/dist/BigMafAdapter/index.d.ts +2 -0
- package/dist/BigMafAdapter/index.js +11 -0
- package/dist/BigMafAdapter/index.js.map +1 -0
- package/dist/LinearMafDisplay/components/ColorLegend.d.ts +8 -0
- package/dist/LinearMafDisplay/components/ColorLegend.js +19 -0
- package/dist/LinearMafDisplay/components/ColorLegend.js.map +1 -0
- package/dist/LinearMafDisplay/components/ReactComponent.d.ts +6 -0
- package/dist/LinearMafDisplay/components/ReactComponent.js +50 -0
- package/dist/LinearMafDisplay/components/ReactComponent.js.map +1 -0
- package/dist/LinearMafDisplay/components/RectBg.d.ts +9 -0
- package/dist/LinearMafDisplay/components/RectBg.js +7 -0
- package/dist/LinearMafDisplay/components/RectBg.js.map +1 -0
- package/dist/LinearMafDisplay/components/SetRowHeight.d.ts +11 -0
- package/dist/LinearMafDisplay/components/SetRowHeight.js +36 -0
- package/dist/LinearMafDisplay/components/SetRowHeight.js.map +1 -0
- package/dist/LinearMafDisplay/components/SvgWrapper.d.ts +8 -0
- package/dist/LinearMafDisplay/components/SvgWrapper.js +21 -0
- package/dist/LinearMafDisplay/components/SvgWrapper.js.map +1 -0
- package/dist/LinearMafDisplay/components/Tree.d.ts +5 -0
- package/dist/LinearMafDisplay/components/Tree.js +22 -0
- package/dist/LinearMafDisplay/components/Tree.js.map +1 -0
- package/dist/LinearMafDisplay/components/YScaleBars.d.ts +8 -0
- package/dist/LinearMafDisplay/components/YScaleBars.js +20 -0
- package/dist/LinearMafDisplay/components/YScaleBars.js.map +1 -0
- package/dist/LinearMafDisplay/components/util.d.ts +1 -0
- package/dist/LinearMafDisplay/components/util.js +8 -0
- package/dist/LinearMafDisplay/components/util.js.map +1 -0
- package/dist/LinearMafDisplay/configSchema.d.ts +34 -0
- package/dist/LinearMafDisplay/configSchema.js +15 -0
- package/dist/LinearMafDisplay/configSchema.js.map +1 -0
- package/dist/LinearMafDisplay/index.d.ts +2 -0
- package/dist/LinearMafDisplay/index.js +20 -0
- package/dist/LinearMafDisplay/index.js.map +1 -0
- package/dist/LinearMafDisplay/renderSvg.d.ts +4 -0
- package/dist/LinearMafDisplay/renderSvg.js +18 -0
- package/dist/LinearMafDisplay/renderSvg.js.map +1 -0
- package/dist/LinearMafDisplay/stateModel.d.ts +426 -0
- package/dist/LinearMafDisplay/stateModel.js +276 -0
- package/dist/LinearMafDisplay/stateModel.js.map +1 -0
- package/dist/LinearMafDisplay/types.d.ts +17 -0
- package/dist/LinearMafDisplay/types.js +16 -0
- package/dist/LinearMafDisplay/types.js.map +1 -0
- package/dist/LinearMafRenderer/LinearMafRenderer.d.ts +45 -0
- package/dist/LinearMafRenderer/LinearMafRenderer.js +183 -0
- package/dist/LinearMafRenderer/LinearMafRenderer.js.map +1 -0
- package/dist/LinearMafRenderer/components/ReactComponent.d.ts +6 -0
- package/dist/LinearMafRenderer/components/ReactComponent.js +8 -0
- package/dist/LinearMafRenderer/components/ReactComponent.js.map +1 -0
- package/dist/LinearMafRenderer/configSchema.d.ts +2 -0
- package/dist/LinearMafRenderer/configSchema.js +13 -0
- package/dist/LinearMafRenderer/configSchema.js.map +1 -0
- package/dist/LinearMafRenderer/index.d.ts +2 -0
- package/dist/LinearMafRenderer/index.js +12 -0
- package/dist/LinearMafRenderer/index.js.map +1 -0
- package/dist/LinearMafRenderer/util.d.ts +10 -0
- package/dist/LinearMafRenderer/util.js +16 -0
- package/dist/LinearMafRenderer/util.js.map +1 -0
- package/dist/MafAddTrackWorkflow/AddTrackWorkflow.d.ts +5 -0
- package/dist/MafAddTrackWorkflow/AddTrackWorkflow.js +128 -0
- package/dist/MafAddTrackWorkflow/AddTrackWorkflow.js.map +1 -0
- package/dist/MafAddTrackWorkflow/index.d.ts +2 -0
- package/dist/MafAddTrackWorkflow/index.js +12 -0
- package/dist/MafAddTrackWorkflow/index.js.map +1 -0
- package/dist/MafRPC/index.d.ts +16 -0
- package/dist/MafRPC/index.js +19 -0
- package/dist/MafRPC/index.js.map +1 -0
- package/dist/MafTabixAdapter/MafTabixAdapter.d.ts +25 -0
- package/dist/MafTabixAdapter/MafTabixAdapter.js +95 -0
- package/dist/MafTabixAdapter/MafTabixAdapter.js.map +1 -0
- package/dist/MafTabixAdapter/configSchema.d.ts +50 -0
- package/dist/MafTabixAdapter/configSchema.js +56 -0
- package/dist/MafTabixAdapter/configSchema.js.map +1 -0
- package/dist/MafTabixAdapter/index.d.ts +2 -0
- package/dist/MafTabixAdapter/index.js +11 -0
- package/dist/MafTabixAdapter/index.js.map +1 -0
- package/dist/MafTrack/configSchema.d.ts +79 -0
- package/dist/MafTrack/configSchema.js +15 -0
- package/dist/MafTrack/configSchema.js.map +1 -0
- package/dist/MafTrack/index.d.ts +2 -0
- package/dist/MafTrack/index.js +14 -0
- package/dist/MafTrack/index.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/jbrowse-plugin-mafviewer.umd.production.min.js +65 -1
- package/dist/jbrowse-plugin-mafviewer.umd.production.min.js.map +7 -1
- package/dist/parseNewick.d.ts +60 -0
- package/dist/parseNewick.js +95 -0
- package/dist/parseNewick.js.map +1 -0
- package/dist/util.d.ts +9 -0
- package/dist/util.js +9 -0
- package/dist/util.js.map +1 -0
- package/package.json +37 -41
- package/src/BgzipTaffyAdapter/BgzipTaffyAdapter.ts +227 -0
- package/src/BgzipTaffyAdapter/configSchema.ts +59 -0
- package/src/BgzipTaffyAdapter/index.ts +16 -0
- package/src/BgzipTaffyAdapter/rowInstructions.ts +91 -0
- package/src/BgzipTaffyAdapter/types.ts +16 -0
- package/src/BgzipTaffyAdapter/virtualOffset.ts +29 -0
- package/src/BigMafAdapter/BigMafAdapter.ts +12 -13
- package/src/BigMafAdapter/configSchema.ts +11 -0
- package/src/BigMafAdapter/index.ts +2 -1
- package/src/LinearMafDisplay/components/ColorLegend.tsx +38 -27
- package/src/LinearMafDisplay/components/ReactComponent.tsx +68 -3
- package/src/LinearMafDisplay/components/SetRowHeight.tsx +15 -8
- package/src/LinearMafDisplay/components/SvgWrapper.tsx +39 -0
- package/src/LinearMafDisplay/components/Tree.tsx +33 -0
- package/src/LinearMafDisplay/components/YScaleBars.tsx +11 -38
- package/src/LinearMafDisplay/components/util.ts +7 -0
- package/src/LinearMafDisplay/index.ts +2 -1
- package/src/LinearMafDisplay/renderSvg.tsx +2 -1
- package/src/LinearMafDisplay/stateModel.ts +169 -18
- package/src/LinearMafDisplay/types.ts +41 -0
- package/src/LinearMafRenderer/LinearMafRenderer.ts +51 -44
- package/src/LinearMafRenderer/components/ReactComponent.tsx +2 -1
- package/src/LinearMafRenderer/index.ts +2 -1
- package/src/LinearMafRenderer/util.ts +20 -0
- package/src/MafAddTrackWorkflow/AddTrackWorkflow.tsx +133 -51
- package/src/MafRPC/index.ts +39 -0
- package/src/MafTabixAdapter/MafTabixAdapter.ts +33 -27
- package/src/MafTabixAdapter/configSchema.ts +17 -1
- package/src/MafTabixAdapter/index.ts +2 -1
- package/src/MafTrack/index.ts +1 -0
- package/src/index.ts +6 -2
- package/src/parseNewick.ts +94 -0
- package/src/util.ts +11 -0
- package/LICENSE +0 -201
- package/dist/jbrowse-plugin-mafviewer.umd.development.js +0 -1439
- package/dist/jbrowse-plugin-mafviewer.umd.development.js.map +0 -1
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
|
+
|
|
3
|
+
import { ErrorMessage, FileSelector } from '@jbrowse/core/ui'
|
|
4
|
+
import {
|
|
5
|
+
FileLocation,
|
|
6
|
+
getSession,
|
|
7
|
+
isSessionModelWithWidgets,
|
|
8
|
+
isSessionWithAddTracks,
|
|
9
|
+
} from '@jbrowse/core/util'
|
|
10
|
+
import { AddTrackModel } from '@jbrowse/plugin-data-management'
|
|
2
11
|
import {
|
|
3
12
|
Button,
|
|
4
13
|
FormControl,
|
|
@@ -9,16 +18,8 @@ import {
|
|
|
9
18
|
RadioGroup,
|
|
10
19
|
TextField,
|
|
11
20
|
} from '@mui/material'
|
|
12
|
-
import { makeStyles } from 'tss-react/mui'
|
|
13
|
-
import {
|
|
14
|
-
FileLocation,
|
|
15
|
-
getSession,
|
|
16
|
-
isSessionModelWithWidgets,
|
|
17
|
-
isSessionWithAddTracks,
|
|
18
|
-
} from '@jbrowse/core/util'
|
|
19
|
-
import { AddTrackModel } from '@jbrowse/plugin-data-management'
|
|
20
|
-
import { ErrorMessage, FileSelector } from '@jbrowse/core/ui'
|
|
21
21
|
import { getRoot } from 'mobx-state-tree'
|
|
22
|
+
import { makeStyles } from 'tss-react/mui'
|
|
22
23
|
|
|
23
24
|
const useStyles = makeStyles()(theme => ({
|
|
24
25
|
textbox: {
|
|
@@ -35,15 +36,25 @@ const useStyles = makeStyles()(theme => ({
|
|
|
35
36
|
},
|
|
36
37
|
}))
|
|
37
38
|
|
|
39
|
+
type AdapterTypeOptions =
|
|
40
|
+
| 'BigMafAdapter'
|
|
41
|
+
| 'MafTabixAdapter'
|
|
42
|
+
| 'BgzipTaffyAdapter'
|
|
43
|
+
type IndexTypeOptions = 'TBI' | 'CSI'
|
|
44
|
+
|
|
38
45
|
export default function MultiMAFWidget({ model }: { model: AddTrackModel }) {
|
|
39
46
|
const { classes } = useStyles()
|
|
40
47
|
const [samples, setSamples] = useState('')
|
|
41
48
|
const [loc, setLoc] = useState<FileLocation>()
|
|
42
49
|
const [indexLoc, setIndexLoc] = useState<FileLocation>()
|
|
50
|
+
const [nhLoc, setNhLoc] = useState<FileLocation>()
|
|
43
51
|
const [error, setError] = useState<unknown>()
|
|
44
52
|
const [trackName, setTrackName] = useState('MAF track')
|
|
45
|
-
const [
|
|
46
|
-
|
|
53
|
+
const [fileTypeChoice, setFileTypeChoice] =
|
|
54
|
+
useState<AdapterTypeOptions>('BigMafAdapter')
|
|
55
|
+
const [indexTypeChoice, setIndexTypeChoice] =
|
|
56
|
+
useState<IndexTypeOptions>('TBI')
|
|
57
|
+
|
|
47
58
|
const rootModel = getRoot<any>(model)
|
|
48
59
|
return (
|
|
49
60
|
<Paper className={classes.paper}>
|
|
@@ -52,63 +63,121 @@ export default function MultiMAFWidget({ model }: { model: AddTrackModel }) {
|
|
|
52
63
|
<FormControl>
|
|
53
64
|
<FormLabel>File type</FormLabel>
|
|
54
65
|
<RadioGroup
|
|
55
|
-
value={
|
|
56
|
-
onChange={event =>
|
|
66
|
+
value={fileTypeChoice}
|
|
67
|
+
onChange={event => {
|
|
68
|
+
setFileTypeChoice(event.target.value as AdapterTypeOptions)
|
|
69
|
+
}}
|
|
57
70
|
>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
label="mafTabix"
|
|
69
|
-
/>
|
|
71
|
+
{['BigMafAdapter', 'MafTabixAdapter', 'BgzipTaffyAdapter'].map(
|
|
72
|
+
r => (
|
|
73
|
+
<FormControlLabel
|
|
74
|
+
value={r}
|
|
75
|
+
control={<Radio />}
|
|
76
|
+
checked={fileTypeChoice === r}
|
|
77
|
+
label={r}
|
|
78
|
+
/>
|
|
79
|
+
),
|
|
80
|
+
)}
|
|
70
81
|
</RadioGroup>
|
|
71
82
|
</FormControl>
|
|
72
|
-
{
|
|
83
|
+
{fileTypeChoice === 'BigMafAdapter' ? (
|
|
73
84
|
<FileSelector
|
|
74
85
|
location={loc}
|
|
75
86
|
name="Path to bigMaf"
|
|
76
|
-
setLocation={arg => setLoc(arg)}
|
|
77
87
|
rootModel={rootModel}
|
|
88
|
+
setLocation={arg => {
|
|
89
|
+
setLoc(arg)
|
|
90
|
+
}}
|
|
78
91
|
/>
|
|
79
|
-
) : (
|
|
92
|
+
) : fileTypeChoice === 'MafTabixAdapter' ? (
|
|
80
93
|
<>
|
|
94
|
+
<FormControl>
|
|
95
|
+
<FormLabel>Index type</FormLabel>
|
|
96
|
+
<RadioGroup
|
|
97
|
+
value={fileTypeChoice}
|
|
98
|
+
onChange={event => {
|
|
99
|
+
setIndexTypeChoice(event.target.value as IndexTypeOptions)
|
|
100
|
+
}}
|
|
101
|
+
>
|
|
102
|
+
{['TBI', 'CSI'].map(r => (
|
|
103
|
+
<FormControlLabel
|
|
104
|
+
value={r}
|
|
105
|
+
control={<Radio />}
|
|
106
|
+
checked={fileTypeChoice === r}
|
|
107
|
+
label={r}
|
|
108
|
+
/>
|
|
109
|
+
))}
|
|
110
|
+
</RadioGroup>
|
|
111
|
+
</FormControl>
|
|
81
112
|
<FileSelector
|
|
82
113
|
location={loc}
|
|
83
114
|
name="Path to MAF tabix"
|
|
84
|
-
setLocation={arg => setLoc(arg)}
|
|
85
115
|
rootModel={rootModel}
|
|
116
|
+
setLocation={arg => {
|
|
117
|
+
setLoc(arg)
|
|
118
|
+
}}
|
|
86
119
|
/>
|
|
87
120
|
<FileSelector
|
|
88
121
|
location={indexLoc}
|
|
89
122
|
name="Path to MAF tabix index"
|
|
90
|
-
setLocation={arg => setIndexLoc(arg)}
|
|
91
123
|
rootModel={rootModel}
|
|
124
|
+
setLocation={arg => {
|
|
125
|
+
setIndexLoc(arg)
|
|
126
|
+
}}
|
|
127
|
+
/>
|
|
128
|
+
</>
|
|
129
|
+
) : (
|
|
130
|
+
<>
|
|
131
|
+
<FileSelector
|
|
132
|
+
location={loc}
|
|
133
|
+
name="Path to TAF.gz (Bgzipped TAF)"
|
|
134
|
+
rootModel={rootModel}
|
|
135
|
+
setLocation={arg => {
|
|
136
|
+
setLoc(arg)
|
|
137
|
+
}}
|
|
138
|
+
/>
|
|
139
|
+
<FileSelector
|
|
140
|
+
location={indexLoc}
|
|
141
|
+
name="Path to TAF.gz.tai (TAF index)"
|
|
142
|
+
rootModel={rootModel}
|
|
143
|
+
setLocation={arg => {
|
|
144
|
+
setIndexLoc(arg)
|
|
145
|
+
}}
|
|
92
146
|
/>
|
|
93
147
|
</>
|
|
94
148
|
)}
|
|
95
149
|
</Paper>
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
150
|
+
<div>
|
|
151
|
+
<FileSelector
|
|
152
|
+
location={nhLoc}
|
|
153
|
+
name="Path to newick tree (.nh)"
|
|
154
|
+
rootModel={rootModel}
|
|
155
|
+
setLocation={arg => {
|
|
156
|
+
setNhLoc(arg)
|
|
157
|
+
}}
|
|
158
|
+
/>
|
|
159
|
+
<TextField
|
|
160
|
+
multiline
|
|
161
|
+
rows={10}
|
|
162
|
+
value={samples}
|
|
163
|
+
onChange={event => {
|
|
164
|
+
setSamples(event.target.value)
|
|
165
|
+
}}
|
|
166
|
+
helperText="Sample names (optional if .nh supplied, required if not)"
|
|
167
|
+
placeholder={
|
|
168
|
+
'Enter sample names from the MAF file, one per line, or JSON formatted array of samples'
|
|
169
|
+
}
|
|
170
|
+
variant="outlined"
|
|
171
|
+
fullWidth
|
|
172
|
+
/>
|
|
173
|
+
</div>
|
|
107
174
|
|
|
108
175
|
<TextField
|
|
109
176
|
value={trackName}
|
|
110
|
-
onChange={event => setTrackName(event.target.value)}
|
|
111
177
|
helperText="Track name"
|
|
178
|
+
onChange={event => {
|
|
179
|
+
setTrackName(event.target.value)
|
|
180
|
+
}}
|
|
112
181
|
/>
|
|
113
182
|
<Button
|
|
114
183
|
variant="contained"
|
|
@@ -125,7 +194,7 @@ export default function MultiMAFWidget({ model }: { model: AddTrackModel }) {
|
|
|
125
194
|
|
|
126
195
|
const trackId = [
|
|
127
196
|
`${trackName.toLowerCase().replaceAll(' ', '_')}-${Date.now()}`,
|
|
128
|
-
|
|
197
|
+
session.adminMode ? '' : '-sessionTrack',
|
|
129
198
|
].join('')
|
|
130
199
|
|
|
131
200
|
if (isSessionWithAddTracks(session)) {
|
|
@@ -135,18 +204,31 @@ export default function MultiMAFWidget({ model }: { model: AddTrackModel }) {
|
|
|
135
204
|
name: trackName,
|
|
136
205
|
assemblyNames: [model.assembly],
|
|
137
206
|
adapter:
|
|
138
|
-
|
|
207
|
+
fileTypeChoice === 'BigMafAdapter'
|
|
139
208
|
? {
|
|
140
|
-
type:
|
|
209
|
+
type: fileTypeChoice,
|
|
141
210
|
bigBedLocation: loc,
|
|
142
211
|
samples: sampleNames,
|
|
212
|
+
nhLocation: nhLoc,
|
|
143
213
|
}
|
|
144
|
-
:
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
214
|
+
: fileTypeChoice === 'MafTabixAdapter'
|
|
215
|
+
? {
|
|
216
|
+
type: fileTypeChoice,
|
|
217
|
+
bedGzLocation: loc,
|
|
218
|
+
nhLocation: nhLoc,
|
|
219
|
+
index: {
|
|
220
|
+
indexType: indexTypeChoice,
|
|
221
|
+
location: indexLoc,
|
|
222
|
+
},
|
|
223
|
+
samples: sampleNames,
|
|
224
|
+
}
|
|
225
|
+
: {
|
|
226
|
+
type: fileTypeChoice,
|
|
227
|
+
tafGzLocation: loc,
|
|
228
|
+
taiLocation: indexLoc,
|
|
229
|
+
nhLocation: nhLoc,
|
|
230
|
+
samples: sampleNames,
|
|
231
|
+
},
|
|
150
232
|
})
|
|
151
233
|
|
|
152
234
|
model.view?.showTrack(trackId)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache'
|
|
2
|
+
import RpcMethodTypeWithFiltersAndRenameRegions from '@jbrowse/core/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions'
|
|
3
|
+
|
|
4
|
+
import type PluginManager from '@jbrowse/core/PluginManager'
|
|
5
|
+
import type { AnyConfigurationModel } from '@jbrowse/core/configuration'
|
|
6
|
+
import type { Region } from '@jbrowse/core/util'
|
|
7
|
+
|
|
8
|
+
export class MafGetSamples extends RpcMethodTypeWithFiltersAndRenameRegions {
|
|
9
|
+
name = 'MafGetSamples'
|
|
10
|
+
|
|
11
|
+
async execute(
|
|
12
|
+
args: {
|
|
13
|
+
adapterConfig: AnyConfigurationModel
|
|
14
|
+
stopToken?: string
|
|
15
|
+
sessionId: string
|
|
16
|
+
headers?: Record<string, string>
|
|
17
|
+
regions: Region[]
|
|
18
|
+
bpPerPx: number
|
|
19
|
+
},
|
|
20
|
+
rpcDriverClassName: string,
|
|
21
|
+
) {
|
|
22
|
+
const pm = this.pluginManager
|
|
23
|
+
const deserializedArgs = await this.deserializeArguments(
|
|
24
|
+
args,
|
|
25
|
+
rpcDriverClassName,
|
|
26
|
+
)
|
|
27
|
+
const { regions, adapterConfig, sessionId } = deserializedArgs
|
|
28
|
+
const { dataAdapter } = await getAdapter(pm, sessionId, adapterConfig)
|
|
29
|
+
|
|
30
|
+
// @ts-expect-error
|
|
31
|
+
return dataAdapter.getSamples(regions, deserializedArgs)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default function MafRPCF(pluginManager: PluginManager) {
|
|
36
|
+
pluginManager.addRpcMethod(() => {
|
|
37
|
+
return new MafGetSamples(pluginManager)
|
|
38
|
+
})
|
|
39
|
+
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter'
|
|
2
|
-
import { getSnapshot } from 'mobx-state-tree'
|
|
3
2
|
import { Feature, Region, SimpleFeature } from '@jbrowse/core/util'
|
|
3
|
+
import { openLocation } from '@jbrowse/core/util/io'
|
|
4
4
|
import { ObservableCreate } from '@jbrowse/core/util/rxjs'
|
|
5
|
+
import { getSnapshot } from 'mobx-state-tree'
|
|
5
6
|
import { firstValueFrom, toArray } from 'rxjs'
|
|
6
7
|
|
|
8
|
+
import parseNewick from '../parseNewick'
|
|
9
|
+
import { normalize } from '../util'
|
|
10
|
+
|
|
7
11
|
interface OrganismRecord {
|
|
8
12
|
chr: string
|
|
9
13
|
start: number
|
|
@@ -13,7 +17,7 @@ interface OrganismRecord {
|
|
|
13
17
|
data: string
|
|
14
18
|
}
|
|
15
19
|
|
|
16
|
-
export default class
|
|
20
|
+
export default class MafTabixAdapter extends BaseFeatureDataAdapter {
|
|
17
21
|
public setupP?: Promise<{ adapter: BaseFeatureDataAdapter }>
|
|
18
22
|
|
|
19
23
|
async setup() {
|
|
@@ -31,7 +35,7 @@ export default class BigMafAdapter extends BaseFeatureDataAdapter {
|
|
|
31
35
|
}
|
|
32
36
|
async setupPre() {
|
|
33
37
|
if (!this.setupP) {
|
|
34
|
-
this.setupP = this.setup().catch(e => {
|
|
38
|
+
this.setupP = this.setup().catch((e: unknown) => {
|
|
35
39
|
this.setupP = undefined
|
|
36
40
|
throw e
|
|
37
41
|
})
|
|
@@ -55,13 +59,7 @@ export default class BigMafAdapter extends BaseFeatureDataAdapter {
|
|
|
55
59
|
const features = await firstValueFrom(
|
|
56
60
|
adapter.getFeatures(query).pipe(toArray()),
|
|
57
61
|
)
|
|
58
|
-
|
|
59
|
-
const sampleStrings =
|
|
60
|
-
typeof samples[0] === 'string'
|
|
61
|
-
? (samples as string[])
|
|
62
|
-
: (samples as { id: string }[]).map(s => s.id)
|
|
63
|
-
const sampleSet = new Set(sampleStrings)
|
|
64
|
-
let i = 0
|
|
62
|
+
|
|
65
63
|
for (const feature of features) {
|
|
66
64
|
const data = (feature.get('field5') as string).split(',')
|
|
67
65
|
const alignments = {} as Record<string, OrganismRecord>
|
|
@@ -69,26 +67,18 @@ export default class BigMafAdapter extends BaseFeatureDataAdapter {
|
|
|
69
67
|
|
|
70
68
|
for (const [j, elt] of data.entries()) {
|
|
71
69
|
const ad = elt.split(':')
|
|
72
|
-
const idx = ad[0]
|
|
73
|
-
const org = ad[0]
|
|
74
|
-
const last = ad[0]
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
: sampleStrings.find(f => ad[0].startsWith(f))
|
|
78
|
-
if (s) {
|
|
79
|
-
alignments[s] = {
|
|
70
|
+
const idx = ad[0]!.lastIndexOf('.')
|
|
71
|
+
const org = ad[0]!.slice(0, idx)
|
|
72
|
+
const last = ad[0]!.slice(idx + 1)
|
|
73
|
+
if (org) {
|
|
74
|
+
alignments[org] = {
|
|
80
75
|
chr: last,
|
|
81
|
-
start: +ad[1]
|
|
82
|
-
srcSize: +ad[2]
|
|
76
|
+
start: +ad[1]!,
|
|
77
|
+
srcSize: +ad[2]!,
|
|
83
78
|
strand: ad[3] === '-' ? -1 : 1,
|
|
84
|
-
unknown: +ad[4]
|
|
85
|
-
data: alns[j]
|
|
79
|
+
unknown: +ad[4]!,
|
|
80
|
+
data: alns[j]!,
|
|
86
81
|
}
|
|
87
|
-
} else if (i < 100) {
|
|
88
|
-
console.error(`line not processed ${ad[0]}`)
|
|
89
|
-
i++
|
|
90
|
-
} else if (i > 100) {
|
|
91
|
-
console.error('too many errors, not printing any more')
|
|
92
82
|
}
|
|
93
83
|
}
|
|
94
84
|
|
|
@@ -110,5 +100,21 @@ export default class BigMafAdapter extends BaseFeatureDataAdapter {
|
|
|
110
100
|
observer.complete()
|
|
111
101
|
})
|
|
112
102
|
}
|
|
103
|
+
|
|
104
|
+
async getSamples(_query: Region) {
|
|
105
|
+
const nhLoc = this.getConf('nhLocation')
|
|
106
|
+
const nh =
|
|
107
|
+
nhLoc.uri === '/path/to/my.nh'
|
|
108
|
+
? undefined
|
|
109
|
+
: await openLocation(nhLoc).readFile('utf8')
|
|
110
|
+
|
|
111
|
+
// TODO: we may need to resolve the exact set of rows in the visible region
|
|
112
|
+
// here
|
|
113
|
+
return {
|
|
114
|
+
samples: normalize(this.getConf('samples')),
|
|
115
|
+
tree: nh ? parseNewick(nh) : undefined,
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
113
119
|
freeResources(): void {}
|
|
114
120
|
}
|
|
@@ -2,7 +2,6 @@ import { ConfigurationSchema } from '@jbrowse/core/configuration'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* #config MafTabixAdapter
|
|
5
|
-
* used to configure MafTabix adapter
|
|
6
5
|
*/
|
|
7
6
|
function x() {} // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
8
7
|
|
|
@@ -28,17 +27,34 @@ const configSchema = ConfigurationSchema(
|
|
|
28
27
|
},
|
|
29
28
|
},
|
|
30
29
|
index: ConfigurationSchema('Index', {
|
|
30
|
+
/**
|
|
31
|
+
* #slot index.location
|
|
32
|
+
*/
|
|
31
33
|
location: {
|
|
32
34
|
type: 'fileLocation',
|
|
33
35
|
defaultValue: {
|
|
34
36
|
uri: '/path/to/my.bed.gz.tbi',
|
|
35
37
|
},
|
|
36
38
|
},
|
|
39
|
+
/**
|
|
40
|
+
* #slot index.indexType
|
|
41
|
+
*/
|
|
37
42
|
indexType: {
|
|
38
43
|
type: 'string',
|
|
39
44
|
defaultValue: 'TBI',
|
|
40
45
|
},
|
|
41
46
|
}),
|
|
47
|
+
/**
|
|
48
|
+
* #slot
|
|
49
|
+
*/
|
|
50
|
+
nhLocation: {
|
|
51
|
+
type: 'fileLocation',
|
|
52
|
+
description: 'newick tree',
|
|
53
|
+
defaultValue: {
|
|
54
|
+
uri: '/path/to/my.nh',
|
|
55
|
+
locationType: 'UriLocation',
|
|
56
|
+
},
|
|
57
|
+
},
|
|
42
58
|
},
|
|
43
59
|
{ explicitlyTyped: true },
|
|
44
60
|
)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import PluginManager from '@jbrowse/core/PluginManager'
|
|
2
2
|
import { AdapterType } from '@jbrowse/core/pluggableElementTypes'
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import MafTabixAdapter from './MafTabixAdapter'
|
|
5
|
+
import configSchema from './configSchema'
|
|
5
6
|
|
|
6
7
|
export default function MafTabixAdapterF(pluginManager: PluginManager) {
|
|
7
8
|
return pluginManager.addAdapterType(
|
package/src/MafTrack/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -2,12 +2,14 @@ import Plugin from '@jbrowse/core/Plugin'
|
|
|
2
2
|
import PluginManager from '@jbrowse/core/PluginManager'
|
|
3
3
|
|
|
4
4
|
import { version } from '../package.json'
|
|
5
|
+
import BgzipTaffyAdapterF from './BgzipTaffyAdapter'
|
|
5
6
|
import BigMafAdapterF from './BigMafAdapter'
|
|
6
|
-
import MafTrackF from './MafTrack'
|
|
7
7
|
import LinearMafDisplayF from './LinearMafDisplay'
|
|
8
8
|
import LinearMafRendererF from './LinearMafRenderer'
|
|
9
|
-
import MafTabixAdapterF from './MafTabixAdapter'
|
|
10
9
|
import MafAddTrackWorkflowF from './MafAddTrackWorkflow'
|
|
10
|
+
import MafRPCF from './MafRPC'
|
|
11
|
+
import MafTabixAdapterF from './MafTabixAdapter'
|
|
12
|
+
import MafTrackF from './MafTrack'
|
|
11
13
|
|
|
12
14
|
export default class MafViewerPlugin extends Plugin {
|
|
13
15
|
name = 'MafViewerPlugin'
|
|
@@ -19,7 +21,9 @@ export default class MafViewerPlugin extends Plugin {
|
|
|
19
21
|
LinearMafDisplayF(pluginManager)
|
|
20
22
|
LinearMafRendererF(pluginManager)
|
|
21
23
|
MafTabixAdapterF(pluginManager)
|
|
24
|
+
BgzipTaffyAdapterF(pluginManager)
|
|
22
25
|
MafAddTrackWorkflowF(pluginManager)
|
|
26
|
+
MafRPCF(pluginManager)
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
configure(_pluginManager: PluginManager) {}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Newick format parser in JavaScript.
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Jason Davies 2010.
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
* furnished to do so, subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice shall be included in
|
|
14
|
+
* all copies or substantial portions of the Software.
|
|
15
|
+
*
|
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
22
|
+
* THE SOFTWARE.
|
|
23
|
+
*
|
|
24
|
+
* Example tree (from http://en.wikipedia.org/wiki/Newick_format):
|
|
25
|
+
*
|
|
26
|
+
* +--0.1--A
|
|
27
|
+
* F-----0.2-----B +-------0.3----C
|
|
28
|
+
* +------------------0.5-----E
|
|
29
|
+
* +---------0.4------D
|
|
30
|
+
*
|
|
31
|
+
* Newick format:
|
|
32
|
+
* (A:0.1,B:0.2,(C:0.3,D:0.4)E:0.5)F;
|
|
33
|
+
*
|
|
34
|
+
* Converted to JSON:
|
|
35
|
+
* {
|
|
36
|
+
* name: "F",
|
|
37
|
+
* children: [
|
|
38
|
+
* {name: "A", length: 0.1},
|
|
39
|
+
* {name: "B", length: 0.2},
|
|
40
|
+
* {
|
|
41
|
+
* name: "E",
|
|
42
|
+
* length: 0.5,
|
|
43
|
+
* children: [
|
|
44
|
+
* {name: "C", length: 0.3},
|
|
45
|
+
* {name: "D", length: 0.4}
|
|
46
|
+
* ]
|
|
47
|
+
* }
|
|
48
|
+
* ]
|
|
49
|
+
* }
|
|
50
|
+
*
|
|
51
|
+
* Converted to JSON, but with no names or lengths:
|
|
52
|
+
* {
|
|
53
|
+
* children: [
|
|
54
|
+
* {}, {}, {
|
|
55
|
+
* children: [{}, {}]
|
|
56
|
+
* }
|
|
57
|
+
* ]
|
|
58
|
+
* }
|
|
59
|
+
*/
|
|
60
|
+
export default function parseNewick(s: string) {
|
|
61
|
+
const ancestors = []
|
|
62
|
+
|
|
63
|
+
let tree = {} as Record<string, any>
|
|
64
|
+
const tokens = s.split(/\s*(;|\(|\)|,|:)\s*/)
|
|
65
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
66
|
+
const token = tokens[i]!
|
|
67
|
+
const subtree = {}
|
|
68
|
+
switch (token) {
|
|
69
|
+
case '(': // new children
|
|
70
|
+
tree.children = [subtree]
|
|
71
|
+
ancestors.push(tree)
|
|
72
|
+
tree = subtree
|
|
73
|
+
break
|
|
74
|
+
case ',': // another branch
|
|
75
|
+
ancestors.at(-1)?.children.push(subtree)
|
|
76
|
+
tree = subtree
|
|
77
|
+
break
|
|
78
|
+
case ')': // optional name next
|
|
79
|
+
tree = ancestors.pop()!
|
|
80
|
+
break
|
|
81
|
+
case ':': // optional length next
|
|
82
|
+
break
|
|
83
|
+
default: {
|
|
84
|
+
const x = tokens[i - 1]!
|
|
85
|
+
if (x === ')' || x === '(' || x === ',') {
|
|
86
|
+
tree.name = token
|
|
87
|
+
} else if (x === ':') {
|
|
88
|
+
tree.length = Number.parseFloat(token)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return tree
|
|
94
|
+
}
|
package/src/util.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
function isStrs(array: unknown[]): array is string[] {
|
|
2
|
+
return typeof array[0] === 'string'
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function normalize(
|
|
6
|
+
r: string[] | { id: string; label: string; color?: string }[],
|
|
7
|
+
) {
|
|
8
|
+
return isStrs(r)
|
|
9
|
+
? r.map(elt => ({ id: elt, label: elt, color: undefined }))
|
|
10
|
+
: r
|
|
11
|
+
}
|