UNPKG

molstar

Version:

A comprehensive macromolecular library.

208 lines (207 loc) 9.4 kB
"use strict"; /** * Copyright (c) 2019-2024 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Sebastian Bittrich <sebastian.bittrich@rcsb.org> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.DefaultDSSPComputationProps = exports.DSSPComputationParams = void 0; exports.computeUnitDSSP = computeUnitDSSP; const secondary_structure_1 = require("../../../mol-model/structure/model/properties/secondary-structure"); const types_1 = require("../../../mol-model/structure/model/types"); const param_definition_1 = require("../../../mol-util/param-definition"); const bends_1 = require("./dssp/bends"); const backbone_hbonds_1 = require("./dssp/backbone-hbonds"); const common_1 = require("./dssp/common"); const turns_1 = require("./dssp/turns"); const helices_1 = require("./dssp/helices"); const ladders_1 = require("./dssp/ladders"); const bridges_1 = require("./dssp/bridges"); const sheets_1 = require("./dssp/sheets"); const dihedral_angles_1 = require("./dssp/dihedral-angles"); const trace_lookup_1 = require("./dssp/trace-lookup"); const protein_info_1 = require("./dssp/protein-info"); const int_1 = require("../../../mol-data/int"); /** * TODO bugs to fix: * - some turns are not detected correctly: see e.g. pdb:1acj - maybe more than 2 hbonds require some residue to donate electrons * - some sheets are not extended correctly: see e.g. pdb:1acj * - validate new helix definition * - validate new ordering of secondary structure elements */ exports.DSSPComputationParams = { oldDefinition: param_definition_1.ParamDefinition.Boolean(true, { description: 'Whether to use the old DSSP convention for the annotation of turns and helices, causes them to be two residues shorter' }), oldOrdering: param_definition_1.ParamDefinition.Boolean(true, { description: 'Alpha-helices are preferred over 3-10 helices' }) }; exports.DefaultDSSPComputationProps = param_definition_1.ParamDefinition.getDefaultValues(exports.DSSPComputationParams); async function computeUnitDSSP(unit, params) { const proteinInfo = (0, protein_info_1.getUnitProteinInfo)(unit); const { residueIndices } = proteinInfo; const lookup3d = (0, trace_lookup_1.calcUnitProteinTraceLookup3D)(unit, residueIndices); const hbonds = (0, backbone_hbonds_1.calcUnitBackboneHbonds)(unit, proteinInfo, lookup3d); const residueCount = residueIndices.length; const flags = new Uint32Array(residueCount); // console.log(`calculating secondary structure elements using ${ params.oldDefinition ? 'old' : 'revised'} definition and ${ params.oldOrdering ? 'old' : 'revised'} ordering of secondary structure elements`) const torsionAngles = (0, dihedral_angles_1.calculateUnitDihedralAngles)(unit, proteinInfo); const ladders = []; const bridges = []; const getResidueFlag = params.oldDefinition ? getOriginalResidueFlag : getUpdatedResidueFlag; const getFlagName = params.oldOrdering ? getOriginalFlagName : getUpdatedFlagName; const ctx = { params, getResidueFlag, getFlagName, unit, proteinInfo, flags, hbonds, torsionAngles, ladders, bridges }; (0, turns_1.assignTurns)(ctx); (0, helices_1.assignHelices)(ctx); (0, bends_1.assignBends)(ctx); (0, bridges_1.assignBridges)(ctx); (0, ladders_1.assignLadders)(ctx); (0, sheets_1.assignSheets)(ctx); const assignment = getDSSPAssignment(flags, getResidueFlag); const type = new Uint32Array(residueCount); const keys = []; const elements = []; const getIndex = (rI) => int_1.SortedArray.indexOf(residueIndices, rI); for (let i = 0, il = residueIndices.length; i < il; ++i) { const assign = assignment[i]; type[i] = assign; const flag = getResidueFlag(flags[i]); // console.log(i, SortedArray.indexOf(residueIndices, i), getFlagName(flags[i])) // TODO is this expected behavior? elements will be strictly split depending on 'winning' flag if (elements.length === 0 /* would fail at very start */ || flag !== elements[elements.length - 1].flags /* flag changed */) { elements[elements.length] = createElement(mapToKind(assign), flags[i], getResidueFlag); } keys[i] = elements.length - 1; } return (0, secondary_structure_1.SecondaryStructure)(type, keys, elements, getIndex); } function createElement(kind, flag, getResidueFlag) { // TODO would be nice to add more detailed information if (kind === 'helix') { return { kind: 'helix', flags: getResidueFlag(flag) }; } else if (kind === 'sheet') { return { kind: 'sheet', flags: getResidueFlag(flag) }; } else if (kind === 'turn' || kind === 'bend') { return { kind: 'turn', flags: getResidueFlag(flag) }; } else { return { kind: 'none' }; } } function mapToKind(assignment) { if (assignment === types_1.SecondaryStructureType.SecondaryStructureDssp.H || assignment === types_1.SecondaryStructureType.SecondaryStructureDssp.G || assignment === types_1.SecondaryStructureType.SecondaryStructureDssp.I) { return 'helix'; } else if (assignment === types_1.SecondaryStructureType.SecondaryStructureDssp.B || assignment === types_1.SecondaryStructureType.SecondaryStructureDssp.E) { return 'sheet'; } else if (assignment === types_1.SecondaryStructureType.SecondaryStructureDssp.T) { return 'turn'; } else if (assignment === types_1.SecondaryStructureType.SecondaryStructureDssp.S) { return 'bend'; } else { return 'none'; } } /** Original priority: H,B,E,G,I,T,S */ function getOriginalResidueFlag(f) { if (common_1.DSSPType.is(f, 1 /* DSSPType.Flag.H */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.H; if (common_1.DSSPType.is(f, 4 /* DSSPType.Flag.E */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.E; if (common_1.DSSPType.is(f, 2 /* DSSPType.Flag.B */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.B; if (common_1.DSSPType.is(f, 8 /* DSSPType.Flag.G */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.G; if (common_1.DSSPType.is(f, 16 /* DSSPType.Flag.I */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.I; if (common_1.DSSPType.is(f, 64 /* DSSPType.Flag.T */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.T; if (common_1.DSSPType.is(f, 32 /* DSSPType.Flag.S */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.S; return 0 /* SecondaryStructureType.Flag.None */; } function getOriginalFlagName(f) { if (common_1.DSSPType.is(f, 1 /* DSSPType.Flag.H */)) return 'H'; if (common_1.DSSPType.is(f, 4 /* DSSPType.Flag.E */)) return 'E'; if (common_1.DSSPType.is(f, 2 /* DSSPType.Flag.B */)) return 'B'; if (common_1.DSSPType.is(f, 8 /* DSSPType.Flag.G */)) return 'G'; if (common_1.DSSPType.is(f, 16 /* DSSPType.Flag.I */)) return 'I'; if (common_1.DSSPType.is(f, 64 /* DSSPType.Flag.T */)) return 'T'; if (common_1.DSSPType.is(f, 32 /* DSSPType.Flag.S */)) return 'S'; return '-'; } /** Version 2.1.0 priority: I,H,B,E,G,T,S */ function getUpdatedResidueFlag(f) { if (common_1.DSSPType.is(f, 16 /* DSSPType.Flag.I */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.I; if (common_1.DSSPType.is(f, 1 /* DSSPType.Flag.H */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.H; if (common_1.DSSPType.is(f, 4 /* DSSPType.Flag.E */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.E; if (common_1.DSSPType.is(f, 2 /* DSSPType.Flag.B */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.B; if (common_1.DSSPType.is(f, 8 /* DSSPType.Flag.G */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.G; if (common_1.DSSPType.is(f, 64 /* DSSPType.Flag.T */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.T; if (common_1.DSSPType.is(f, 32 /* DSSPType.Flag.S */)) return types_1.SecondaryStructureType.SecondaryStructureDssp.S; return 0 /* SecondaryStructureType.Flag.None */; } function getUpdatedFlagName(f) { if (common_1.DSSPType.is(f, 16 /* DSSPType.Flag.I */)) return 'I'; if (common_1.DSSPType.is(f, 1 /* DSSPType.Flag.H */)) return 'H'; if (common_1.DSSPType.is(f, 4 /* DSSPType.Flag.E */)) return 'E'; if (common_1.DSSPType.is(f, 2 /* DSSPType.Flag.B */)) return 'B'; if (common_1.DSSPType.is(f, 8 /* DSSPType.Flag.G */)) return 'G'; if (common_1.DSSPType.is(f, 64 /* DSSPType.Flag.T */)) return 'T'; if (common_1.DSSPType.is(f, 32 /* DSSPType.Flag.S */)) return 'S'; return '-'; } function getDSSPAssignment(flags, getResidueFlag) { const type = new Uint32Array(flags.length); for (let i = 0, il = flags.length; i < il; ++i) { const f = common_1.DSSPType.create(flags[i]); type[i] = getResidueFlag(f); } return type; }