UNPKG

@jbrowse/plugin-wiggle

Version:

JBrowse 2 wiggle adapters, tracks, etc.

146 lines (145 loc) 9.87 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const ui_1 = require("@jbrowse/core/ui"); const util_1 = require("@jbrowse/core/util"); const tracks_1 = require("@jbrowse/core/util/tracks"); const material_1 = require("@mui/material"); const copy_to_clipboard_1 = __importDefault(require("copy-to-clipboard")); const file_saver_1 = require("file-saver"); const mobx_react_1 = require("mobx-react"); const mobx_state_tree_1 = require("mobx-state-tree"); const mui_1 = require("tss-react/mui"); const useStyles = (0, mui_1.makeStyles)()(theme => ({ textAreaFont: { fontFamily: 'Courier New', }, mgap: { display: 'flex', flexDirection: 'column', gap: theme.spacing(4), }, })); const WiggleClusterDialogManuals = (0, mobx_react_1.observer)(function ({ model, handleClose, children, }) { const { classes } = useStyles(); const [paste, setPaste] = (0, react_1.useState)(''); const [ret, setRet] = (0, react_1.useState)(); const [error, setError] = (0, react_1.useState)(); const [loading, setLoading] = (0, react_1.useState)(false); const [showAdvanced, setShowAdvanced] = (0, util_1.useLocalStorage)('cluster-showAdvanced', false); const [clusterMethod, setClusterMethod] = (0, react_1.useState)('single'); const [samplesPerPixel, setSamplesPerPixel] = (0, react_1.useState)('1'); (0, react_1.useEffect)(() => { ; (async () => { try { setError(undefined); setRet(undefined); setLoading(true); const view = (0, util_1.getContainingView)(model); const { dynamicBlocks, bpPerPx } = view; const { rpcManager } = (0, util_1.getSession)(model); const { sourcesWithoutLayout, adapterConfig } = model; const sessionId = (0, tracks_1.getRpcSessionId)(model); const ret = (await rpcManager.call(sessionId, 'MultiWiggleGetScoreMatrix', { regions: dynamicBlocks.contentBlocks, sources: sourcesWithoutLayout, sessionId, adapterConfig, bpPerPx: bpPerPx / +samplesPerPixel, })); setRet(ret); } catch (e) { if (!(0, util_1.isAbortException)(e) && (0, mobx_state_tree_1.isAlive)(model)) { console.error(e); setError(e); } } finally { setLoading(false); } })(); }, [model, samplesPerPixel]); const results = ret ? `inputMatrix<-matrix(c(${Object.values(ret) .map(val => val.join(',')) .join(',\n')} ),nrow=${Object.values(ret).length},byrow=TRUE) rownames(inputMatrix)<-c(${Object.keys(ret) .map(key => `'${key}'`) .join(',')}) resultClusters<-hclust(dist(inputMatrix), method='${clusterMethod}') cat(resultClusters$order,sep='\\n')` : undefined; const resultsTsv = ret ? Object.entries(ret) .map(([key, val]) => [key, ...val].join('\t')) .join('\n') : undefined; return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(material_1.DialogContent, { children: [children, (0, jsx_runtime_1.jsxs)("div", { style: { marginTop: 50 }, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: '8px', flexWrap: 'wrap', marginBottom: '16px', }, children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => { (0, file_saver_1.saveAs)(new Blob([results || ''], { type: 'text/plain;charset=utf-8', }), 'cluster.R'); }, children: "Download Rscript" }), ' ', "or", ' ', (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => { (0, copy_to_clipboard_1.default)(results || ''); }, children: "Copy Rscript to clipboard" }), ' ', "or", ' ', (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => { (0, file_saver_1.saveAs)(new Blob([resultsTsv || ''], { type: 'text/plain;charset=utf-8', }), 'scores.tsv'); }, children: "Download TSV" })] }), (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => { setShowAdvanced(!showAdvanced); }, children: showAdvanced ? 'Hide advanced options' : 'Show advanced options' }) }), showAdvanced ? ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", children: "Advanced options" }), (0, jsx_runtime_1.jsx)(material_1.RadioGroup, { children: Object.entries({ single: 'Single', complete: 'Complete', }).map(([key, val]) => ((0, jsx_runtime_1.jsx)(material_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(material_1.Radio, { checked: clusterMethod === key, onChange: () => { setClusterMethod(key); } }), label: val }, key))) }), (0, jsx_runtime_1.jsxs)("div", { style: { marginTop: 20 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { children: "This procedure samples the data at each 'pixel' across the visible by default" }), (0, jsx_runtime_1.jsx)(material_1.TextField, { label: "Samples per pixel (>1 for denser sampling, between 0-1 for sparser sampling)", variant: "outlined", size: "small", value: samplesPerPixel, onChange: event => { setSamplesPerPixel(event.target.value); } })] })] })) : null, results ? ((0, jsx_runtime_1.jsx)("div", {})) : loading ? ((0, jsx_runtime_1.jsx)(ui_1.LoadingEllipses, { variant: "h6", title: "Generating score matrix" })) : error ? ((0, jsx_runtime_1.jsx)(ui_1.ErrorMessage, { error: error })) : null] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", gutterBottom: true, style: { marginTop: '16px' }, children: "Clustering Results:" }), (0, jsx_runtime_1.jsx)(material_1.TextField, { multiline: true, fullWidth: true, variant: "outlined", placeholder: "Paste results from Rscript here (sequence of numbers, one per line, specifying the new ordering)", rows: 10, value: paste, onChange: event => { setPaste(event.target.value); }, slotProps: { input: { classes: { input: classes.textAreaFont, }, }, } })] })] })] }), (0, jsx_runtime_1.jsxs)(material_1.DialogActions, { children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => { const { sourcesWithoutLayout } = model; if (sourcesWithoutLayout) { try { model.setLayout(paste .split('\n') .map(t => t.trim()) .filter(f => !!f) .map(r => +r) .map(idx => { const ret = sourcesWithoutLayout[idx - 1]; if (!ret) { throw new Error(`out of bounds at ${idx}`); } return ret; })); } catch (e) { console.error(e); (0, util_1.getSession)(model).notifyError(`${e}`, e); } } handleClose(); }, children: "Apply clustering" }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", color: "secondary", onClick: () => { handleClose(); }, children: "Cancel" })] })] })); }); exports.default = WiggleClusterDialogManuals;