UNPKG

pdbe-molstar

Version:
631 lines (630 loc) 38.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SuperpositionColorPalette = void 0; exports.getNextColor = getNextColor; exports.initSuperposition = initSuperposition; exports.loadAfStructure = loadAfStructure; exports.superposeAf = superposeAf; exports.renderSuperposition = renderSuperposition; exports.transform = transform; const tslib_1 = require("tslib"); const linear_algebra_1 = require("molstar/lib/mol-math/linear-algebra"); const structure_1 = require("molstar/lib/mol-model/structure"); const transforms_1 = require("molstar/lib/mol-plugin-state/transforms"); const builder_1 = require("molstar/lib/mol-script/language/builder"); const script_1 = require("molstar/lib/mol-script/script"); const mol_state_1 = require("molstar/lib/mol-state"); const assets_1 = require("molstar/lib/mol-util/assets"); const color_1 = require("molstar/lib/mol-util/color/color"); const lists_1 = require("molstar/lib/mol-util/color/lists"); const alphafold_transparency_1 = require("./alphafold-transparency"); const helpers_1 = require("./helpers"); const plugin_custom_state_1 = require("./plugin-custom-state"); const superposition_sifts_mapping_1 = require("./superposition-sifts-mapping"); function combinedColorPalette(palettes) { return palettes.flatMap(paletteName => lists_1.ColorLists[paletteName].list); } exports.SuperpositionColorPalette = combinedColorPalette(['dark-2', 'red-yellow-green', 'paired', 'set-1', 'accent', 'set-2', 'rainbow']); const DefaultLigandColor = color_1.Color.fromRgb(253, 3, 253); function getNextColor(plugin, segmentIndex) { const spState = (0, plugin_custom_state_1.PluginCustomState)(plugin).superpositionState; if (!spState) throw new Error('customState.superpositionState has not been initialized'); const nextColor = exports.SuperpositionColorPalette[spState.colorCounters[segmentIndex]]; spState.colorCounters[segmentIndex] = (spState.colorCounters[segmentIndex] + 1) % exports.SuperpositionColorPalette.length; return nextColor; } function initSuperposition(plugin, completeSubject) { return tslib_1.__awaiter(this, void 0, void 0, function* () { var _a; let success = false; try { yield plugin.clear(); const customState = (0, plugin_custom_state_1.PluginCustomState)(plugin); customState.superpositionState = { models: {}, entries: {}, refMaps: {}, segmentData: undefined, matrixData: {}, activeSegment: 0, loadedStructs: [], visibleRefs: [], invalidStruct: [], noMatrixStruct: [], hets: {}, colorCounters: [], alphafold: { apiData: { bcif: '', cif: '', pae: '', length: 0, }, length: 0, ref: '', traceOnly: true, visibility: [], transforms: [], rmsds: [], coordinateSystems: [], }, }; // Get segment and cluster information for the given uniprot accession yield getSegmentData(plugin); const segmentData = customState.superpositionState.segmentData; if (!segmentData) return; // Load Matrix Data yield getMatrixData(plugin); if (!customState.superpositionState.segmentData) return; if (!customState.initParams.moleculeId) throw new Error('initParams.moleculeId is not defined'); const afApiData = yield getAfUrls(plugin, customState.initParams.moleculeId); if (afApiData) customState.superpositionState.alphafold.apiData = afApiData; segmentData.forEach(() => { customState.superpositionState.loadedStructs.push([]); customState.superpositionState.visibleRefs.push([]); customState.superpositionState.colorCounters.push(0); }); // Set segment and cluster details from superPositionParams const superpositionParams = customState.initParams.superpositionParams; const segmentIndex = (superpositionParams === null || superpositionParams === void 0 ? void 0 : superpositionParams.segment) ? superpositionParams.segment - 1 : 0; customState.superpositionState.activeSegment = segmentIndex + 1; const clusterIndexs = (superpositionParams === null || superpositionParams === void 0 ? void 0 : superpositionParams.cluster) ? superpositionParams.cluster : undefined; // Emit segment API data load event (_a = customState.events) === null || _a === void 0 ? void 0 : _a.superpositionInit.next(true); // Get entry list to load matrix data const entryList = []; const clusters = segmentData[segmentIndex].clusters; clusters.forEach((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 === null || superpositionParams === void 0 ? void 0 : superpositionParams.superposeAll) { entryList.push(...cluster); } else { entryList.push(cluster[0]); } }); yield renderSuperposition(plugin, segmentIndex, entryList); success = true; } finally { completeSubject === null || completeSubject === void 0 ? void 0 : completeSubject.next(success); } }); } function createCarbVisLabel(carbLigNamesAndCount) { const compList = []; for (const carbCompId in carbLigNamesAndCount) { compList.push(`${carbCompId} (${carbLigNamesAndCount[carbCompId]})`); } return compList.join(', '); } function getAfUrls(plugin, accession) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const url = `https://alphafold.ebi.ac.uk/api/prediction/${accession}`; try { const apiResponse = yield plugin.runTask(plugin.fetch({ url, type: 'json' })); if (apiResponse === null || apiResponse === void 0 ? void 0 : apiResponse[0].bcifUrl) { return { bcif: apiResponse[0].bcifUrl, cif: apiResponse[0].cifUrl, pae: apiResponse[0].paeImageUrl, length: apiResponse[0].uniprotEnd, }; } } catch (_a) { // ignore, will return undefined } console.warn(`Failed to get AFDB URLs for ${accession}: ${url}`); return undefined; }); } function loadAfStructure(plugin) { return tslib_1.__awaiter(this, void 0, void 0, function* () { var _a, _b; const customState = (0, plugin_custom_state_1.PluginCustomState)(plugin); if (!customState.superpositionState) throw new Error('customState.superpositionState has not been initialized'); const isBinary = ((_a = customState.initParams) === null || _a === void 0 ? void 0 : _a.encoding) === 'bcif'; const url = isBinary ? customState.superpositionState.alphafold.apiData.bcif : customState.superpositionState.alphafold.apiData.cif; const { structure } = yield loadStructure(plugin, url, 'mmcif', isBinary); const strInstance = structure; if (!strInstance) return false; // Store Refs in state const spState = customState.superpositionState; spState.alphafold.ref = strInstance === null || strInstance === void 0 ? void 0 : strInstance.ref; if (!((_b = customState.initParams) === null || _b === void 0 ? void 0 : _b.moleculeId)) throw new Error('initParams.moleculeId is not defined'); spState.models[`AF-${customState.initParams.moleculeId}`] = strInstance === null || strInstance === void 0 ? void 0 : strInstance.ref; const chainSel = yield plugin.builders.structure.tryCreateComponentStatic(strInstance, 'polymer', { label: `AlphaFold Structure`, tags: [`alphafold-chain`, `superposition-sel`] }); if (chainSel) { yield plugin.builders.structure.representation.addRepresentation(chainSel, { type: 'putty', color: 'plddt-confidence', size: 'uniform', sizeParams: { value: 1.5 } }, { tag: `af-superposition-visual` }); return strInstance === null || strInstance === void 0 ? void 0 : strInstance.ref; } return false; }); } function superposeAf(plugin, traceOnly, segmentIndex) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const customState = (0, plugin_custom_state_1.PluginCustomState)(plugin); const spState = customState.superpositionState; if (!(spState === null || spState === void 0 ? void 0 : spState.segmentData)) return; // Load AF structure const afStrRef = spState.alphafold.ref || (yield loadAfStructure(plugin)); if (!afStrRef) return; const afStr = plugin.managers.structure.hierarchy.current.refs.get(afStrRef); const segmentNum = segmentIndex ? segmentIndex : spState.activeSegment - 1; if (!spState.alphafold.transforms[segmentNum]) { // Create representative list const mappingResult = []; const coordinateSystems = []; const failedPairsResult = []; const zeroOverlapPairsResult = []; let minRmsd = 0; let minIndex = 0; const rmsdList = []; const segmentClusters = spState.segmentData[segmentNum].clusters; segmentClusters.forEach((cluster) => { var _a, _b, _c; const modelRef = spState.models[`${cluster[0].pdb_id}_${cluster[0].struct_asym_id}`]; if (modelRef) { const structHierarchy = plugin.managers.structure.hierarchy.current.refs.get(modelRef); if (structHierarchy) { const input = [structHierarchy.components[0], afStr]; const structures = input.map(s => { var _a; return (_a = s.cell.obj) === null || _a === void 0 ? void 0 : _a.data; }); let { entries, failedPairs, zeroOverlapPairs } = (0, superposition_sifts_mapping_1.alignAndSuperposeWithSIFTSMapping)(structures, { traceOnly, includeResidueTest: loc => structure_1.StructureProperties.atom.B_iso_or_equiv(loc) > 70, applyTestIndex: [1], }); if (entries.length === 0 || (entries && entries[0] && entries[0].transform.rmsd.toFixed(1) === '0.0')) { const alignWithoutPlddt = (0, superposition_sifts_mapping_1.alignAndSuperposeWithSIFTSMapping)(structures, { traceOnly }); entries = alignWithoutPlddt.entries; } if (entries && entries[0]) { mappingResult.push(entries[0]); coordinateSystems.push((_c = (_b = (_a = input[0]) === null || _a === void 0 ? void 0 : _a.transform) === null || _b === void 0 ? void 0 : _b.cell.obj) === null || _c === void 0 ? void 0 : _c.data.coordinateSystem); const totalMappings = mappingResult.length; if (totalMappings === 1 || entries[0].transform.rmsd < minRmsd) { minRmsd = entries[0].transform.rmsd; minIndex = totalMappings === 1 ? 0 : mappingResult.length - 1; } rmsdList.push(`${cluster[0].pdb_id} chain ${cluster[0].struct_asym_id}:${entries[0].transform.rmsd.toFixed(2)}`); } else { if (failedPairs.length > 0) failedPairsResult.push(failedPairs); if (zeroOverlapPairs.length > 0) zeroOverlapPairsResult.push(zeroOverlapPairs); // rmsdList.push(`${cluster[0].pdb_id} ${cluster[0].struct_asym_id}:-`) } } } }); // console.log(failedPairsResult); // console.log(zeroOverlapPairsResult); if (mappingResult.length > 0) { spState.alphafold.visibility[segmentNum] = true; spState.alphafold.transforms[segmentNum] = mappingResult[minIndex].transform.bTransform; spState.alphafold.coordinateSystems[segmentNum] = coordinateSystems[minIndex]; spState.alphafold.rmsds[segmentNum] = rmsdList.sort((a, b) => parseFloat(a.split(':')[1]) - parseFloat(b.split(':')[1])); } } yield afTransform(plugin, afStr.cell, spState.alphafold.transforms[segmentNum], spState.alphafold.coordinateSystems[segmentNum]); (0, alphafold_transparency_1.applyAFTransparency)(plugin, afStr, 0.8, 70); return true; }); } function renderSuperposition(plugin, segmentIndex, entryList) { return tslib_1.__awaiter(this, void 0, void 0, function* () { var _a; const customState = (0, plugin_custom_state_1.PluginCustomState)(plugin); const superpositionParams = customState.initParams.superpositionParams; let busyFlagOn = false; if (entryList.length > 1) { busyFlagOn = true; (_a = customState.events) === null || _a === void 0 ? void 0 : _a.isBusy.next(true); } // Load Coordinates and render respresentations return plugin.dataTransaction(() => tslib_1.__awaiter(this, void 0, void 0, function* () { var _a, e_1, _b, _c; var _d; if (!customState.initParams) throw new Error('customState.initParams has not been initialized'); if (!customState.superpositionState) throw new Error('customState.superpositionState has not been initialized'); const spState = customState.superpositionState; for (const s of entryList) { // 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}`); continue; } spState.loadedStructs[segmentIndex].push(`${s.pdb_id}_${s.struct_asym_id}`); // Set Coordinate server url const request = (superpositionParams && superpositionParams.ligandView) ? { pdbId: s.pdb_id, queryType: 'full' } : { pdbId: s.pdb_id, queryType: 'atoms', queryParams: { auth_asym_id: s.auth_asym_id } }; const strUrl = (0, helpers_1.getStructureUrl)(customState.initParams, request); // Load Data let strInstance; let modelRef; let clearOnFail = true; if (superpositionParams && superpositionParams.ligandView && spState.entries[s.pdb_id]) { const polymerInstance = plugin.state.data.select(spState.entries[s.pdb_id])[0]; modelRef = polymerInstance.transform.parent; const modelInstance = plugin.state.data.select(modelRef)[0]; strInstance = yield plugin.builders.structure.createStructure(modelInstance, { name: 'model', params: {} }); clearOnFail = false; } else { const isBinary = customState.initParams.encoding === 'bcif' ? true : false; const { model, structure } = yield loadStructure(plugin, strUrl, 'mmcif', isBinary); strInstance = structure; modelRef = model.ref; } if (!strInstance) continue; // 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; // Apply tranform matrix const matrix = linear_algebra_1.Mat4.ofRows(customState.superpositionState.matrixData[`${s.pdb_id}_${s.auth_asym_id}`].matrix); yield transform(plugin, strInstance, matrix); // Create representations let chainSel; if ((superpositionParams && superpositionParams.ligandView) && s.is_representative) { const uniformColor1 = getNextColor(plugin, segmentIndex); // random color chainSel = yield plugin.builders.structure.tryCreateComponentFromExpression(strInstance, chainSelection(s.struct_asym_id), `Chain-${segmentIndex}`, { label: `Chain`, tags: [`superposition-sel`] }); if (chainSel) { yield plugin.builders.structure.representation.addRepresentation(chainSel, { type: 'putty', color: 'uniform', colorParams: { value: uniformColor1 }, size: 'uniform' }, { tag: `superposition-visual` }); spState.refMaps[chainSel.ref] = `${s.pdb_id}_${s.struct_asym_id}`; } } else if ((superpositionParams && superpositionParams.ligandView) && !s.is_representative) { // Do nothing } else { const uniformColor2 = getNextColor(plugin, segmentIndex); // random color chainSel = yield plugin.builders.structure.tryCreateComponentStatic(strInstance, 'polymer', { label: `Chain`, tags: [`Chain-${segmentIndex}`, `superposition-sel`] }); if (chainSel) { yield plugin.builders.structure.representation.addRepresentation(chainSel, { type: 'putty', color: 'uniform', colorParams: { value: uniformColor2 }, size: 'uniform' }, { tag: `superposition-visual` }); spState.refMaps[chainSel.ref] = `${s.pdb_id}_${s.struct_asym_id}`; } // // const addTooltipUpdate = plugin.state.behaviors.build().to(BestDatabaseSequenceMapping.id).update(BestDatabaseSequenceMapping, (old: any) => { old.showTooltip = true; }); // // await plugin.runTask(plugin.state.behaviors.updateTree(addTooltipUpdate)); // BestDatabaseSequenceMapping // console.log(plugin.state.data.select(modelRef)[0]) } let invalidStruct = chainSel ? false : true; if (superpositionParams && superpositionParams.ligandView) { const state = plugin.state.data; const hetInfo = yield getLigandNamesFromModelData(plugin, state, modelRef); const hets = hetInfo ? hetInfo.hetNames : []; // const interactingHets = []; if (hets && hets.length > 0) { try { for (var _e = true, hets_1 = (e_1 = void 0, tslib_1.__asyncValues(hets)), hets_1_1; hets_1_1 = yield hets_1.next(), _a = hets_1_1.done, !_a; _e = true) { _c = hets_1_1.value; _e = false; const het = _c; const ligand = builder_1.MolScriptBuilder.struct.generator.atomGroups({ 'chain-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.struct.atomProperty.macromolecular.auth_asym_id(), s.auth_asym_id]), 'residue-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.struct.atomProperty.macromolecular.label_comp_id(), het]), 'group-by': builder_1.MolScriptBuilder.core.str.concat([builder_1.MolScriptBuilder.struct.atomProperty.core.operatorName(), builder_1.MolScriptBuilder.struct.atomProperty.macromolecular.residueKey()]), }); const labelTagParams = { label: `${het}`, tags: [`superposition-ligand-sel`] }; const hetColor = (0, helpers_1.normalizeColor)(superpositionParams.ligandColor, DefaultLigandColor); const ligandExp = yield plugin.builders.structure.tryCreateComponentFromExpression(strInstance, ligand, `${het}-${segmentIndex}`, labelTagParams); if (ligandExp) { yield plugin.builders.structure.representation.addRepresentation(ligandExp, { type: 'ball-and-stick', color: 'uniform', colorParams: { value: hetColor } }, { tag: `superposition-ligand-visual` }); spState.refMaps[ligandExp.ref] = `${s.pdb_id}_${s.struct_asym_id}`; invalidStruct = false; // interactingHets.push(het); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (!_e && !_a && (_b = hets_1.return)) yield _b.call(hets_1); } finally { if (e_1) throw e_1.error; } } } const carbEntityCount = hetInfo ? hetInfo.carbEntityCount : 0; if (carbEntityCount > 0) { // Get Carbohydrate Polymers details from PDBe API const allCarbPolymers = yield getCarbPolymerDetailsFromApi(plugin, s.pdb_id); // Polymer chain + surroundings query const polymerChainWithSurroundings = builder_1.MolScriptBuilder.struct.modifier.includeSurroundings({ 0: builder_1.MolScriptBuilder.struct.generator.atomGroups({ 'entity-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.ammp('entityType'), 'polymer']), 'chain-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.struct.atomProperty.macromolecular.auth_asym_id(), s.auth_asym_id]), 'group-by': builder_1.MolScriptBuilder.core.str.concat([builder_1.MolScriptBuilder.struct.atomProperty.core.operatorName(), builder_1.MolScriptBuilder.struct.atomProperty.macromolecular.residueKey()]), }), radius: 5, 'as-whole-residues': true, }); let i = 0; for (const carbEntityChainId of allCarbPolymers.branchedChains) { const carbEntityChain = builder_1.MolScriptBuilder.struct.generator.atomGroups({ 'entity-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.ammp('entityType'), 'branched']), 'chain-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.struct.atomProperty.macromolecular.auth_asym_id(), carbEntityChainId]), 'group-by': builder_1.MolScriptBuilder.core.str.concat([builder_1.MolScriptBuilder.struct.atomProperty.core.operatorName(), builder_1.MolScriptBuilder.struct.atomProperty.macromolecular.residueKey()]), }); const carbEntityChainInVicinity = builder_1.MolScriptBuilder.struct.filter.intersectedBy({ 0: polymerChainWithSurroundings, by: carbEntityChain, }); const data = (plugin.state.data.select(strInstance.ref)[0].obj).data; const carbChainSel = script_1.Script.getStructureSelection(carbEntityChainInVicinity, data); if (carbChainSel && carbChainSel.kind === 'sequence') { // console.log(carbEntityChainId + ' chain present in 5 A radius'); const carbLigands = []; const carbLigNamesAndCount = {}; const carbLigList = []; for (const carbLigs of allCarbPolymers.branchedLigands[i]) { const ligResDetails = carbLigs.split('-'); carbLigands.push(builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.struct.atomProperty.macromolecular.auth_seq_id(), +ligResDetails[1]])); if (carbLigNamesAndCount[ligResDetails[0]]) { carbLigNamesAndCount[ligResDetails[0]]++; } else { carbLigNamesAndCount[ligResDetails[0]] = 1; } carbLigList.push(ligResDetails[0]); } const carbVisLabel = createCarbVisLabel(carbLigNamesAndCount); const branchedEntity = builder_1.MolScriptBuilder.struct.generator.atomGroups({ 'entity-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.ammp('entityType'), 'branched']), 'group-by': builder_1.MolScriptBuilder.core.str.concat([builder_1.MolScriptBuilder.struct.atomProperty.core.operatorName(), builder_1.MolScriptBuilder.struct.atomProperty.macromolecular.residueKey()]), 'chain-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.struct.atomProperty.macromolecular.auth_asym_id(), carbEntityChainId]), 'residue-test': builder_1.MolScriptBuilder.core.logic.or(carbLigands), }); const labelTagParams = { label: `${carbVisLabel}`, tags: [`superposition-carb-sel`] }; const ligandExp = yield plugin.builders.structure.tryCreateComponentFromExpression(strInstance, branchedEntity, `${carbLigList.join('-')}-${segmentIndex}`, labelTagParams); if (ligandExp) { yield plugin.builders.structure.representation.addRepresentation(ligandExp, { type: 'carbohydrate' }, { tag: `superposition-carb-visual` }); spState.refMaps[ligandExp.ref] = `${s.pdb_id}_${s.struct_asym_id}`; invalidStruct = false; } } i++; } } if (invalidStruct) { spState.invalidStruct.push(`${s.pdb_id}_${s.struct_asym_id}`); const 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; } } } if (busyFlagOn) { busyFlagOn = false; (_d = customState.events) === null || _d === void 0 ? void 0 : _d.isBusy.next(false); } })); }); } function getLigandNamesFromModelData(plugin, state, modelRef) { return tslib_1.__awaiter(this, void 0, void 0, function* () { var _a; const cell = state.select(modelRef)[0]; if (!cell || !cell.obj) return undefined; const model = cell.obj.data; if (!model) return; const structures = []; for (const s of plugin.managers.structure.hierarchy.selection.structures) { const structure = (_a = s.cell.obj) === null || _a === void 0 ? void 0 : _a.data; if (structure) structures.push(structure); } const info = yield helpers_1.ModelInfo.get(model, structures); return info; }); } function loadStructure(plugin, url, format, isBinary) { return tslib_1.__awaiter(this, void 0, void 0, function* () { try { const data = yield plugin.builders.data.download({ url: assets_1.Asset.Url(url), isBinary: isBinary }); const trajectory = yield plugin.builders.structure.parseTrajectory(data, format); const model = yield plugin.builders.structure.createModel(trajectory); const modelProperties = yield plugin.builders.structure.insertModelProperties(model); const structure = yield plugin.builders.structure.createStructure(modelProperties || model, { name: 'model', params: {} }); yield plugin.builders.structure.insertStructureProperties(structure); return { data, trajectory, model, structure }; } catch (e) { return { structure: undefined }; } }); } 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]), }); } /** Apply tranformation to a structure. Only use once per structure, combining multiple transformations is not implemented. */ function transform(plugin, s, matrix) { const 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 afTransform(plugin, s, matrix, coordinateSystem) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const r = mol_state_1.StateObjectRef.resolveAndCheck(plugin.state.data, s); if (!r) return; const o = plugin.state.data.selectQ(q => q.byRef(r.transform.ref).subtree().withTransformer(transforms_1.StateTransforms.Model.TransformStructureConformation))[0]; const transform = coordinateSystem && !linear_algebra_1.Mat4.isIdentity(coordinateSystem.matrix) ? linear_algebra_1.Mat4.mul((0, linear_algebra_1.Mat4)(), coordinateSystem.matrix, matrix) : matrix; const params = { transform: { name: 'matrix', params: { data: transform, transpose: false }, }, }; const b = o ? plugin.state.data.build().to(o).update(params) : plugin.state.data.build().to(s) .insert(transforms_1.StateTransforms.Model.TransformStructureConformation, params, { tags: 'SuperpositionTransform' }); yield plugin.runTask(plugin.state.data.updateTree(b)); }); } function getMatrixData(plugin) { return tslib_1.__awaiter(this, void 0, void 0, function* () { var _a, _b, _c; const customState = (0, plugin_custom_state_1.PluginCustomState)(plugin); if (!customState.initParams) throw new Error('customState.initParams has not been initialized'); if (!customState.superpositionState) throw new Error('customState.superpositionState has not been initialized'); const matrixAccession = (_b = (_a = customState.initParams.superpositionParams) === null || _a === void 0 ? void 0 : _a.matrixAccession) !== null && _b !== void 0 ? _b : customState.initParams.moleculeId; const clusterRecUrlStr = `${customState.initParams.pdbeUrl}static/superpose/matrices/${matrixAccession}`; const assetManager = plugin.managers.asset; const clusterRecUrl = assets_1.Asset.getUrlAsset(assetManager, clusterRecUrlStr); try { const clusterRecData = yield plugin.runTask(assetManager.resolve(clusterRecUrl, 'json', false)); if (clusterRecData && clusterRecData.data) { customState.superpositionState.matrixData = clusterRecData.data; } } catch (e) { customState.superpositionError = `Matrix data not available for ${matrixAccession}`; (_c = customState.events) === null || _c === void 0 ? void 0 : _c.superpositionInit.next(true); // Emit segment API data load event } }); } /** Download data about segment clustering and save in plugin custom state */ function getSegmentData(plugin) { return tslib_1.__awaiter(this, void 0, void 0, function* () { var _a; const customState = (0, plugin_custom_state_1.PluginCustomState)(plugin); if (!customState.initParams) throw new Error('customState.initParams has not been initialized'); if (!customState.superpositionState) throw new Error('customState.superpositionState has not been initialized'); // Get Data const segmentsUrl = `${customState.initParams.pdbeUrl}graph-api/uniprot/superposition/${customState.initParams.moleculeId}`; const assetManager = plugin.managers.asset; const url = assets_1.Asset.getUrlAsset(assetManager, segmentsUrl); try { const result = yield plugin.runTask(assetManager.resolve(url, 'json', false)); if (result === null || result === void 0 ? void 0 : result.data) { customState.superpositionState.segmentData = result.data[customState.initParams.moleculeId]; } } catch (e) { customState.superpositionError = `Superposition data not available for ${customState.initParams.moleculeId}`; (_a = customState.events) === null || _a === void 0 ? void 0 : _a.superpositionInit.next(true); // Emit segment API data load event } }); } function getChainLigands(carbEntity) { const ligandChain = []; const ligandLabels = []; const ligands = []; const labelValueArr = []; let ligNameStr = ''; for (const chemComp of carbEntity.chem_comp_list) { labelValueArr.push(`${chemComp.chem_comp_id} (${chemComp.count})`); } ligNameStr = labelValueArr.join(', '); for (const chain of carbEntity.chains) { ligandChain.push(chain.chain_id); ligandLabels.push(ligNameStr); const chainLigands = []; for (const residue of chain.residues) { chainLigands.push(residue.chem_comp_id + '-' + residue.residue_number); } ligands.push(chainLigands); } return { ligands, ligandChain, ligandLabels, }; } function getCarbPolymerDetailsFromApi(plugin, pdb_id) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const customState = (0, plugin_custom_state_1.PluginCustomState)(plugin); if (!customState.initParams) throw new Error('customState.initParams has not been initialized'); // Get Data const apiUrl = `${customState.initParams.pdbeUrl}api/pdb/entry/carbohydrate_polymer/${pdb_id}`; const assetManager = plugin.managers.asset; const url = assets_1.Asset.getUrlAsset(assetManager, apiUrl); let branchedLigands = []; let branchedChains = []; let branchedlabels = []; try { const result = yield plugin.runTask(assetManager.resolve(url, 'json', false)); if (result && result.data) { const carbEntities = result.data[pdb_id]; for (const carbEntity of carbEntities) { const carbLigData = getChainLigands(carbEntity); branchedLigands = branchedLigands.concat(carbLigData.ligands); branchedChains = branchedChains.concat(carbLigData.ligandChain); branchedlabels = branchedlabels.concat(carbLigData.ligandLabels); } } } catch (e) { // ignore } return { branchedChains, branchedLigands, branchedlabels, }; }); }