molstar
Version:
A comprehensive macromolecular library.
269 lines (268 loc) • 12.9 kB
JavaScript
"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;