UNPKG

molstar

Version:

A comprehensive macromolecular library.

269 lines (268 loc) 12.9 kB
"use strict"; /** * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> * @author David Sehnal <david.sehnal@gmail.com> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.eachPolymerGapElement = exports.getPolymerGapElementLoci = exports.eachPolymerElement = exports.eachAtomicUnitTracedElement = exports.getPolymerElementLoci = exports.PolymerGapLocationIterator = exports.PolymerLocationIterator = exports.getGapRanges = exports.getPolymerRanges = exports.OverhangFactor = exports.NucleicShift = exports.StandardShift = exports.HelixTension = exports.StandardTension = void 0; var tslib_1 = require("tslib"); var structure_1 = require("../../../../mol-model/structure"); var int_1 = require("../../../../mol-data/int"); var loci_1 = require("../../../../mol-model/loci"); var location_iterator_1 = require("../../../../mol-geo/util/location-iterator"); var common_1 = require("./common"); tslib_1.__exportStar(require("./polymer/backbone"), exports); tslib_1.__exportStar(require("./polymer/gap-iterator"), exports); tslib_1.__exportStar(require("./polymer/trace-iterator"), exports); tslib_1.__exportStar(require("./polymer/curve-segment"), exports); exports.StandardTension = 0.5; exports.HelixTension = 0.9; exports.StandardShift = 0.5; exports.NucleicShift = 0.3; exports.OverhangFactor = 2; function getPolymerRanges(unit) { switch (unit.kind) { case 0 /* Unit.Kind.Atomic */: return unit.model.atomicRanges.polymerRanges; case 1 /* Unit.Kind.Spheres */: return unit.model.coarseHierarchy.spheres.polymerRanges; case 2 /* Unit.Kind.Gaussians */: return unit.model.coarseHierarchy.gaussians.polymerRanges; } } exports.getPolymerRanges = getPolymerRanges; function getGapRanges(unit) { switch (unit.kind) { case 0 /* Unit.Kind.Atomic */: return unit.model.atomicRanges.gapRanges; case 1 /* Unit.Kind.Spheres */: return unit.model.coarseHierarchy.spheres.gapRanges; case 2 /* Unit.Kind.Gaussians */: return unit.model.coarseHierarchy.gaussians.gapRanges; } } exports.getGapRanges = getGapRanges; var PolymerLocationIterator; (function (PolymerLocationIterator) { function fromGroup(structureGroup) { var group = structureGroup.group, structure = structureGroup.structure; var polymerElements = group.units[0].polymerElements; var groupCount = polymerElements.length; var instanceCount = group.units.length; var location = structure_1.StructureElement.Location.create(structure); var getLocation = function (groupIndex, instanceIndex) { var unit = group.units[instanceIndex]; location.unit = unit; location.element = polymerElements[groupIndex]; return location; }; return (0, location_iterator_1.LocationIterator)(groupCount, instanceCount, 1, getLocation); } PolymerLocationIterator.fromGroup = fromGroup; })(PolymerLocationIterator = exports.PolymerLocationIterator || (exports.PolymerLocationIterator = {})); var PolymerGapLocationIterator; (function (PolymerGapLocationIterator) { function fromGroup(structureGroup) { var group = structureGroup.group, structure = structureGroup.structure; var gapElements = group.units[0].gapElements; var groupCount = gapElements.length; var instanceCount = group.units.length; var location = structure_1.StructureElement.Location.create(structure); var getLocation = function (groupIndex, instanceIndex) { var unit = group.units[instanceIndex]; location.unit = unit; location.element = gapElements[groupIndex]; return location; }; return (0, location_iterator_1.LocationIterator)(groupCount, instanceCount, 1, getLocation); } PolymerGapLocationIterator.fromGroup = fromGroup; })(PolymerGapLocationIterator = exports.PolymerGapLocationIterator || (exports.PolymerGapLocationIterator = {})); /** Return a Loci for the elements of the whole residue of a polymer element. */ function getPolymerElementLoci(pickingId, structureGroup, id) { var objectId = pickingId.objectId, instanceId = pickingId.instanceId, groupId = pickingId.groupId; if (id === objectId) { var structure = structureGroup.structure, group = structureGroup.group; var unit = group.units[instanceId]; if (structure_1.Unit.isAtomic(unit)) { return (0, common_1.getResidueLoci)(structure, unit, unit.polymerElements[groupId]); } else { var elements = unit.elements; var elementIndex = unit.polymerElements[groupId]; var unitIndex = int_1.OrderedSet.indexOf(elements, elementIndex); if (unitIndex !== -1) { var indices = int_1.OrderedSet.ofSingleton(unitIndex); return structure_1.StructureElement.Loci(structure, [{ unit: unit, indices: indices }]); } } } return loci_1.EmptyLoci; } exports.getPolymerElementLoci = getPolymerElementLoci; function tryApplyResidueInterval(offset, elements, traceElementIndex, apply, r1, r2) { var start = -1, startIdx = -1; for (var rI = r1; rI <= r2; rI++) { var eI = traceElementIndex[rI]; if (eI < 0) continue; start = int_1.OrderedSet.indexOf(elements, eI); if (start >= 0) { startIdx = rI; break; } } if (start < 0) { return false; } var end = start; for (var rI = r2; rI > startIdx; rI--) { var eI = traceElementIndex[rI]; if (eI < 0) continue; var e = int_1.OrderedSet.indexOf(elements, eI); if (e >= 0) { end = e; break; } } return apply(int_1.Interval.ofRange(offset + start, offset + end)); } function eachAtomicUnitTracedElement(offset, groupSize, elementsSelector, apply, e) { var changed = false; var elements = e.unit.elements; var traceElementIndex = e.unit.model.atomicHierarchy.derived.residue.traceElementIndex; var resIndex = e.unit.model.atomicHierarchy.residueAtomSegments.index; var tracedElements = elementsSelector(e.unit); if (int_1.Interval.is(e.indices)) { if (int_1.Interval.start(e.indices) === 0 && int_1.Interval.end(e.indices) === e.unit.elements.length) { // full unit here changed = apply(int_1.Interval.ofBounds(offset, offset + groupSize)) || changed; } else { var r1 = resIndex[elements[int_1.Interval.min(e.indices)]]; var r2 = resIndex[elements[int_1.Interval.max(e.indices)]]; changed = tryApplyResidueInterval(offset, tracedElements, traceElementIndex, apply, r1, r2) || changed; } } else { var indices = e.indices; for (var i = 0, _i = indices.length; i < _i; i++) { var r1 = resIndex[elements[indices[i]]]; var r2 = r1; var endI = i + 1; while (endI < _i) { var _r = resIndex[elements[indices[endI]]]; if (_r - r2 > 1) break; r2 = _r; endI++; } i = endI - 1; changed = tryApplyResidueInterval(offset, tracedElements, traceElementIndex, apply, r1, r2) || changed; } } return changed; } exports.eachAtomicUnitTracedElement = eachAtomicUnitTracedElement; function selectPolymerElements(u) { return u.polymerElements; } /** Mark a polymer element (e.g. part of a cartoon trace) */ function eachPolymerElement(loci, structureGroup, apply) { var changed = false; if (!structure_1.StructureElement.Loci.is(loci)) return false; var structure = structureGroup.structure, group = structureGroup.group; if (!structure_1.Structure.areEquivalent(loci.structure, structure)) return false; var groupCount = group.units[0].polymerElements.length; for (var _a = 0, _b = loci.elements; _a < _b.length; _a++) { var e = _b[_a]; if (!group.unitIndexMap.has(e.unit.id)) continue; var offset = group.unitIndexMap.get(e.unit.id) * groupCount; // to target unit instance if (structure_1.Unit.isAtomic(e.unit)) { changed = eachAtomicUnitTracedElement(offset, groupCount, selectPolymerElements, apply, e) || changed; } else { if (int_1.Interval.is(e.indices)) { var start = offset + int_1.Interval.start(e.indices); var end = offset + int_1.Interval.end(e.indices); changed = apply(int_1.Interval.ofBounds(start, end)) || changed; } else { for (var i = 0, _i = e.indices.length; i < _i; i++) { var start = e.indices[i]; var endI = i + 1; while (endI < _i && e.indices[endI] === start) endI++; i = endI - 1; var end = e.indices[i]; changed = apply(int_1.Interval.ofRange(offset + start, offset + end)) || changed; } } } } return changed; } exports.eachPolymerElement = eachPolymerElement; /** Return a Loci for both directions of the polymer gap element. */ function getPolymerGapElementLoci(pickingId, structureGroup, id) { var objectId = pickingId.objectId, instanceId = pickingId.instanceId, groupId = pickingId.groupId; if (id === objectId) { var structure = structureGroup.structure, group = structureGroup.group; var unit = group.units[instanceId]; var unitIndexA = int_1.OrderedSet.indexOf(unit.elements, unit.gapElements[groupId]); var unitIndexB = int_1.OrderedSet.indexOf(unit.elements, unit.gapElements[groupId % 2 ? groupId - 1 : groupId + 1]); if (unitIndexA !== -1 && unitIndexB !== -1) { return structure_1.Bond.Loci(structure, [ structure_1.Bond.Location(structure, unit, unitIndexA, structure, unit, unitIndexB), structure_1.Bond.Location(structure, unit, unitIndexB, structure, unit, unitIndexA) ]); } } return loci_1.EmptyLoci; } exports.getPolymerGapElementLoci = getPolymerGapElementLoci; function eachPolymerGapElement(loci, structureGroup, apply) { var changed = false; if (structure_1.Bond.isLoci(loci)) { var structure = structureGroup.structure, group = structureGroup.group; if (!structure_1.Structure.areRootsEquivalent(loci.structure, structure)) return false; loci = structure_1.Bond.remapLoci(loci, structure); var groupCount = group.units[0].gapElements.length; for (var _a = 0, _b = loci.bonds; _a < _b.length; _a++) { var b = _b[_a]; var unitIdx = group.unitIndexMap.get(b.aUnit.id); if (unitIdx !== undefined) { var idxA = int_1.OrderedSet.indexOf(b.aUnit.gapElements, b.aUnit.elements[b.aIndex]); var idxB = int_1.OrderedSet.indexOf(b.bUnit.gapElements, b.bUnit.elements[b.bIndex]); if (idxA !== -1 && idxB !== -1) { if (apply(int_1.Interval.ofSingleton(unitIdx * groupCount + idxA))) changed = true; } } } } else if (structure_1.StructureElement.Loci.is(loci)) { var structure = structureGroup.structure, group = structureGroup.group; if (!structure_1.Structure.areRootsEquivalent(loci.structure, structure)) return false; loci = structure_1.StructureElement.Loci.remap(loci, structure); var groupCount_1 = group.units[0].gapElements.length; var _loop_1 = function (e) { var unitIdx = group.unitIndexMap.get(e.unit.id); if (unitIdx !== undefined) { int_1.OrderedSet.forEach(e.indices, function (v) { var idx = int_1.OrderedSet.indexOf(e.unit.gapElements, e.unit.elements[v]); if (idx !== -1) { if (apply(int_1.Interval.ofSingleton(unitIdx * groupCount_1 + idx))) changed = true; } }); } }; for (var _c = 0, _d = loci.elements; _c < _d.length; _c++) { var e = _d[_c]; _loop_1(e); } } return changed; } exports.eachPolymerGapElement = eachPolymerGapElement;