molstar
Version:
A comprehensive macromolecular library.
117 lines • 6.5 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>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAtomicRanges = void 0;
var int_1 = require("../../../../../mol-data/int");
var sorted_ranges_1 = require("../../../../../mol-data/int/sorted-ranges");
var types_1 = require("../../types");
var util_1 = require("../../../util");
var linear_algebra_1 = require("../../../../../mol-math/linear-algebra");
function areBackboneConnected(riStart, riEnd, conformation, index, derived) {
var _a = derived.residue, polymerType = _a.polymerType, traceElementIndex = _a.traceElementIndex, directionFromElementIndex = _a.directionFromElementIndex, directionToElementIndex = _a.directionToElementIndex;
var ptStart = polymerType[riStart];
var ptEnd = polymerType[riEnd];
if (ptStart === 0 /* NA */ || ptEnd === 0 /* NA */)
return false;
if (traceElementIndex[riStart] === -1 || traceElementIndex[riEnd] === -1)
return false;
var eiStart = index.findAtomsOnResidue(riStart, (0, util_1.getAtomIdForAtomRole)(ptStart, 'backboneStart'));
var eiEnd = index.findAtomsOnResidue(riEnd, (0, util_1.getAtomIdForAtomRole)(ptEnd, 'backboneEnd'));
if (eiStart === -1 || eiEnd === -1) {
eiStart = index.findAtomsOnResidue(riStart, (0, util_1.getAtomIdForAtomRole)(ptStart, 'coarseBackbone'));
eiEnd = index.findAtomsOnResidue(riEnd, (0, util_1.getAtomIdForAtomRole)(ptEnd, 'coarseBackbone'));
}
var x = conformation.x, y = conformation.y, z = conformation.z;
var pStart = linear_algebra_1.Vec3.create(x[eiStart], y[eiStart], z[eiStart]);
var pEnd = linear_algebra_1.Vec3.create(x[eiEnd], y[eiEnd], z[eiEnd]);
var isCoarse = directionFromElementIndex[riStart] === -1 || directionToElementIndex[riStart] === -1 || directionFromElementIndex[riEnd] === -1 || directionToElementIndex[riEnd] === -1;
return linear_algebra_1.Vec3.distance(pStart, pEnd) < (isCoarse ? 10 : 3);
}
function getAtomicRanges(hierarchy, entities, conformation, sequence) {
var polymerRanges = [];
var gapRanges = [];
var cyclicPolymerMap = new Map();
var chainIt = int_1.Segmentation.transientSegments(hierarchy.chainAtomSegments, int_1.Interval.ofBounds(0, hierarchy.atoms._rowCount));
var residueIt = int_1.Segmentation.transientSegments(hierarchy.residueAtomSegments, int_1.Interval.ofBounds(0, hierarchy.atoms._rowCount));
var index = hierarchy.index, derived = hierarchy.derived;
var label_seq_id = hierarchy.residues.label_seq_id;
var label_entity_id = hierarchy.chains.label_entity_id;
var _a = derived.residue, moleculeType = _a.moleculeType, traceElementIndex = _a.traceElementIndex;
var prevSeqId;
var prevStart;
var prevEnd;
var startIndex;
while (chainIt.hasNext) {
var chainSegment = chainIt.move();
residueIt.setSegment(chainSegment);
prevSeqId = -1;
prevStart = -1;
prevEnd = -1;
startIndex = -1;
var eI = entities.getEntityIndex(label_entity_id.value(chainSegment.index));
var seq = sequence.byEntityKey[eI];
var maxSeqId = seq ? seq.sequence.seqId.value(seq.sequence.seqId.rowCount - 1) : -1;
// check cyclic peptides, seqIds and distance must be compatible
var riStart = hierarchy.residueAtomSegments.index[chainSegment.start];
var riEnd = hierarchy.residueAtomSegments.index[chainSegment.end - 1];
var seqIdStart = label_seq_id.value(riStart);
var seqIdEnd = label_seq_id.value(riEnd);
if (seqIdStart === 1 && seqIdEnd === maxSeqId && conformation.xyzDefined && areBackboneConnected(riStart, riEnd, conformation, index, derived)) {
cyclicPolymerMap.set(riStart, riEnd);
cyclicPolymerMap.set(riEnd, riStart);
}
while (residueIt.hasNext) {
var residueSegment = residueIt.move();
var residueIndex = residueSegment.index;
var seqId = label_seq_id.value(residueIndex);
// treat polymers residues that don't have a trace element resolved as gaps
if ((0, types_1.isPolymer)(moleculeType[residueIndex]) && traceElementIndex[residueIndex] !== -1) {
if (startIndex !== -1) {
if (seqId !== prevSeqId + 1) {
polymerRanges.push(startIndex, prevEnd - 1);
gapRanges.push(prevStart, residueSegment.end - 1);
startIndex = residueSegment.start;
}
else if (!residueIt.hasNext) {
polymerRanges.push(startIndex, residueSegment.end - 1);
// TODO store terminal gaps
}
else {
var riStart_1 = hierarchy.residueAtomSegments.index[residueSegment.start];
var riEnd_1 = hierarchy.residueAtomSegments.index[prevEnd - 1];
if (conformation.xyzDefined && !areBackboneConnected(riStart_1, riEnd_1, conformation, hierarchy.index, derived)) {
polymerRanges.push(startIndex, prevEnd - 1);
// add gap even for consecutive residues if they are not connected
gapRanges.push(prevStart, residueSegment.end - 1);
startIndex = residueSegment.start;
}
}
}
else {
startIndex = residueSegment.start; // start polymer
// TODO store terminal gaps
}
}
else {
if (startIndex !== -1) {
polymerRanges.push(startIndex, prevEnd - 1);
startIndex = -1;
}
}
prevStart = residueSegment.start;
prevEnd = residueSegment.end;
prevSeqId = seqId;
}
}
return {
polymerRanges: sorted_ranges_1.SortedRanges.ofSortedRanges(polymerRanges),
gapRanges: sorted_ranges_1.SortedRanges.ofSortedRanges(gapRanges),
cyclicPolymerMap: cyclicPolymerMap
};
}
exports.getAtomicRanges = getAtomicRanges;
//# sourceMappingURL=atomic-ranges.js.map