jbrowse-plugin-msaview 2.7.3 → 2.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.
Files changed (31) hide show
  1. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js +7 -1
  2. package/dist/LaunchMsaView/components/OrthologQuery/OrthologPanel.d.ts +8 -0
  3. package/dist/LaunchMsaView/components/OrthologQuery/OrthologPanel.js +89 -0
  4. package/dist/LaunchMsaView/components/OrthologQuery/orthologLaunchView.d.ts +9 -0
  5. package/dist/LaunchMsaView/components/OrthologQuery/orthologLaunchView.js +13 -0
  6. package/dist/LaunchMsaView/components/TranscriptSelector.js +7 -1
  7. package/dist/MsaViewPanel/afterCreateAutoruns.d.ts +8 -0
  8. package/dist/MsaViewPanel/afterCreateAutoruns.js +28 -0
  9. package/dist/MsaViewPanel/doLaunchOrthologs.d.ts +23 -0
  10. package/dist/MsaViewPanel/doLaunchOrthologs.js +97 -0
  11. package/dist/MsaViewPanel/model.d.ts +21 -5
  12. package/dist/MsaViewPanel/model.js +12 -1
  13. package/dist/jbrowse-plugin-msaview.umd.production.min.js +31 -27
  14. package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
  15. package/dist/utils/ncbiOrthologs.d.ts +135 -0
  16. package/dist/utils/ncbiOrthologs.js +241 -0
  17. package/dist/utils/ncbiOrthologs.test.d.ts +1 -0
  18. package/dist/utils/ncbiOrthologs.test.js +41 -0
  19. package/dist/version.d.ts +1 -1
  20. package/dist/version.js +1 -1
  21. package/package.json +3 -3
  22. package/src/LaunchMsaView/components/LaunchMsaViewDialog.tsx +13 -2
  23. package/src/LaunchMsaView/components/OrthologQuery/OrthologPanel.tsx +172 -0
  24. package/src/LaunchMsaView/components/OrthologQuery/orthologLaunchView.ts +28 -0
  25. package/src/LaunchMsaView/components/TranscriptSelector.tsx +6 -0
  26. package/src/MsaViewPanel/afterCreateAutoruns.ts +27 -0
  27. package/src/MsaViewPanel/doLaunchOrthologs.ts +123 -0
  28. package/src/MsaViewPanel/model.ts +24 -0
  29. package/src/utils/ncbiOrthologs.test.ts +56 -0
  30. package/src/utils/ncbiOrthologs.ts +350 -0
  31. package/src/version.ts +1 -1
@@ -4,6 +4,7 @@ import { getSession } from '@jbrowse/core/util';
4
4
  import { Tab, Tabs } from '@mui/material';
5
5
  import ManualMSALoader from './ManualMSALoader/ManualMSALoader';
6
6
  import NCBIBlastPanel from './NCBIBlastQuery/NCBIBlastPanel';
7
+ import OrthologPanel from './OrthologQuery/OrthologPanel';
7
8
  import PreLoadedMSA from './PreLoadedMSA/PreLoadedMSADataPanel';
8
9
  import { readMsaDatasets } from './PreLoadedMSA/types';
9
10
  import TabPanel from './TabPanel';
