UNPKG

pdbe-molstar-3dbionotes

Version:
433 lines 26.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.renderSuperposition = exports.initSuperposition = void 0; var tslib_1 = require("tslib"); var linear_algebra_1 = require("Molstar/mol-math/linear-algebra"); var builder_1 = require("Molstar/mol-script/language/builder"); var transforms_1 = require("Molstar/mol-plugin-state/transforms"); var assets_1 = require("Molstar/mol-util/assets"); var helpers_1 = require("./helpers"); var lists_1 = require("Molstar/mol-util/color/lists"); var color_1 = require("Molstar/mol-util/color/color"); function getRandomColor(plugin, segmentIndex) { var clList = lists_1.ColorLists; var spState = plugin.customState.superpositionState; var palleteIndex = spState.colorState[segmentIndex].palleteIndex; var colorIndex = spState.colorState[segmentIndex].colorIndex; if (clList[spState.colorPalette[palleteIndex]].list[colorIndex + 1]) { colorIndex += 1; } else { colorIndex = 0; palleteIndex = spState.colorPalette[palleteIndex + 1] ? palleteIndex + 1 : 0; } var palleteName = spState.colorPalette[palleteIndex]; plugin.customState.superpositionState.colorState[segmentIndex].palleteIndex = palleteIndex; plugin.customState.superpositionState.colorState[segmentIndex].colorIndex = colorIndex; return clList[palleteName].list[colorIndex]; } function initSuperposition(plugin) { return tslib_1.__awaiter(this, void 0, void 0, function () { var customState, superpositionParams, segmentData, segmentIndex, clusterIndexs, entryList, clusters; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, plugin.clear()]; case 1: _a.sent(); customState = plugin.customState; superpositionParams = customState.initParams.superpositionParams; plugin.customState.superpositionState = { models: {}, entries: {}, refMaps: {}, segmentData: void 0, matrixData: {}, activeSegment: 0, loadedStructs: [], visibleRefs: [], invalidStruct: [], noMatrixStruct: [], hets: {}, colorPalette: ['dark-2', 'red-yellow-green', 'paired', 'set-1', 'accent', 'set-2', 'rainbow'], colorState: [] }; // Get segment and cluster information for the given uniprot accession return [4 /*yield*/, getSegmentData(plugin)]; case 2: // Get segment and cluster information for the given uniprot accession _a.sent(); segmentData = plugin.customState.superpositionState.segmentData; if (!segmentData) return [2 /*return*/]; // Load Matrix Data return [4 /*yield*/, getMatrixData(plugin)]; case 3: // Load Matrix Data _a.sent(); if (!plugin.customState.superpositionState.segmentData) return [2 /*return*/]; segmentData.forEach(function () { plugin.customState.superpositionState.loadedStructs.push([]); plugin.customState.superpositionState.visibleRefs.push([]); plugin.customState.superpositionState.colorState.push({ palleteIndex: 0, colorIndex: -1 }); }); segmentIndex = (superpositionParams && superpositionParams.segment) ? superpositionParams.segment - 1 : 0; plugin.customState.superpositionState.activeSegment = segmentIndex + 1; clusterIndexs = (superpositionParams && superpositionParams.cluster) ? superpositionParams.cluster : void 0; // Emit segment API data load event plugin.customState.events.superpositionInit.next(true); entryList = []; clusters = segmentData[segmentIndex].clusters; clusters.forEach(function (cluster, clusterIndex) { // Validate for cluster index if provided in superPositionParams if (clusterIndexs && clusterIndexs.indexOf(clusterIndex) === -1) return; // Add respresentative structure to the list if (superpositionParams && superpositionParams.superposeAll) { entryList = entryList.concat(cluster); } else { entryList.push(cluster[0]); } }); return [4 /*yield*/, renderSuperposition(plugin, segmentIndex, entryList)]; case 4: _a.sent(); return [2 /*return*/]; } }); }); } exports.initSuperposition = initSuperposition; function renderSuperposition(plugin, segmentIndex, entryList) { return tslib_1.__awaiter(this, void 0, void 0, function () { var customState, superpositionParams, busyFlagOn; var _this = this; return tslib_1.__generator(this, function (_a) { customState = plugin.customState; superpositionParams = customState.initParams.superpositionParams; busyFlagOn = false; if (entryList.length > 1) { busyFlagOn = true; customState.events.isBusy.next(true); } // Load Coordinates and render respresentations return [2 /*return*/, plugin.dataTransaction(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var spState, entryList_1, entryList_1_1, s, strUrl, strInstance, modelRef, clearOnFail, polymerInstance, modelInstance, isBinary, _a, model, structure, matrix, chainSel, uniformColor1, uniformColor2, invalidStruct, state, hets, interactingHets, hets_1, hets_1_1, het, ligParam, ligandQuery, labelTagParams, hetColor, _b, r, g, b, ligandExp, e_1_1, loadedStructIndex, e_2_1; var e_2, _c, e_1, _d; return tslib_1.__generator(this, function (_e) { switch (_e.label) { case 0: spState = plugin.customState.superpositionState; _e.label = 1; case 1: _e.trys.push([1, 35, 36, 41]); entryList_1 = tslib_1.__asyncValues(entryList); _e.label = 2; case 2: return [4 /*yield*/, entryList_1.next()]; case 3: if (!(entryList_1_1 = _e.sent(), !entryList_1_1.done)) return [3 /*break*/, 34]; s = entryList_1_1.value; // validate matrix availability if (!spState.matrixData[s.pdb_id + "_" + s.auth_asym_id]) { spState.noMatrixStruct.push(s.pdb_id + "_" + s.struct_asym_id); spState.invalidStruct.push(s.pdb_id + "_" + s.struct_asym_id); return [3 /*break*/, 33]; } spState.loadedStructs[segmentIndex].push(s.pdb_id + "_" + s.struct_asym_id); strUrl = customState.initParams.pdbeUrl + "model-server/v1/" + s.pdb_id + "/atoms?auth_asym_id=" + s.auth_asym_id + "&encoding=" + customState.initParams.encoding; if (superpositionParams && superpositionParams.ligandView) strUrl = "https://www.ebi.ac.uk/pdbe/entry-files/download/" + s.pdb_id + ".bcif"; strInstance = void 0; modelRef = void 0; clearOnFail = true; if (!(superpositionParams && superpositionParams.ligandView && spState.entries[s.pdb_id])) return [3 /*break*/, 5]; polymerInstance = plugin.state.data.select(spState.entries[s.pdb_id])[0]; modelRef = polymerInstance.transform.parent; modelInstance = plugin.state.data.select(modelRef)[0]; return [4 /*yield*/, plugin.builders.structure.createStructure(modelInstance, { name: 'model', params: {} })]; case 4: strInstance = _e.sent(); clearOnFail = false; return [3 /*break*/, 7]; case 5: isBinary = customState.initParams.encoding === 'bcif' ? true : false; return [4 /*yield*/, loadStructure(plugin, strUrl, 'mmcif', isBinary)]; case 6: _a = _e.sent(), model = _a.model, structure = _a.structure; strInstance = structure; modelRef = model.ref; _e.label = 7; case 7: if (!strInstance) return [3 /*break*/, 33]; // Store Refs in state if (!spState.models[s.pdb_id + "_" + s.struct_asym_id]) spState.models[s.pdb_id + "_" + s.struct_asym_id] = strInstance === null || strInstance === void 0 ? void 0 : strInstance.ref; if (superpositionParams && superpositionParams.ligandView && !spState.entries[s.pdb_id]) spState.entries[s.pdb_id] = strInstance === null || strInstance === void 0 ? void 0 : strInstance.ref; matrix = linear_algebra_1.Mat4.ofRows(plugin.customState.superpositionState.matrixData[s.pdb_id + "_" + s.auth_asym_id].matrix); return [4 /*yield*/, transform(plugin, strInstance, matrix)]; case 8: _e.sent(); chainSel = void 0; if (!((superpositionParams && superpositionParams.ligandView) && s.is_representative)) return [3 /*break*/, 12]; uniformColor1 = getRandomColor(plugin, segmentIndex); return [4 /*yield*/, plugin.builders.structure.tryCreateComponentFromExpression(strInstance, chainSelection(s.struct_asym_id), "Chain-" + segmentIndex, { label: "Chain", tags: ["superposition-sel"] })]; case 9: chainSel = _e.sent(); if (!chainSel) return [3 /*break*/, 11]; return [4 /*yield*/, plugin.builders.structure.representation.addRepresentation(chainSel, { type: 'putty', color: 'uniform', colorParams: { value: uniformColor1 }, size: 'uniform' }, { tag: "superposition-visual" })]; case 10: _e.sent(); spState.refMaps[chainSel.ref] = s.pdb_id + "_" + s.struct_asym_id; _e.label = 11; case 11: return [3 /*break*/, 16]; case 12: if (!((superpositionParams && superpositionParams.ligandView) && !s.is_representative)) return [3 /*break*/, 13]; return [3 /*break*/, 16]; case 13: uniformColor2 = getRandomColor(plugin, segmentIndex); return [4 /*yield*/, plugin.builders.structure.tryCreateComponentStatic(strInstance, 'polymer', { label: "Chain", tags: ["Chain-" + segmentIndex, "superposition-sel"] })]; case 14: chainSel = _e.sent(); if (!chainSel) return [3 /*break*/, 16]; return [4 /*yield*/, plugin.builders.structure.representation.addRepresentation(chainSel, { type: 'putty', color: 'uniform', colorParams: { value: uniformColor2 }, size: 'uniform' }, { tag: "superposition-visual" })]; case 15: _e.sent(); spState.refMaps[chainSel.ref] = s.pdb_id + "_" + s.struct_asym_id; _e.label = 16; case 16: invalidStruct = chainSel ? false : true; if (!(superpositionParams && superpositionParams.ligandView)) return [3 /*break*/, 33]; state = plugin.state.data; return [4 /*yield*/, getHetNames(state, modelRef)]; case 17: hets = _e.sent(); interactingHets = []; if (!(hets && hets.length > 0)) return [3 /*break*/, 32]; _e.label = 18; case 18: _e.trys.push([18, 26, 27, 32]); hets_1 = (e_1 = void 0, tslib_1.__asyncValues(hets)); _e.label = 19; case 19: return [4 /*yield*/, hets_1.next()]; case 20: if (!(hets_1_1 = _e.sent(), !hets_1_1.done)) return [3 /*break*/, 25]; het = hets_1_1.value; ligParam = { label_comp_id: het, auth_asym_id: s.auth_asym_id }; ligandQuery = helpers_1.LigandView.query(ligParam); labelTagParams = { label: "" + het, tags: ["superposition-ligand-sel"] }; hetColor = color_1.Color.fromRgb(253, 3, 253); if (superpositionParams && superpositionParams.ligandColor) { _b = superpositionParams.ligandColor, r = _b.r, g = _b.g, b = _b.b; hetColor = color_1.Color.fromRgb(r, g, b); } return [4 /*yield*/, plugin.builders.structure.tryCreateComponentFromExpression(strInstance, ligandQuery.core, het + "-" + segmentIndex, labelTagParams)]; case 21: ligandExp = _e.sent(); if (!ligandExp) return [3 /*break*/, 23]; return [4 /*yield*/, plugin.builders.structure.representation.addRepresentation(ligandExp, { type: 'ball-and-stick', color: 'uniform', colorParams: { value: hetColor } }, { tag: "superposition-ligand-visual" })]; case 22: _e.sent(); spState.refMaps[ligandExp.ref] = s.pdb_id + "_" + s.struct_asym_id; _e.label = 23; case 23: if (ligandExp) { invalidStruct = false; interactingHets.push(het); } _e.label = 24; case 24: return [3 /*break*/, 19]; case 25: return [3 /*break*/, 32]; case 26: e_1_1 = _e.sent(); e_1 = { error: e_1_1 }; return [3 /*break*/, 32]; case 27: _e.trys.push([27, , 30, 31]); if (!(hets_1_1 && !hets_1_1.done && (_d = hets_1.return))) return [3 /*break*/, 29]; return [4 /*yield*/, _d.call(hets_1)]; case 28: _e.sent(); _e.label = 29; case 29: return [3 /*break*/, 31]; case 30: if (e_1) throw e_1.error; return [7 /*endfinally*/]; case 31: return [7 /*endfinally*/]; case 32: if (invalidStruct) { spState.invalidStruct.push(s.pdb_id + "_" + s.struct_asym_id); loadedStructIndex = spState.loadedStructs[segmentIndex].indexOf(s.pdb_id + "_" + s.struct_asym_id); if (loadedStructIndex > -1) spState.loadedStructs[segmentIndex].splice(loadedStructIndex, 1); // remove downloaded data if (clearOnFail) { // const m = plugin.state.data.select(modelRef)[0]; // const t = plugin.state.data.select(m.transform.parent)[0]; // const d = plugin.state.data.select(t.transform.parent)[0]; // PluginCommands.State.RemoveObject(plugin, { state: d.parent!, ref: d.transform.parent, removeParentGhosts: true }); } } else { if (interactingHets.length > 0) spState.hets[s.pdb_id + "_" + s.struct_asym_id] = interactingHets; } _e.label = 33; case 33: return [3 /*break*/, 2]; case 34: return [3 /*break*/, 41]; case 35: e_2_1 = _e.sent(); e_2 = { error: e_2_1 }; return [3 /*break*/, 41]; case 36: _e.trys.push([36, , 39, 40]); if (!(entryList_1_1 && !entryList_1_1.done && (_c = entryList_1.return))) return [3 /*break*/, 38]; return [4 /*yield*/, _c.call(entryList_1)]; case 37: _e.sent(); _e.label = 38; case 38: return [3 /*break*/, 40]; case 39: if (e_2) throw e_2.error; return [7 /*endfinally*/]; case 40: return [7 /*endfinally*/]; case 41: if (busyFlagOn) { busyFlagOn = false; customState.events.isBusy.next(false); } return [2 /*return*/]; } }); }); })]; }); }); } exports.renderSuperposition = renderSuperposition; function getHetNames(state, modelRef) { return tslib_1.__awaiter(this, void 0, void 0, function () { var cell, model, info; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: cell = state.select(modelRef)[0]; if (!cell || !cell.obj) return [2 /*return*/, void 0]; model = cell.obj.data; if (!model) return [2 /*return*/]; return [4 /*yield*/, helpers_1.ModelInfo.get(model)]; case 1: info = _a.sent(); if (info && info.hetNames.length > 0) return [2 /*return*/, info.hetNames]; return [2 /*return*/, void 0]; } }); }); } function loadStructure(plugin, url, format, isBinary) { return tslib_1.__awaiter(this, void 0, void 0, function () { var data, trajectory, model, structure, e_3; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 5, , 6]); return [4 /*yield*/, plugin.builders.data.download({ url: assets_1.Asset.Url(url), isBinary: isBinary })]; case 1: data = _a.sent(); return [4 /*yield*/, plugin.builders.structure.parseTrajectory(data, format)]; case 2: trajectory = _a.sent(); return [4 /*yield*/, plugin.builders.structure.createModel(trajectory)]; case 3: model = _a.sent(); return [4 /*yield*/, plugin.builders.structure.createStructure(model, { name: 'model', params: {} })]; case 4: structure = _a.sent(); return [2 /*return*/, { data: data, trajectory: trajectory, model: model, structure: structure }]; case 5: e_3 = _a.sent(); return [2 /*return*/, { structure: void 0 }]; case 6: return [2 /*return*/]; } }); }); } function chainSelection(struct_asym_id) { return builder_1.MolScriptBuilder.struct.generator.atomGroups({ 'chain-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.struct.atomProperty.macromolecular.label_asym_id(), struct_asym_id]) }); } function transform(plugin, s, matrix) { var b = plugin.state.data.build().to(s) .insert(transforms_1.StateTransforms.Model.TransformStructureConformation, { transform: { name: 'matrix', params: { data: matrix, transpose: false } } }); return plugin.runTask(plugin.state.data.updateTree(b)); } function getMatrixData(plugin) { return tslib_1.__awaiter(this, void 0, void 0, function () { var customState, matrixAccession, clusterRecUrlStr, assetManager, clusterRecUrl, clusterRecData, e_4; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: customState = plugin.customState; matrixAccession = customState.initParams.superpositionParams.matrixAccession ? customState.initParams.superpositionParams.matrixAccession : customState.initParams.moleculeId; clusterRecUrlStr = customState.initParams.pdbeUrl + "graph-api/uniprot/superposition_matrices/" + matrixAccession; assetManager = plugin.managers.asset; clusterRecUrl = assets_1.Asset.getUrlAsset(assetManager, clusterRecUrlStr); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, plugin.runTask(assetManager.resolve(clusterRecUrl, 'json', false))]; case 2: clusterRecData = _a.sent(); if (clusterRecData && clusterRecData.data) { plugin.customState.superpositionState.matrixData = clusterRecData.data; } return [3 /*break*/, 4]; case 3: e_4 = _a.sent(); customState['superpositionError'] = "Matrix data not available for " + matrixAccession; plugin.customState.events.superpositionInit.next(true); // Emit segment API data load event return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); } function getSegmentData(plugin) { return tslib_1.__awaiter(this, void 0, void 0, function () { var customState, segmentsUrl, assetManager, url, result, e_5; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: customState = plugin.customState; segmentsUrl = customState.initParams.pdbeUrl + "graph-api/uniprot/superposition/" + customState.initParams.moleculeId; assetManager = plugin.managers.asset; url = assets_1.Asset.getUrlAsset(assetManager, segmentsUrl); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, plugin.runTask(assetManager.resolve(url, 'json', false))]; case 2: result = _a.sent(); if (result && result.data) { customState.superpositionState.segmentData = result.data[customState.initParams.moleculeId]; } return [3 /*break*/, 4]; case 3: e_5 = _a.sent(); customState['superpositionError'] = "Superposition data not available for " + customState.initParams.moleculeId; plugin.customState.events.superpositionInit.next(true); // Emit segment API data load event return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); } //# sourceMappingURL=superposition.js.map