UNPKG

molstar

Version:

A comprehensive macromolecular library.

208 lines 8.8 kB
/** * Copyright (c) 2019 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> */ import { __awaiter, __generator } from "tslib"; import { SecondaryStructure } from '../../../mol-model/structure/model/properties/seconday-structure'; import { SecondaryStructureType } from '../../../mol-model/structure/model/types'; import { ParamDefinition as PD } from '../../../mol-util/param-definition'; import { assignBends } from './dssp/bends'; import { calcUnitBackboneHbonds } from './dssp/backbone-hbonds'; import { DSSPType } from './dssp/common'; import { assignTurns } from './dssp/turns'; import { assignHelices } from './dssp/helices'; import { assignLadders } from './dssp/ladders'; import { assignBridges } from './dssp/bridges'; import { assignSheets } from './dssp/sheets'; import { calculateUnitDihedralAngles } from './dssp/dihedral-angles'; import { calcUnitProteinTraceLookup3D } from './dssp/trace-lookup'; import { getUnitProteinInfo } from './dssp/protein-info'; import { SortedArray } from '../../../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 */ export var DSSPComputationParams = { oldDefinition: PD.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: PD.Boolean(true, { description: 'Alpha-helices are preferred over 3-10 helices' }) }; export function computeUnitDSSP(unit, params) { return __awaiter(this, void 0, void 0, function () { var proteinInfo, residueIndices, lookup3d, hbonds, residueCount, flags, torsionAngles, ladders, bridges, getResidueFlag, getFlagName, ctx, assignment, type, keys, elements, getIndex, i, il, assign, flag; return __generator(this, function (_a) { proteinInfo = getUnitProteinInfo(unit); residueIndices = proteinInfo.residueIndices; lookup3d = calcUnitProteinTraceLookup3D(unit, residueIndices); hbonds = calcUnitBackboneHbonds(unit, proteinInfo, lookup3d); residueCount = residueIndices.length; flags = new Uint32Array(residueCount); torsionAngles = calculateUnitDihedralAngles(unit, proteinInfo); ladders = []; bridges = []; getResidueFlag = params.oldDefinition ? getOriginalResidueFlag : getUpdatedResidueFlag; getFlagName = params.oldOrdering ? getOriginalFlagName : getUpdatedFlagName; ctx = { params: params, getResidueFlag: getResidueFlag, getFlagName: getFlagName, unit: unit, proteinInfo: proteinInfo, flags: flags, hbonds: hbonds, torsionAngles: torsionAngles, ladders: ladders, bridges: bridges }; assignTurns(ctx); assignHelices(ctx); assignBends(ctx); assignBridges(ctx); assignLadders(ctx); assignSheets(ctx); assignment = getDSSPAssignment(flags, getResidueFlag); type = new Uint32Array(residueCount); keys = []; elements = []; getIndex = function (rI) { return SortedArray.indexOf(residueIndices, rI); }; for (i = 0, il = residueIndices.length; i < il; ++i) { assign = assignment[i]; type[i] = assign; 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 [2 /*return*/, 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 === SecondaryStructureType.SecondaryStructureDssp.H || assignment === SecondaryStructureType.SecondaryStructureDssp.G || assignment === SecondaryStructureType.SecondaryStructureDssp.I) { return 'helix'; } else if (assignment === SecondaryStructureType.SecondaryStructureDssp.B || assignment === SecondaryStructureType.SecondaryStructureDssp.E) { return 'sheet'; } else if (assignment === SecondaryStructureType.SecondaryStructureDssp.T) { return 'turn'; } else if (assignment === SecondaryStructureType.SecondaryStructureDssp.S) { return 'bend'; } else { return 'none'; } } /** Original priority: H,B,E,G,I,T,S */ function getOriginalResidueFlag(f) { if (DSSPType.is(f, 1 /* H */)) return SecondaryStructureType.SecondaryStructureDssp.H; if (DSSPType.is(f, 4 /* E */)) return SecondaryStructureType.SecondaryStructureDssp.E; if (DSSPType.is(f, 2 /* B */)) return SecondaryStructureType.SecondaryStructureDssp.B; if (DSSPType.is(f, 8 /* G */)) return SecondaryStructureType.SecondaryStructureDssp.G; if (DSSPType.is(f, 16 /* I */)) return SecondaryStructureType.SecondaryStructureDssp.I; if (DSSPType.is(f, 64 /* T */)) return SecondaryStructureType.SecondaryStructureDssp.T; if (DSSPType.is(f, 32 /* S */)) return SecondaryStructureType.SecondaryStructureDssp.S; return 0 /* None */; } function getOriginalFlagName(f) { if (DSSPType.is(f, 1 /* H */)) return 'H'; if (DSSPType.is(f, 4 /* E */)) return 'E'; if (DSSPType.is(f, 2 /* B */)) return 'B'; if (DSSPType.is(f, 8 /* G */)) return 'G'; if (DSSPType.is(f, 16 /* I */)) return 'I'; if (DSSPType.is(f, 64 /* T */)) return 'T'; if (DSSPType.is(f, 32 /* S */)) return 'S'; return '-'; } /** Version 2.1.0 priority: I,H,B,E,G,T,S */ function getUpdatedResidueFlag(f) { if (DSSPType.is(f, 16 /* I */)) return SecondaryStructureType.SecondaryStructureDssp.I; if (DSSPType.is(f, 1 /* H */)) return SecondaryStructureType.SecondaryStructureDssp.H; if (DSSPType.is(f, 4 /* E */)) return SecondaryStructureType.SecondaryStructureDssp.E; if (DSSPType.is(f, 2 /* B */)) return SecondaryStructureType.SecondaryStructureDssp.B; if (DSSPType.is(f, 8 /* G */)) return SecondaryStructureType.SecondaryStructureDssp.G; if (DSSPType.is(f, 64 /* T */)) return SecondaryStructureType.SecondaryStructureDssp.T; if (DSSPType.is(f, 32 /* S */)) return SecondaryStructureType.SecondaryStructureDssp.S; return 0 /* None */; } function getUpdatedFlagName(f) { if (DSSPType.is(f, 16 /* I */)) return 'I'; if (DSSPType.is(f, 1 /* H */)) return 'H'; if (DSSPType.is(f, 4 /* E */)) return 'E'; if (DSSPType.is(f, 2 /* B */)) return 'B'; if (DSSPType.is(f, 8 /* G */)) return 'G'; if (DSSPType.is(f, 64 /* T */)) return 'T'; if (DSSPType.is(f, 32 /* S */)) return 'S'; return '-'; } function getDSSPAssignment(flags, getResidueFlag) { var type = new Uint32Array(flags.length); for (var i = 0, il = flags.length; i < il; ++i) { var f = DSSPType.create(flags[i]); type[i] = getResidueFlag(f); } return type; } //# sourceMappingURL=dssp.js.map