jbrowse-plugin-msaview 3.7.0 → 3.8.0

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 CHANGED
@@ -1,25 +1,26 @@
1
1
  # jbrowse-plugin-msaview
2
2
 
3
- This plugin packages https://github.com/gmod/react-msaview for usage inside of
4
- JBrowse 2
5
-
6
- See the docs for the react-msaview for more info
7
- https://github.com/GMOD/react-msaview/blob/main/docs/user_guide.md
3
+ A multiple sequence alignment and phylogenetic tree viewer for JBrowse 2, linked
4
+ column by column to the genome. It packages
5
+ [react-msaview](https://github.com/GMOD/react-msaview), whose
6
+ [user guide](https://github.com/GMOD/react-msaview/blob/main/docs/user_guide.md)
7
+ covers the viewer itself.
8
8
 
9
9
  ## Gallery
10
10
 
11
11
  ![](img/1.png)
12
12
 
13
- MSAView plugin running in JBrowse 2
13
+ The [demo](#demo) below: TP53 in the genome view beside a vertebrate p53
14
+ alignment carrying per-residue variant tracks. Each release recaptures it with
15
+ `pnpm readme-figure`.
14
16
 
15
17
  ## Demo
16
18
 
17
- [p53 across vertebrates, linked to the genome and the structure](https://jbrowse.org/code/jb2/main/?config=https://jbrowse.org/ucsc/hg38/config.json&session=spec-{%22views%22:[{%22type%22:%22LinearGenomeView%22,%22id%22:%22lgv1%22,%22assembly%22:%22hg38%22,%22loc%22:%22chr17:7,661,779-7,687,538%22,%22tracks%22:[%22hg38-ncbiRefSeqSelect%22,%22hg38-clinvarMain%22]},{%22type%22:%22MsaView%22,%22displayName%22:%22p53%20across%20vertebrates%22,%22msaFileLocation%22:{%22uri%22:%22https://gmod.org/JBrowseMSA/demo/data/p53/p53-vertebrates.afa%22},%22treeFileLocation%22:{%22uri%22:%22https://gmod.org/JBrowseMSA/demo/data/p53/p53-vertebrates.nh%22},%22querySeqName%22:%22Human%22,%22relativeTo%22:%22Human%22,%22connectedViewId%22:%22lgv1%22,%22connectedTranscript%22:%22NM_000546.6%22,%22placement%22:%22splitRight%22,%22colorSchemeName%22:%22clustalx_protein_dynamic%22,%22highlights%22:[{%22row%22:%22Human%22,%22start%22:102,%22end%22:292,%22label%22:%22DNA-binding%22,%22color%22:%22rgba%28255,140,0,0.15%29%22},{%22row%22:%22Human%22,%22start%22:175,%22end%22:175,%22label%22:%22R175%22},{%22row%22:%22Human%22,%22start%22:245,%22end%22:245,%22label%22:%22G245%22},{%22row%22:%22Human%22,%22start%22:248,%22end%22:248,%22label%22:%22R248%22},{%22row%22:%22Human%22,%22start%22:249,%22end%22:249,%22label%22:%22R249%22},{%22row%22:%22Human%22,%22start%22:273,%22end%22:273,%22label%22:%22R273%22},{%22row%22:%22Human%22,%22start%22:282,%22end%22:282,%22label%22:%22R282%22}],%22columnTracks%22:[{%22id%22:%22clinvar%22,%22name%22:%22ClinVar%20pathogenic%20missense%22,%22kind%22:%22bar%22,%22row%22:%22Human%22,%22color%22:%22%23c0392b%22,%22height%22:60,%22max%22:8,%22values%22:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,2,4,3,0,6,0,0,0,0,0,0,0,0,0,0,1,2,1,5,0,0,2,2,3,1,1,4,0,0,2,0,0,2,0,3,0,0,0,1,0,0,0,6,2,0,0,1,1,3,6,2,0,1,0,2,1,1,0,0,2,0,0,2,1,3,0,3,3,1,3,5,1,3,0,0,0,0,0,0,0,0,1,0,0,4,3,1,1,1,0,1,0,0,0,0,0,3,0,0,0,0,0,0,0,3,2,1,1,0,1,0,3,0,0,0,0,0,0,0,0,0,0,0,3,0,4,0,2,4,6,2,3,5,2,0,4,5,4,1,6,2,1,2,0,1,3,0,0,0,2,1,0,0,0,0,0,2,3,3,0,1,4,1,3,6,0,2,1,1,3,0,3,8,3,1,0,2,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,5,0,0,0,1,1,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},{%22id%22:%22alphamissense%22,%22name%22:%22AlphaMissense%20mean%20%28x100%29%22,%22kind%22:%22bar%22,%22row%22:%22Human%22,%22color%22:%22%231565c0%22,%22height%22:60,%22max%22:100,%22values%22:[49,27,19,11,12,14,18,10,12,14,28,17,40,57,73,65,65,68,95,29,30,72,95,21,24,60,39,21,18,17,18,16,17,12,11,13,14,13,14,21,22,20,17,20,16,16,15,14,17,17,15,13,37,29,11,19,16,11,11,12,14,20,14,12,11,20,13,19,15,14,12,13,15,17,14,17,15,19,20,17,15,15,22,22,19,22,20,24,17,23,67,41,46,66,63,37,90,98,63,35,36,20,76,15,99,13,58,48,98,26,81,57,97,43,17,64,87,68,90,98,96,92,73,81,98,91,95,23,13,81,56,97,84,97,98,87,86,81,91,84,94,93,89,66,81,57,77,26,20,13,90,69,17,52,70,49,91,98,87,88,94,87,95,89,48,54,52,76,76,68,92,87,98,78,99,100,98,97,100,96,85,50,38,52,32,74,52,32,83,87,71,47,99,95,89,95,91,96,95,81,20,25,69,48,98,24,64,93,17,23,84,56,99,92,91,93,70,89,76,91,77,27,92,87,57,92,58,35,54,68,75,87,85,87,74,93,96,100,95,98,99,100,94,100,100,98,97,100,99,93,93,59,91,91,87,92,93,99,87,22,21,94,24,76,83,99,98,36,61,97,93,93,99,95,100,97,100,100,99,100,100,97,84,60,98,96,47,62,13,18,56,34,17,17,11,9,9,16,11,15,13,18,20,17,81,75,26,26,23,13,12,14,16,18,18,14,15,15,47,54,46,19,13,34,24,50,56,88,36,87,48,93,63,98,73,40,89,90,45,60,88,51,36,81,77,55,79,75,87,31,54,67,23,18,17,16,25,22,13,15,15,16,20,18,15,20,25,13,15,56,21,47,45,21,16,16,15,21,16,20,66,47,13,26,19,66,13,28,18,16,47,54,66]},{%22id%22:%22mavedb%22,%22name%22:%22MaveDB%20nutlin-3,%20p53WT%22,%22kind%22:%22bar%22,%22row%22:%22Human%22,%22color%22:%22%232e7d32%22,%22height%22:60,%22max%22:2,%22values%22:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.6,0,0.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.1,0,0,0.2,0.4,0,0,0,0,0.1,0,0.8,0,0.7,0.3,1.6,0.1,1.4,0.1,1.3,0,0,0,0.1,0,0.1,0.5,0.2,0.4,0.4,0.8,0.8,1.4,1.5,0.1,0.1,1.2,1,1.7,1.1,1.4,1.3,0.8,0.5,0.5,0.8,0.4,1.2,0.4,1.4,0.7,1.2,0.6,1.1,0.5,0.4,0.6,1.5,1.3,0,0.7,1.3,0.3,1.4,1,1.4,0.8,1.4,0.8,1.8,0.8,0.3,0,0.2,0.8,0.4,0,0.6,0.7,1.7,1,1.2,2,1.1,0.6,2,0.8,0.7,0.3,0.1,0.4,0.2,0.3,0.1,0.1,0.5,0.8,0.1,0.1,1.4,1.6,1.4,0.7,1.3,0.1,0.1,0,0,0,0.9,0.3,1.8,0,0,1,0,0.1,0.9,0.7,1.2,1.1,1.5,1.4,0.6,1.3,0.5,1.5,0.4,0.3,0.6,0.3,0.1,0.4,0.3,0.2,0.7,0.5,0.6,1.4,0.5,1.4,0.6,1.7,1.1,1.9,0.8,1.3,1.3,1.7,0.9,1.7,2.2,2,0.9,1.5,2.1,1,1.4,0.3,1.3,1.2,1.4,0.8,1.4,1.4,0.9,0.5,0.5,0.7,0.5,0.5,0.8,1.6,1,0.9,0.8,1.5,1.3,1.5,1.5,1.7,1.8,0.5,0.4,2,0,0.9,0.6,1,0,0,1,1.8,0,0.1,0.2,0.1,0.2,0,0.1,0.4,0.4,0.3,0.4,0.6,0.4,0.6,0.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}],%22region%22:{%22row%22:%22Human%22,%22start%22:170,%22end%22:290}},{%22type%22:%22ProteinView%22,%22uniprotId%22:%22P04637%22,%22transcriptId%22:%22NM_000546.6%22,%22connectedViewId%22:%22lgv1%22,%22connectedView%22:{%22assembly%22:%22hg38%22,%22loc%22:%22chr17:7,661,779-7,687,538%22,%22tracks%22:[%22hg38-ncbiRefSeqSelect%22]}}]}):
18
- TP53 in hg38 with ClinVar, a vertebrate p53 alignment carrying ClinVar,
19
- AlphaMissense and MaveDB per-residue tracks, and the AlphaFold model of P04637.
20
- Hovering a codon, a column or a residue lights the other two views. See
21
- [DEVELOPERS.md](DEVELOPERS.md#demo-p53-variant-evidence) for how the link is
22
- built.
19
+ [p53 across vertebrates, linked to the genome and the structure](https://jbrowse.org/code/jb2/main/?config=https://jbrowse.org/ucsc/hg38/config.json&session=spec-{%22views%22:[{%22type%22:%22LinearGenomeView%22,%22id%22:%22lgv1%22,%22assembly%22:%22hg38%22,%22loc%22:%22chr17:7,661,779-7,687,538%22,%22tracks%22:[%22hg38-ncbiRefSeqSelect%22]},{%22type%22:%22MsaView%22,%22displayName%22:%22p53%20across%20vertebrates%22,%22msa%22:%22https://gmod.org/JBrowseMSA/demo/data/p53/p53-vertebrates.afa%22,%22tree%22:%22https://gmod.org/JBrowseMSA/demo/data/p53/p53-vertebrates.nh%22,%22query%22:%22Human%22,%22connectedViewId%22:%22lgv1%22,%22connectedTranscript%22:%22NM_000546.6%22,%22placement%22:%22splitRight%22,%22colorSchemeName%22:%22clustalx_protein_dynamic%22,%22highlights%22:[{%22start%22:102,%22end%22:292,%22label%22:%22DNA-binding%22,%22color%22:%22rgba%28255,140,0,0.15%29%22},175,245,248,249,273,282],%22region%22:%22170-290%22,%22columnTracks%22:[{%22name%22:%22ClinVar%20pathogenic%20missense%22,%22color%22:%22%23c0392b%22,%22max%22:8,%22start%22:105,%22values%22:[2,1,0,0,2,4,3,0,6,0,0,0,0,0,0,0,0,0,0,1,2,1,5,0,0,2,2,3,1,1,4,0,0,2,0,0,2,0,3,0,0,0,1,0,0,0,6,2,0,0,1,1,3,6,2,0,1,0,2,1,1,0,0,2,0,0,2,1,3,0,3,3,1,3,5,1,3,0,0,0,0,0,0,0,0,1,0,0,4,3,1,1,1,0,1,0,0,0,0,0,3,0,0,0,0,0,0,0,3,2,1,1,0,1,0,3,0,0,0,0,0,0,0,0,0,0,0,3,0,4,0,2,4,6,2,3,5,2,0,4,5,4,1,6,2,1,2,0,1,3,0,0,0,2,1,0,0,0,0,0,2,3,3,0,1,4,1,3,6,0,2,1,1,3,0,3,8,3,1,0,2,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,5,0,0,0,1,1,0,2,0,0,1]},{%22name%22:%22AlphaMissense%20mean%20%28x100%29%22,%22color%22:%22%231565c0%22,%22max%22:100,%22values%22:[49,27,19,11,12,14,18,10,12,14,28,17,40,57,73,65,65,68,95,29,30,72,95,21,24,60,39,21,18,17,18,16,17,12,11,13,14,13,14,21,22,20,17,20,16,16,15,14,17,17,15,13,37,29,11,19,16,11,11,12,14,20,14,12,11,20,13,19,15,14,12,13,15,17,14,17,15,19,20,17,15,15,22,22,19,22,20,24,17,23,67,41,46,66,63,37,90,98,63,35,36,20,76,15,99,13,58,48,98,26,81,57,97,43,17,64,87,68,90,98,96,92,73,81,98,91,95,23,13,81,56,97,84,97,98,87,86,81,91,84,94,93,89,66,81,57,77,26,20,13,90,69,17,52,70,49,91,98,87,88,94,87,95,89,48,54,52,76,76,68,92,87,98,78,99,100,98,97,100,96,85,50,38,52,32,74,52,32,83,87,71,47,99,95,89,95,91,96,95,81,20,25,69,48,98,24,64,93,17,23,84,56,99,92,91,93,70,89,76,91,77,27,92,87,57,92,58,35,54,68,75,87,85,87,74,93,96,100,95,98,99,100,94,100,100,98,97,100,99,93,93,59,91,91,87,92,93,99,87,22,21,94,24,76,83,99,98,36,61,97,93,93,99,95,100,97,100,100,99,100,100,97,84,60,98,96,47,62,13,18,56,34,17,17,11,9,9,16,11,15,13,18,20,17,81,75,26,26,23,13,12,14,16,18,18,14,15,15,47,54,46,19,13,34,24,50,56,88,36,87,48,93,63,98,73,40,89,90,45,60,88,51,36,81,77,55,79,75,87,31,54,67,23,18,17,16,25,22,13,15,15,16,20,18,15,20,25,13,15,56,21,47,45,21,16,16,15,21,16,20,66,47,13,26,19,66,13,28,18,16,47,54,66]},{%22name%22:%22MaveDB%20nutlin-3,%20p53WT%22,%22color%22:%22%232e7d32%22,%22max%22:2,%22start%22:27,%22values%22:[0.6,0,0.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.1,0,0,0.2,0.4,0,0,0,0,0.1,0,0.8,0,0.7,0.3,1.6,0.1,1.4,0.1,1.3,0,0,0,0.1,0,0.1,0.5,0.2,0.4,0.4,0.8,0.8,1.4,1.5,0.1,0.1,1.2,1,1.7,1.1,1.4,1.3,0.8,0.5,0.5,0.8,0.4,1.2,0.4,1.4,0.7,1.2,0.6,1.1,0.5,0.4,0.6,1.5,1.3,0,0.7,1.3,0.3,1.4,1,1.4,0.8,1.4,0.8,1.8,0.8,0.3,0,0.2,0.8,0.4,0,0.6,0.7,1.7,1,1.2,2,1.1,0.6,2,0.8,0.7,0.3,0.1,0.4,0.2,0.3,0.1,0.1,0.5,0.8,0.1,0.1,1.4,1.6,1.4,0.7,1.3,0.1,0.1,0,0,0,0.9,0.3,1.8,0,0,1,0,0.1,0.9,0.7,1.2,1.1,1.5,1.4,0.6,1.3,0.5,1.5,0.4,0.3,0.6,0.3,0.1,0.4,0.3,0.2,0.7,0.5,0.6,1.4,0.5,1.4,0.6,1.7,1.1,1.9,0.8,1.3,1.3,1.7,0.9,1.7,2.2,2,0.9,1.5,2.1,1,1.4,0.3,1.3,1.2,1.4,0.8,1.4,1.4,0.9,0.5,0.5,0.7,0.5,0.5,0.8,1.6,1,0.9,0.8,1.5,1.3,1.5,1.5,1.7,1.8,0.5,0.4,2,0,0.9,0.6,1,0,0,1,1.8,0,0.1,0.2,0.1,0.2,0,0.1,0.4,0.4,0.3,0.4,0.6,0.4,0.6,0.5]}]},{%22type%22:%22ProteinView%22,%22uniprotId%22:%22P04637%22,%22transcriptId%22:%22NM_000546.6%22,%22connectedViewId%22:%22lgv1%22,%22connectedView%22:{%22assembly%22:%22hg38%22,%22loc%22:%22chr17:7,661,779-7,687,538%22,%22tracks%22:[%22hg38-ncbiRefSeqSelect%22]}}]}):
20
+ TP53 in hg38, a vertebrate p53 alignment carrying ClinVar, AlphaMissense and
21
+ MaveDB per-residue tracks, and the AlphaFold model of P04637. Hovering a codon,
22
+ a column or a residue lights the other two views.
23
+ [Launching](docs/launching.md#the-readme-demo-taken-apart) takes the link apart.
23
24
 
24
25
  An older shared session:
25
26
  https://jbrowse.org/code/jb2/main/index.html?config=https://unpkg.com/jbrowse-plugin-msaview/dist/config.json&session=share-BVmmEYAoAv&password=SuQaN
@@ -43,7 +44,7 @@ https://jbrowse.org/code/jb2/main/index.html?config=https://unpkg.com/jbrowse-pl
43
44
  - Aligns and builds trees in the browser, so a UniRef launch needs no job at any
44
45
  external service; EBI's aligners remain an option
45
46
  - Every launch is also a session-spec URL (`orthologParams`, `searchParams`,
46
- `connectedTranscript`), see [DEVELOPERS.md](DEVELOPERS.md)
47
+ `connectedTranscript`), see [launching](docs/launching.md)
47
48
 
48
49
  ## File format supports
49
50
 
@@ -54,30 +55,43 @@ https://jbrowse.org/code/jb2/main/index.html?config=https://unpkg.com/jbrowse-pl
54
55
  - Clustal files (e.g. .aln file, uses clustal-js parser)
55
56
  - Newick (tree can be loaded separately as a .nh file)
56
57
 
57
- ## Publication
58
+ ## Availability
58
59
 
59
- If you find this tool useful please cite our work
60
+ This plugin is installed by default on https://genomes.jbrowse.org so you can
61
+ use it on any species there
60
62
 
61
- Diesh, C., Stevens, G., Bridge, C., Hogue, G., Buels, R., Cain, S., Stein, L., &
62
- Holmes, I. (2026). Proteins in the Genome Browser: Integration of Phylogenies,
63
- Alignments, and Structures With Nucleotide-level Evidence in JBrowse 2. Journal
64
- of Molecular Biology, 169645. https://doi.org/10.1016/j.jmb.2026.169645
63
+ ## Documentation
65
64
 
66
- See also https://github.com/GMOD/proteinbrowser for overview
65
+ Using the plugin:
67
66
 
68
- ## Availability
67
+ - [Alignments from a gene](docs/alignments-from-a-gene.md): the launch dialog's
68
+ sources — NCBI, PANTHER and UniRef orthologs, EBI searches — and aligning in
69
+ the browser.
70
+ - [Your own alignments](docs/your-own-alignments.md): opening an alignment you
71
+ made, from a file, a link, or a per-gene dataset a site configures.
72
+ - [BLAST](docs/blast.md): why searches run at EBI rather than NCBI, and the
73
+ manual route to NCBI's `nr`.
69
74
 
70
- This plugin is installed by default on https://genomes.jbrowse.org so you can
71
- use it on any species there
75
+ Linking and embedding:
76
+
77
+ - [Launching from a URL or code](docs/launching.md): worked session-spec links,
78
+ the genome connection, highlights, opening on a residue, and placement.
79
+ - [Launch parameters](docs/launch-parameters.md): every argument and field.
80
+ - [Linked views](docs/linked-views.md): how a column reaches its codon and a
81
+ protein3d structure.
72
82
 
73
- ## Programmatic usage
83
+ Working on the plugin:
74
84
 
75
- See [DEVELOPERS.md](DEVELOPERS.md)
85
+ - [DEVELOPERS.md](DEVELOPERS.md): running it locally, the checks, the README
86
+ figure and publishing.
76
87
 
77
- ## Publishing
88
+ ## Publication
78
89
 
79
- just push a new tag using e.g.
90
+ If you find this tool useful please cite our work
80
91
 
81
- ```
82
- pnpm version minor
83
- ```
92
+ Diesh, C., Stevens, G., Bridge, C., Hogue, G., Buels, R., Cain, S., Stein, L., &
93
+ Holmes, I. (2026). Proteins in the Genome Browser: Integration of Phylogenies,
94
+ Alignments, and Structures With Nucleotide-level Evidence in JBrowse 2. Journal
95
+ of Molecular Biology, 169645. https://doi.org/10.1016/j.jmb.2026.169645
96
+
97
+ See also https://github.com/GMOD/proteinbrowser for overview
@@ -6,6 +6,9 @@ export interface ContextMenuInfo {
6
6
  featureId: string;
7
7
  type?: string;
8
8
  };
9
+ subfeature?: {
10
+ featureId: string;
11
+ };
9
12
  displayedRegionIndex: number;
10
13
  }
11
14
  export interface DisplayModel {
@@ -38,6 +38,7 @@ export function launchTarget(self) {
38
38
  return isGeneLikeType(info.item.type)
39
39
  ? {
40
40
  fetchFeature: () => fetchFullFeature(info.item.featureId, info.displayedRegionIndex),
41
+ preferredTranscriptId: info.subfeature?.featureId,
41
42
  }
42
43
  : undefined;
43
44
  }
@@ -108,6 +108,19 @@ describe('launchTarget', () => {
108
108
  // the choice is ever stated
109
109
  expect(target?.preferredTranscriptId).toBe(mrna.id());
110
110
  });
111
+ // the canvas host names the clicked isoform beside the gene it fetches, as
112
+ // its own Collapse introns dialog reads it
113
+ test('carries the isoform a canvas click landed on', () => {
114
+ const host = modernHost('gene');
115
+ const target = launchTarget({
116
+ ...host,
117
+ contextMenuInfo: {
118
+ ...host.contextMenuInfo,
119
+ subfeature: { featureId: 'mrna-2' },
120
+ },
121
+ });
122
+ expect(target?.preferredTranscriptId).toBe('mrna-2');
123
+ });
111
124
  // a host that has both shapes must not fall through to the legacy branch and
112
125
  // launch on a stale feature when the click was not on a gene
113
126
  test('a non-gene click on a host carrying both shapes offers nothing', () => {
@@ -1,7 +1,30 @@
1
+ import { expandSpec } from 'react-msaview';
1
2
  import { launchMsaView } from '../utils/launchMsaView';
3
+ /**
4
+ * `msa` and `tree` onto the plugin's own sources, so a url still goes through
5
+ * `init.msaUrl` and its format sniffing, and `query` onto `querySeqName`
6
+ */
7
+ function withLongSources({ msa, tree, ...args }) {
8
+ const inlineMsa = msa?.includes('\n') ? msa : undefined;
9
+ const inlineTree = tree?.trimStart().startsWith('(') ? tree : undefined;
10
+ const data = inlineMsa || inlineTree
11
+ ? {
12
+ ...args.data,
13
+ ...(inlineMsa ? { msa: inlineMsa } : {}),
14
+ ...(inlineTree ? { tree: inlineTree } : {}),
15
+ }
16
+ : args.data;
17
+ return {
18
+ ...args,
19
+ data: data,
20
+ ...(msa && !inlineMsa ? { msaFileLocation: { uri: msa } } : {}),
21
+ ...(tree && !inlineTree ? { treeFileLocation: { uri: tree } } : {}),
22
+ querySeqName: args.querySeqName ?? args.query,
23
+ };
24
+ }
2
25
  export default function LaunchMsaViewExtensionPointF(pluginManager) {
3
26
  pluginManager.addToExtensionPoint('LaunchView-MsaView', (args) => {
4
- const { session, data, msaFileLocation, msaIndexedLocation, msaName, treeFileLocation, querySeqName, searchParams, ...rest } = args;
27
+ const { session, query, data, msaFileLocation, msaIndexedLocation, msaName, treeFileLocation, querySeqName, searchParams, ...rest } = withLongSources(args);
5
28
  // `orthologParams` and `searchParams` name no alignment at all — the
6
29
  // view builds one at launch, which is the dialog's Orthologs and BLAST
7
30
  // tabs reached declaratively.
@@ -27,7 +50,7 @@ export default function LaunchMsaViewExtensionPointF(pluginManager) {
27
50
  querySeqName,
28
51
  };
29
52
  launchMsaView(session, {
30
- ...rest,
53
+ ...expandSpec({ ...rest, query }),
31
54
  ...(searchParams ? { blastParams: searchParams } : {}),
32
55
  data,
33
56
  ...(treeFileLocation
@@ -77,3 +77,48 @@ test('one field set is enough to need init', () => {
77
77
  querySeqName: 'QUERY',
78
78
  });
79
79
  });
80
+ test('msa and tree urls reach the plugin sources, query the query row', () => {
81
+ const snapshot = launch({
82
+ msa: 'https://example.com/p53.afa',
83
+ tree: 'https://example.com/p53.nh',
84
+ query: 'Human',
85
+ });
86
+ expect(snapshot.init).toMatchObject({
87
+ msaUrl: 'https://example.com/p53.afa',
88
+ querySeqName: 'Human',
89
+ });
90
+ expect(snapshot.treeFilehandle).toEqual({
91
+ uri: 'https://example.com/p53.nh',
92
+ locationType: 'UriLocation',
93
+ });
94
+ expect(snapshot.relativeTo).toBe('Human');
95
+ expect('msa' in snapshot || 'query' in snapshot).toBe(false);
96
+ });
97
+ test('inline msa and newick text become inline data', () => {
98
+ const snapshot = launch({ msa: '>a\nMEEP\n>b\nMEEP', tree: '(a,b);' });
99
+ expect(snapshot.data).toEqual({ msa: '>a\nMEEP\n>b\nMEEP', tree: '(a,b);' });
100
+ expect('init' in snapshot).toBe(false);
101
+ });
102
+ test('highlights, region and column tracks expand onto the query row', () => {
103
+ const snapshot = launch({
104
+ msa: 'https://example.com/p53.afa',
105
+ query: 'Human',
106
+ highlights: ['102-292 DNA-binding', 175],
107
+ region: '170-290',
108
+ columnTracks: [{ name: 'ClinVar', start: 3, values: [2, 1] }],
109
+ });
110
+ expect(snapshot.highlights).toEqual([
111
+ { row: 'Human', start: 102, end: 292, label: 'DNA-binding' },
112
+ { row: 'Human', start: 175, end: 175, label: '{residue}{position}' },
113
+ ]);
114
+ expect(snapshot.region).toEqual({ row: 'Human', start: 170, end: 290 });
115
+ expect(snapshot.columnTracks).toEqual([
116
+ {
117
+ id: 'clinvar',
118
+ name: 'ClinVar',
119
+ kind: 'bar',
120
+ row: 'Human',
121
+ values: [0, 0, 2, 1],
122
+ },
123
+ ]);
124
+ });
@@ -7,7 +7,6 @@ import type { TranscriptRef } from './util';
7
7
  import type { MenuItem } from '@jbrowse/core/ui';
8
8
  import type { Instance } from '@jbrowse/mobx-state-tree';
9
9
  import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
10
- import type { Region } from 'react-msaview';
11
10
  type LGV = LinearGenomeViewModel;
12
11
  type MaybeLGV = LGV | undefined;
13
12
  export interface IRegion {
@@ -112,7 +111,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
112
111
  id: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
113
112
  displayName: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
114
113
  minimized: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
115
- }, "id" | "type" | "autoTreeAreaWidth" | "drawLabels" | "drawNodeBubbles" | "drawNodeLabels" | "drawTree" | "labelsAlignRight" | "overviewHeight" | "showBranchLen" | "showTreeOverview" | "treeAreaWidth" | "treeWidth" | "bgColor" | "colorSchemeName" | "msaFormat" | "showColumnStats" | "allowedGappyness" | "clades" | "colWidth" | "collapsed" | "columnTracks" | "currentAlignment" | "data" | "drawMsaLetters" | "encodings" | "gffFilehandle" | "height" | "hideGaps" | "highlightColumns" | "highlights" | "msaFilehandle" | "relativeTo" | "residueMappings" | "rowHeight" | "rowPanels" | "scrollX" | "scrollY" | "scrollZoom" | "scrollZoomAxis" | "showDomainLegend" | "showDomains" | "showOnly" | "subFeatureRows" | "trackHeights" | "treeFilehandle" | "treeMetadataFilehandle" | "turnedOffFeatures" | "turnedOffTracks"> & Omit<Omit<Omit<{}, "autoTreeAreaWidth" | "drawLabels" | "drawNodeBubbles" | "drawNodeLabels" | "drawTree" | "labelsAlignRight" | "overviewHeight" | "showBranchLen" | "showTreeOverview" | "treeAreaWidth" | "treeWidth"> & {
114
+ }, "id" | "type" | "autoTreeAreaWidth" | "drawLabels" | "drawNodeBubbles" | "drawNodeLabels" | "drawTree" | "labelsAlignRight" | "overviewHeight" | "showBranchLen" | "showTreeOverview" | "treeAreaWidth" | "treeWidth" | "bgColor" | "colorSchemeName" | "msaFormat" | "showColumnStats" | "allowedGappyness" | "clades" | "colWidth" | "collapsed" | "columnTracks" | "currentAlignment" | "data" | "drawMsaLetters" | "encodings" | "gffFilehandle" | "height" | "hideGaps" | "highlightColumns" | "highlights" | "msaFilehandle" | "region" | "relativeTo" | "residueMappings" | "rowHeight" | "rowPanels" | "scrollX" | "scrollY" | "scrollZoom" | "scrollZoomAxis" | "showDomainLegend" | "showDomains" | "showOnly" | "subFeatureRows" | "trackHeights" | "treeFilehandle" | "treeMetadataFilehandle" | "turnedOffFeatures" | "turnedOffTracks"> & Omit<Omit<Omit<{}, "autoTreeAreaWidth" | "drawLabels" | "drawNodeBubbles" | "drawNodeLabels" | "drawTree" | "labelsAlignRight" | "overviewHeight" | "showBranchLen" | "showTreeOverview" | "treeAreaWidth" | "treeWidth"> & {
116
115
  drawLabels: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
117
116
  labelsAlignRight: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
118
117
  treeAreaWidth: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<number>, [undefined]>;
@@ -129,7 +128,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
129
128
  colorSchemeName: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
130
129
  showColumnStats: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
131
130
  msaFormat: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<import("msa-parsers").MSAFormat>>;
132
- }, "id" | "type" | "allowedGappyness" | "clades" | "colWidth" | "collapsed" | "columnTracks" | "currentAlignment" | "data" | "drawMsaLetters" | "encodings" | "gffFilehandle" | "height" | "hideGaps" | "highlightColumns" | "highlights" | "msaFilehandle" | "relativeTo" | "residueMappings" | "rowHeight" | "rowPanels" | "scrollX" | "scrollY" | "scrollZoom" | "scrollZoomAxis" | "showDomainLegend" | "showDomains" | "showOnly" | "subFeatureRows" | "trackHeights" | "treeFilehandle" | "treeMetadataFilehandle" | "turnedOffFeatures" | "turnedOffTracks"> & {
131
+ }, "id" | "type" | "allowedGappyness" | "clades" | "colWidth" | "collapsed" | "columnTracks" | "currentAlignment" | "data" | "drawMsaLetters" | "encodings" | "gffFilehandle" | "height" | "hideGaps" | "highlightColumns" | "highlights" | "msaFilehandle" | "region" | "relativeTo" | "residueMappings" | "rowHeight" | "rowPanels" | "scrollX" | "scrollY" | "scrollZoom" | "scrollZoomAxis" | "showDomainLegend" | "showDomains" | "showOnly" | "subFeatureRows" | "trackHeights" | "treeFilehandle" | "treeMetadataFilehandle" | "turnedOffFeatures" | "turnedOffTracks"> & {
133
132
  id: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
134
133
  showDomains: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
135
134
  showDomainLegend: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
@@ -545,10 +544,11 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
545
544
  relativeTo: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
546
545
  highlightColumns: import("@jbrowse/mobx-state-tree").IType<number[] | undefined, number[] | undefined, number[] | undefined>;
547
546
  highlights: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("react-msaview").Highlight, import("react-msaview").Highlight, import("react-msaview").Highlight>>, [undefined]>;
547
+ region: import("@jbrowse/mobx-state-tree").IType<import("react-msaview").Region | undefined, import("react-msaview").Region | undefined, import("react-msaview").Region | undefined>;
548
548
  clades: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("react-msaview").Clade, import("react-msaview").Clade, import("react-msaview").Clade>>, [undefined]>;
549
549
  encodings: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("react-msaview").Encoding, import("react-msaview").Encoding, import("react-msaview").Encoding>>, [undefined]>;
550
550
  rowPanels: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("react-msaview").RowPanelSpec, import("react-msaview").RowPanelSpec, import("react-msaview").RowPanelSpec>>, [undefined]>;
551
- }, "init" | "querySeqName" | "querySeqOffset" | "zoomToBaseLevel" | "launchCompleted" | "connectedViewId" | "connectedFeature" | "connectedTranscript" | "blastParams" | "orthologParams" | "uniprotId" | "dataStoreId" | "mafRegion" | "region"> & {
551
+ }, "init" | "querySeqName" | "querySeqOffset" | "zoomToBaseLevel" | "launchCompleted" | "connectedViewId" | "connectedFeature" | "connectedTranscript" | "blastParams" | "orthologParams" | "uniprotId" | "dataStoreId" | "mafRegion"> & {
552
552
  connectedViewId: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
553
553
  connectedFeature: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
554
554
  connectedTranscript: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
@@ -562,7 +562,6 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
562
562
  dataStoreId: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
563
563
  launchCompleted: import("@jbrowse/mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
564
564
  mafRegion: import("@jbrowse/mobx-state-tree").IType<MafRegion | undefined, MafRegion | undefined, MafRegion | undefined>;
565
- region: import("@jbrowse/mobx-state-tree").IType<Region | undefined, Region | undefined, Region | undefined>;
566
565
  }, {
567
566
  width: number;
568
567
  bodyMounted: boolean;
@@ -646,6 +645,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
646
645
  setHostCarriesData(arg: boolean): void;
647
646
  setMousePos(col?: number, row?: number): void;
648
647
  setHighlightedColumns(columns?: number[]): void;
648
+ setRegion(region?: import("react-msaview").Region): void;
649
649
  setHighlights(highlights: import("react-msaview").Highlight[]): void;
650
650
  setClades(clades: import("react-msaview").Clade[]): void;
651
651
  applyHighlight(owner: string, highlights: import("react-msaview").Highlight[]): void;
@@ -798,7 +798,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
798
798
  visibleColToGlobalCol(visibleCol: number): number;
799
799
  seqPosToGlobalCol(rowName: string, seqPos: number): number | undefined;
800
800
  seqPosToVisibleCol(rowName: string, seqPos: number): number | undefined;
801
- visibleSpan({ row, start: rawStart, end: rawEnd }: Region): {
801
+ visibleSpan({ row, start: rawStart, end: rawEnd }: import("react-msaview").Region): {
802
802
  startCol: number;
803
803
  endCol: number;
804
804
  } | undefined;
@@ -897,6 +897,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
897
897
  start: number;
898
898
  end: number;
899
899
  }[];
900
+ fillHighlightLabel(label: string, row?: string, start?: number): string;
900
901
  readonly resolvedHighlights: import("react-msaview").ResolvedHighlight[];
901
902
  columnStatsAt(col: number): import("react-msaview").ColumnStats | undefined;
902
903
  getRowData(name: string): {
@@ -923,7 +924,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
923
924
  setFilter(accession: string, shown: boolean): void;
924
925
  fit(): void;
925
926
  fitVertically(): void;
926
- zoomToRegion(region: Region): void;
927
+ zoomToRegion(region: import("react-msaview").Region): void;
927
928
  fitHorizontally(): void;
928
929
  afterCreate(): void;
929
930
  } & {
@@ -1015,10 +1016,6 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
1015
1016
  * #action
1016
1017
  */
1017
1018
  setQuerySeqName(arg: string): void;
1018
- /**
1019
- * #action
1020
- */
1021
- setQuerySeqOffset(arg: number): void;
1022
1019
  /**
1023
1020
  * #action
1024
1021
  */
@@ -1031,14 +1028,6 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
1031
1028
  * #action
1032
1029
  */
1033
1030
  setLaunchCompleted(arg: boolean): void;
1034
- /**
1035
- * #action
1036
- */
1037
- setMafRegion(arg?: MafRegion): void;
1038
- /**
1039
- * #action
1040
- */
1041
- setRegion(arg?: Region): void;
1042
1031
  /**
1043
1032
  * #action
1044
1033
  */
@@ -1233,6 +1222,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
1233
1222
  relativeTo: string | undefined;
1234
1223
  highlightColumns: number[] | undefined;
1235
1224
  highlights: import("react-msaview").Highlight[];
1225
+ region: import("react-msaview").Region | undefined;
1236
1226
  clades: import("react-msaview").Clade[];
1237
1227
  encodings: import("react-msaview").Encoding[];
1238
1228
  rowPanels: import("react-msaview").RowPanelSpec[];
@@ -1364,6 +1354,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
1364
1354
  relativeTo: string | undefined;
1365
1355
  highlightColumns: number[] | undefined;
1366
1356
  highlights: import("react-msaview").Highlight[];
1357
+ region: import("react-msaview").Region | undefined;
1367
1358
  clades: import("react-msaview").Clade[];
1368
1359
  encodings: import("react-msaview").Encoding[];
1369
1360
  rowPanels: import("react-msaview").RowPanelSpec[];
@@ -5,7 +5,6 @@ import { genomeToTranscriptSeqMapping } from 'g2p_mapper';
5
5
  import { autorun } from 'mobx';
6
6
  import { MSAModelF } from 'react-msaview';
7
7
  import { autoLoadProteinDomains, launchBlastIfNeeded, launchOrthologsIfNeeded, loadStoredData, observeProteinHighlights, processInit, runCleanup, storeDataToIndexedDB, syncGenomeHoverToMsaColumn, } from './afterCreateAutoruns';
8
- import { applyRegion } from './applyRegion';
9
8
  import { msaCoordToGenomeCoord, msaCoordToGenomeRegions, } from './msaCoordToGenomeCoord';
10
9
  import { deleteMsaData } from './msaDataStore';
11
10
  import { resolveConnectedTranscriptIfNeeded } from './resolveConnectedTranscript';
@@ -108,13 +107,6 @@ export default function stateModelFactory() {
108
107
  * #property
109
108
  */
110
109
  mafRegion: types.frozen(),
111
- /**
112
- * #property
113
- * where the view opens: 1-based residues of `row`, or alignment
114
- * columns without one. Zoomed onto once and then cleared, so a
115
- * reloaded session keeps the reader's own scroll.
116
- */
117
- region: types.frozen(),
118
110
  }))
119
111
  .volatile(() => ({
120
112
  /**
@@ -277,12 +269,6 @@ export default function stateModelFactory() {
277
269
  setQuerySeqName(arg) {
278
270
  self.querySeqName = arg;
279
271
  },
280
- /**
281
- * #action
282
- */
283
- setQuerySeqOffset(arg) {
284
- self.querySeqOffset = arg;
285
- },
286
272
  /**
287
273
  * #action
288
274
  */
@@ -301,18 +287,6 @@ export default function stateModelFactory() {
301
287
  setLaunchCompleted(arg) {
302
288
  self.launchCompleted = arg;
303
289
  },
304
- /**
305
- * #action
306
- */
307
- setMafRegion(arg) {
308
- self.mafRegion = arg;
309
- },
310
- /**
311
- * #action
312
- */
313
- setRegion(arg) {
314
- self.region = arg;
315
- },
316
290
  /**
317
291
  * #action
318
292
  */
@@ -507,9 +481,6 @@ export default function stateModelFactory() {
507
481
  // so they're factories returning the autorun body rather than plain fns
508
482
  addDisposer(self, autorun(syncGenomeHoverToMsaColumn(self)));
509
483
  addDisposer(self, autorun(observeProteinHighlights(self)));
510
- addDisposer(self, autorun(() => {
511
- applyRegion(self);
512
- }));
513
484
  },
514
485
  }));
515
486
  }