@@ -11,14 +12,19 @@ export default function LaunchMsaViewDialog({ handleClose, feature, model, }) {
11
12
  const session = getSession(model);
12
13
  const datasets = readMsaDatasets(session.jbrowse);
13
14
  const hasPreloadedDatasets = !!datasets?.length;
14
- const [value, setValue] = useState('ncbi_blast');
15
+ // orthologs first, and the default: it answers the same question in ~10s
16
+ // that BLAST takes 10+ minutes to answer worse (see utils/ncbiOrthologs.ts)
17
+ const [value, setValue] = useState('orthologs');
15
18
  return (React.createElement(Dialog, { maxWidth: "xl", title: "Launch MSA view", open: true, onClose: handleClose },
16
19
  React.createElement(Tabs, { value: value, onChange: (_event, newValue) => {
17
20
  setValue(newValue);
18
21
  } },
22
+ React.createElement(Tab, { label: "Orthologs (fast)", value: "orthologs" }),
19
23
  React.createElement(Tab, { label: "NCBI BLAST query", value: "ncbi_blast" }),
20
24
  hasPreloadedDatasets ? (React.createElement(Tab, { label: "Pre-loaded MSA datasets", value: "preloaded_msa" })) : null,
21
25
  React.createElement(Tab, { label: "Manual upload", value: "manual_msa" })),
26
+ React.createElement(TabPanel, { value: value, index: "orthologs" },
27
+ React.createElement(OrthologPanel, { handleClose: handleClose, feature: feature, model: model })),
22
28
  React.createElement(TabPanel, { value: value, index: "ncbi_blast" },
23
29
  React.createElement(NCBIBlastPanel, { handleClose: handleClose, feature: feature, model: model })),
24
30
  hasPreloadedDatasets ? (React.createElement(TabPanel, { value: value, index: "preloaded_msa" },
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import type { AbstractTrackModel, Feature } from '@jbrowse/core/util';
3
+ declare const OrthologPanel: ({ handleClose, feature, model, }: {
4
+ model: AbstractTrackModel;
5
+ feature: Feature;
6
+ handleClose: () => void;
7
+ }) => React.JSX.Element;
8
+ export default OrthologPanel;
@@ -0,0 +1,89 @@
1
+ import React, { useMemo, useState } from 'react';
2
+ import { Checkbox, FormControlLabel, MenuItem, Typography } from '@mui/material';
3
+ import { observer } from 'mobx-react';
4
+ import { makeStyles } from 'tss-react/mui';
5
+ import { orthologLaunchView } from './orthologLaunchView';
6
+ import TextField2 from '../../../components/TextField2';
7
+ import { COMMON_SPECIES } from '../../../utils/ncbiOrthologs';
8
+ import { getGeneDisplayName, getGeneIdentifiers, getLinearGenomeView, getTranscriptDisplayName, } from '../../util';
9
+ import LaunchPanelContent from '../LaunchPanelContent';
10
+ import MsaAlgorithmSelect from '../NCBIBlastQuery/MsaAlgorithmSelect';
11
+ import SubmitCancelActions from '../SubmitCancelActions';
12
+ import TranscriptSelector from '../TranscriptSelector';
13
+ import { useTranscriptSelection } from '../useTranscriptSelection';
14
+ const useStyles = makeStyles()({
15
+ selectField: {
16
+ width: 180,
17
+ },
18
+ // A GRID, not a wrapping flex row of fixed-width items. The old form was three
19
+ // 160px columns inside a 560px box, which is five rows for thirteen species and
20
+ // eight for twenty-three -- and the checkbox list is the tallest thing in the
21
+ // dialog, so those rows are the dialog's height. Five auto-fitted columns is
22
+ // five rows for twenty-three, i.e. more species in less space, and it reflows
23
+ // rather than being pinned to a width the dialog may not have.
24
+ speciesBox: {
25
+ display: 'grid',
26
+ gridTemplateColumns: 'repeat(auto-fit, minmax(130px, 1fr))',
27
+ maxWidth: 700,
28
+ marginTop: 4,
29
+ },
30
+ // The label carries the row height; the default control padding is what makes
31
+ // 23 rows of it tall.
32
+ species: {
33
+ marginRight: 0,
34
+ },
35
+ });
36
+ const OrthologPanel = observer(function ({ handleClose, feature, model, }) {
37
+ const { classes } = useStyles();
38
+ const view = getLinearGenomeView(model);
39
+ const [launchViewError, setLaunchViewError] = useState();
40
+ const [taxId, setTaxId] = useState(9606);
41
+ const [msaAlgorithm, setMsaAlgorithm] = useState('clustalo');
42
+ const [excluded, setExcluded] = useState([]);
43
+ const geneCandidates = useMemo(() => getGeneIdentifiers(feature), [feature]);
44
+ const transcriptSelection = useTranscriptSelection({ feature, view });
45
+ const { selectedTranscript, proteinSequence } = transcriptSelection;
46
+ const e = transcriptSelection.error ?? launchViewError;
47
+ const taxa = COMMON_SPECIES.map(s => s.taxId).filter(t => !excluded.includes(t));
48
+ return (React.createElement(React.Fragment, null,
49
+ React.createElement(LaunchPanelContent, { error: e },
50
+ React.createElement(Typography, { variant: "body2" }, "NCBI's precomputed orthologs, one gene per species, aligned at EBI in seconds rather than the 10+ minutes BLAST takes."),
51
+ React.createElement("div", null,
52
+ React.createElement(TextField2, { variant: "outlined", label: "Query species", className: classes.selectField, select: true, value: taxId, onChange: event => {
53
+ setTaxId(Number(event.target.value));
54
+ }, helperText: "the species this gene is from" }, COMMON_SPECIES.map(s => (React.createElement(MenuItem, { value: s.taxId, key: s.taxId }, s.label)))),
55
+ React.createElement(MsaAlgorithmSelect, { className: classes.selectField, value: msaAlgorithm, onChange: setMsaAlgorithm })),
56
+ React.createElement(Typography, { variant: "subtitle2", style: { marginTop: 8 } }, "Species to include (those without an ortholog are skipped)"),
57
+ React.createElement("div", { className: classes.speciesBox }, COMMON_SPECIES.map(s => (React.createElement(FormControlLabel, { className: classes.species, key: s.taxId, control: React.createElement(Checkbox, { checked: !excluded.includes(s.taxId), onChange: event => {
58
+ setExcluded(event.target.checked
59
+ ? excluded.filter(t => t !== s.taxId)
60
+ : [...excluded, s.taxId]);
61
+ } }), label: s.label })))),
62
+ React.createElement(TranscriptSelector, { feature: feature, ...transcriptSelection })),
63
+ React.createElement(SubmitCancelActions, { submitDisabled: !proteinSequence || taxa.length < 2, onSubmit: () => {
64
+ try {
65
+ if (selectedTranscript) {
66
+ setLaunchViewError(undefined);
67
+ orthologLaunchView({
68
+ feature: selectedTranscript,
69
+ view,
70
+ newViewTitle: `Orthologs - ${getGeneDisplayName(feature)} - ${getTranscriptDisplayName(selectedTranscript)}`,
71
+ orthologParams: {
72
+ taxId,
73
+ taxa,
74
+ geneCandidates,
75
+ msaAlgorithm,
76
+ selectedTranscript,
77
+ proteinSequence,
78
+ },
79
+ });
80
+ handleClose();
81
+ }
82
+ }
83
+ catch (e) {
84
+ console.error(e);
85
+ setLaunchViewError(e);
86
+ }
87
+ }, onCancel: handleClose })));
88
+ });
89
+ export default OrthologPanel;
@@ -0,0 +1,9 @@
1
+ import type { OrthologParams } from '../../../MsaViewPanel/model';
2
+ import type { Feature } from '@jbrowse/core/util';
3
+ import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
4
+ export declare function orthologLaunchView({ newViewTitle, view, feature, orthologParams, }: {
5
+ newViewTitle: string;
6
+ view: LinearGenomeViewModel;
7
+ feature: Feature;
8
+ orthologParams: OrthologParams;
9
+ }): void;
@@ -0,0 +1,13 @@
1
+ import { getSession } from '@jbrowse/core/util';
2
+ export function orthologLaunchView({ newViewTitle, view, feature, orthologParams, }) {
3
+ getSession(view).addView('MsaView', {
4
+ type: 'MsaView',
5
+ displayName: newViewTitle,
6
+ connectedViewId: view.id,
7
+ connectedFeature: feature.toJSON(),
8
+ drawNodeBubbles: true,
9
+ colWidth: 10,
10
+ rowHeight: 12,
11
+ orthologParams,
12
+ });
13
+ }
@@ -20,7 +20,13 @@ export default function TranscriptSelector({ feature, options, selectedId, selec
20
20
  const [showSequence, setShowSequence] = useState(false);
21
21
  return (React.createElement(React.Fragment, null,
22
22
  React.createElement("div", { className: classes.flex },
23
- React.createElement(TextField, { variant: "outlined", label: `Choose isoform of ${getGeneDisplayName(feature)}`, select: true, className: classes.minWidth, value: selectedId, onChange: event => {
23
+ React.createElement(TextField, { variant: "outlined", label: `Choose isoform of ${getGeneDisplayName(feature)}`,
24
+ // The query row is this transcript rather than NCBI's representative
25
+ // protein, which is what keeps the alignment linked to the genome view
26
+ // at codon resolution. It used to be a paragraph under the panel; as
27
+ // helper text it says the same thing where the choice is made and
28
+ // costs no height of its own.
29
+ helperText: "the query row, so the alignment stays linked to the genome view", select: true, className: classes.minWidth, value: selectedId, onChange: event => {
24
30
  setSelectedId(event.target.value);
25
31
  } }, options.map(val => {
26
32
  const inSet = validIds
@@ -1,6 +1,14 @@
1
1
  import type { JBrowsePluginMsaViewModel } from './model';
2
2
  export declare function loadStoredData(self: JBrowsePluginMsaViewModel): void;
3
3
  export declare function storeDataToIndexedDB(self: JBrowsePluginMsaViewModel): void;
4
+ /**
5
+ * Same shape as launchBlastIfNeeded, for the ortholog path: the params ARE the
6
+ * request, and clearing them on success is what marks it done. They are left in
7
+ * place on failure so the error stays attributable to a specific request; the
8
+ * autorun's only tracked read is orthologParams itself, so nothing refires
9
+ * until a new request replaces them.
10
+ */
11
+ export declare function launchOrthologsIfNeeded(self: JBrowsePluginMsaViewModel): void;
4
12
  export declare function launchBlastIfNeeded(self: JBrowsePluginMsaViewModel): void;
5
13
  /**
6
14
  * Once an accession-bearing alignment is present (fresh from BLAST or restored
@@ -1,5 +1,6 @@
1
1
  import { getSession } from '@jbrowse/core/util';
2
2
  import { doLaunchBlast } from './doLaunchBlast';
3
+ import { doLaunchOrthologs } from './doLaunchOrthologs';
3
4
  import { fetchIndexedMsa } from './fetchIndexedMsa';
4
5
  import { genomeToMSA } from './genomeToMSA';
5
6
  import { loadProteinDomains } from './loadProteinDomains';
@@ -69,6 +70,33 @@ export function storeDataToIndexedDB(self) {
69
70
  }
70
71
  }
71
72
  }
73
+ /**
74
+ * Same shape as launchBlastIfNeeded, for the ortholog path: the params ARE the
75
+ * request, and clearing them on success is what marks it done. They are left in
76
+ * place on failure so the error stays attributable to a specific request; the
77
+ * autorun's only tracked read is orthologParams itself, so nothing refires
78
+ * until a new request replaces them.
79
+ */
80
+ export function launchOrthologsIfNeeded(self) {
81
+ if (self.orthologParams) {
82
+ void (async () => {
83
+ try {
84
+ self.setProgress('Resolving orthologs');
85
+ self.setError(undefined);
86
+ const data = await doLaunchOrthologs({ self });
87
+ self.setData(data);
88
+ self.setOrthologParams(undefined);
89
+ }
90
+ catch (e) {
91
+ self.setError(e);
92
+ console.error(e);
93
+ }
94
+ finally {
95
+ self.setProgress('');
96
+ }
97
+ })();
98
+ }
99
+ }
72
100
  export function launchBlastIfNeeded(self) {
73
101
  if (self.blastParams) {
74
102
  void (async () => {
@@ -0,0 +1,23 @@
1
+ import type { JBrowsePluginMsaViewModel } from './model';
2
+ /**
3
+ * The no-search-job alternative to doLaunchBlast.
4
+ *
5
+ * BLAST spends 10+ minutes answering "what looks like this sequence" and
6
+ * returns a redundant, accession-labelled hit list. This asks NCBI the question
7
+ * the alignment actually wants — "what is this gene's ortholog in each species"
8
+ * — which NCBI has already computed, so the whole NCBI half returns in about a
9
+ * second and only the EBI alignment (~10s) costs real time.
10
+ *
11
+ * The query row is the user's OWN selected transcript, not NCBI's
12
+ * representative protein for the query species, because `connectedFeature`
13
+ * maps genome coordinates through that row — swapping in a different isoform
14
+ * would silently break the genome<->MSA linkage. The query species is therefore
15
+ * excluded from the ortholog set rather than appearing twice.
16
+ */
17
+ export declare function doLaunchOrthologs({ self, }: {
18
+ self: JBrowsePluginMsaViewModel;
19
+ }): Promise<{
20
+ treeMetadata: string;
21
+ msa: string;
22
+ tree: string;
23
+ }>;
@@ -0,0 +1,97 @@
1
+ import { cleanProteinSequence } from '../LaunchMsaView/util';
2
+ import { launchMSA } from '../utils/msa';
3
+ import { fetchOrthologRows, fetchProteinForGene, resolveGeneId, } from '../utils/ncbiOrthologs';
4
+ /**
5
+ * The no-search-job alternative to doLaunchBlast.
6
+ *
7
+ * BLAST spends 10+ minutes answering "what looks like this sequence" and
8
+ * returns a redundant, accession-labelled hit list. This asks NCBI the question
9
+ * the alignment actually wants — "what is this gene's ortholog in each species"
10
+ * — which NCBI has already computed, so the whole NCBI half returns in about a
11
+ * second and only the EBI alignment (~10s) costs real time.
12
+ *
13
+ * The query row is the user's OWN selected transcript, not NCBI's
14
+ * representative protein for the query species, because `connectedFeature`
15
+ * maps genome coordinates through that row — swapping in a different isoform
16
+ * would silently break the genome<->MSA linkage. The query species is therefore
17
+ * excluded from the ortholog set rather than appearing twice.
18
+ */
19
+ export async function doLaunchOrthologs({ self, }) {
20
+ const { taxId, taxa, geneCandidates, msaAlgorithm, proteinSequence } = self.orthologParams;
21
+ const cleanedSeq = cleanProteinSequence(proteinSequence);
22
+ const onProgress = (arg) => {
23
+ self.setProgress(arg);
24
+ };
25
+ onProgress('Resolving gene at NCBI...');
26
+ const resolved = await resolveGeneId(geneCandidates, taxId);
27
+ if (!resolved) {
28
+ throw new Error(`Could not resolve any of ${geneCandidates.join(', ')} to an NCBI gene in taxon ${taxId}. Try the NCBI BLAST tab, which needs no gene identifier.`);
29
+ }
30
+ // the query species is represented by the user's own transcript below
31
+ const wanted = new Set(taxa.filter(t => t !== taxId));
32
+ const rows = await fetchOrthologRows({
33
+ geneId: resolved.geneId,
34
+ taxa: wanted,
35
+ onProgress,
36
+ });
37
+ const treeMetadata = {
38
+ QUERY: await buildQueryMetadata(self, resolved.geneId, cleanedSeq),
39
+ };
40
+ for (const row of rows) {
41
+ treeMetadata[row.label] = buildRowMetadata(row);
42
+ }
43
+ const result = await launchMSA({
44
+ algorithm: msaAlgorithm,
45
+ sequence: [
46
+ `>QUERY\n${cleanedSeq}`,
47
+ ...rows.map(r => `>${r.label}\n${r.sequence}`),
48
+ ].join('\n'),
49
+ onProgress,
50
+ });
51
+ return {
52
+ ...result,
53
+ treeMetadata: JSON.stringify(treeMetadata),
54
+ };
55
+ }
56
+ /**
57
+ * The query row is the user's own translated transcript, so it carries an
58
+ * Accession — which is what drives the automatic CDD overlay
59
+ * (afterCreateAutoruns.autoLoadProteinDomains -> loadProteinDomains) — ONLY
60
+ * when its sequence is byte-identical to the RefSeq protein that accession
61
+ * names. Attaching it unconditionally would put every domain box at an offset
62
+ * whenever the user picked a non-representative isoform, which is a silently
63
+ * wrong figure rather than a missing one.
64
+ */
65
+ async function buildQueryMetadata(self, geneId, proteinSequence) {
66
+ const transcript = self.orthologParams?.selectedTranscript;
67
+ const metadata = { 'Gene ID': geneId };
68
+ const name = transcript?.get('name') ?? transcript?.get('id');
69
+ if (name) {
70
+ metadata.Transcript = name;
71
+ }
72
+ try {
73
+ const representative = await fetchProteinForGene(geneId);
74
+ if (representative?.sequence === proteinSequence) {
75
+ metadata.Accession = representative.accession;
76
+ }
77
+ }
78
+ catch (e) {
79
+ // a failed lookup only costs the query row its domain overlay, so it must
80
+ // not take down an alignment that is otherwise complete
81
+ console.warn('[msaview-orthologs] query protein lookup failed:', e);
82
+ }
83
+ return metadata;
84
+ }
85
+ function buildRowMetadata(row) {
86
+ const metadata = {
87
+ 'Scientific name': row.scientificName,
88
+ // Accession drives the automatic CDD domain overlay
89
+ // (afterCreateAutoruns.autoLoadProteinDomains -> loadProteinDomains)
90
+ Accession: row.protein,
91
+ 'Gene ID': row.geneId,
92
+ };
93
+ if (row.commonName) {
94
+ metadata['Common name'] = row.commonName;
95
+ }
96
+ return metadata;
97
+ }
@@ -20,6 +20,17 @@ export interface BlastParams {
20
20
  proteinSequence: string;
21
21
  rid?: string;
22
22
  }
23
+ export interface OrthologParams {
24
+ /** NCBI taxon id of the assembly the query gene came from */
25
+ taxId: number;
26
+ /** taxon ids to include as rows (the query taxon is represented by QUERY) */
27
+ taxa: number[];
28
+ /** candidate gene identifiers off the feature, tried in order */
29
+ geneCandidates: string[];
30
+ msaAlgorithm: MsaAlgorithm;
31
+ selectedTranscript?: Feature;
32
+ proteinSequence: string;
33
+ }
23
34
  /**
24
35
  * #stateModel MsaViewPlugin
25
36
  * extends
@@ -42,7 +53,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
42
53
  bgColor: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
43
54
  colorSchemeName: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
44
55
  showColumnStats: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
45
- msaFormat: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<import("react-msaview").MSAFormat>>;
56
+ msaFormat: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<import("msa-parsers").MSAFormat>>;
46
57
  }, "height" | "id" | "type" | "allowedGappyness" | "colWidth" | "collapsed" | "currentAlignment" | "data" | "drawMsaLetters" | "featureFilters" | "gffFilehandle" | "hideGaps" | "highlightColumns" | "msaFilehandle" | "relativeTo" | "rowHeight" | "scrollX" | "scrollY" | "scrollZoom" | "showDomains" | "showOnly" | "subFeatureRows" | "treeFilehandle" | "treeMetadataFilehandle" | "turnedOffTracks"> & {
47
58
  id: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
48
59
  showDomains: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
@@ -456,10 +467,11 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
456
467
  featureFilters: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IMapType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>>, [undefined]>;
457
468
  relativeTo: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
458
469
  highlightColumns: import("@jbrowse/mobx-state-tree").IType<number[] | undefined, number[] | undefined, number[] | undefined>;
459
- }, "init" | "querySeqName" | "zoomToBaseLevel" | "connectedViewId" | "connectedFeature" | "blastParams" | "uniprotId" | "dataStoreId" | "mafRegion"> & {
470
+ }, "init" | "querySeqName" | "zoomToBaseLevel" | "connectedViewId" | "connectedFeature" | "blastParams" | "orthologParams" | "uniprotId" | "dataStoreId" | "mafRegion"> & {
460
471
  connectedViewId: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
461
472
  connectedFeature: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
462
473
  blastParams: import("@jbrowse/mobx-state-tree").IType<BlastParams | undefined, BlastParams | undefined, BlastParams | undefined>;
474
+ orthologParams: import("@jbrowse/mobx-state-tree").IType<OrthologParams | undefined, OrthologParams | undefined, OrthologParams | undefined>;
463
475
  querySeqName: import("@jbrowse/mobx-state-tree").IType<string | undefined, string, string>;
464
476
  uniprotId: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
465
477
  zoomToBaseLevel: import("@jbrowse/mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
@@ -495,7 +507,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
495
507
  setColorSchemeName(name: string): void;
496
508
  setBgColor(arg: boolean): void;
497
509
  setShowColumnStats(arg: boolean): void;
498
- setMSAFormat(arg?: import("react-msaview").MSAFormat): void;
510
+ setMSAFormat(arg?: import("msa-parsers").MSAFormat): void;
499
511
  } & {
500
512
  headerHeight: number;
501
513
  status: {
@@ -582,7 +594,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
582
594
  readonly noDomains: boolean;
583
595
  menuItems(): never[];
584
596
  readonly treeMetadata: Record<string, Record<string, string> | undefined>;
585
- readonly MSA: import("react-msaview").MSAParserType | null;
597
+ readonly MSA: import("msa-parsers").MSAParserType | null;
586
598
  readonly numColumns: number;
587
599
  readonly tree: import("react-msaview").NodeWithIds;
588
600
  readonly rowNames: string[];
@@ -879,6 +891,10 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
879
891
  * #action
880
892
  */
881
893
  setBlastParams(args?: BlastParams): void;
894
+ /**
895
+ * #action
896
+ */
897
+ setOrthologParams(args?: OrthologParams): void;
882
898
  /**
883
899
  * #action
884
900
  */
@@ -940,7 +956,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
940
956
  bgColor: boolean;
941
957
  colorSchemeName: string;
942
958
  showColumnStats: boolean;
943
- msaFormat: import("react-msaview").MSAFormat | undefined;
959
+ msaFormat: import("msa-parsers").MSAFormat | undefined;
944
960
  drawLabels: boolean;
945
961
  labelsAlignRight: boolean;
946
962
  treeAreaWidth: number;
@@ -4,7 +4,7 @@ import { addDisposer, types } from '@jbrowse/mobx-state-tree';
4
4
  import { genomeToTranscriptSeqMapping } from 'g2p_mapper';
5
5
  import { autorun } from 'mobx';
6
6
  import { MSAModelF } from 'react-msaview';
7
- import { autoLoadProteinDomains, launchBlastIfNeeded, loadStoredData, observeProteinHighlights, processInit, runCleanup, storeDataToIndexedDB, syncGenomeHoverToMsaColumn, } from './afterCreateAutoruns';
7
+ import { autoLoadProteinDomains, launchBlastIfNeeded, launchOrthologsIfNeeded, loadStoredData, observeProteinHighlights, processInit, runCleanup, storeDataToIndexedDB, syncGenomeHoverToMsaColumn, } from './afterCreateAutoruns';
8
8
  import { msaCoordToGenomeCoord, msaCoordToGenomeRegions, } from './msaCoordToGenomeCoord';
9
9
  /**
10
10
  * #stateModel MsaViewPlugin
@@ -26,6 +26,10 @@ export default function stateModelFactory() {
26
26
  * #property
27
27
  */
28
28
  blastParams: types.frozen(),
29
+ /**
30
+ * #property
31
+ */
32
+ orthologParams: types.frozen(),
29
33
  /**
30
34
  * #property
31
35
  */
@@ -183,6 +187,12 @@ export default function stateModelFactory() {
183
187
  setBlastParams(args) {
184
188
  self.blastParams = args;
185
189
  },
190
+ /**
191
+ * #action
192
+ */
193
+ setOrthologParams(args) {
194
+ self.orthologParams = args;
195
+ },
186
196
  /**
187
197
  * #action
188
198
  */
@@ -289,6 +299,7 @@ export default function stateModelFactory() {
289
299
  loadStoredData,
290
300
  storeDataToIndexedDB,
291
301
  launchBlastIfNeeded,
302
+ launchOrthologsIfNeeded,
292
303
  processInit,
293
304
  autoLoadProteinDomains,
294
305
  ]) {