molstar
Version:
A comprehensive macromolecular library.
97 lines • 5.11 kB
JavaScript
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { __awaiter, __generator } from "tslib";
import { VdWLookup } from './common';
// TODO
// - iterate over units and elements
// - avoid using serial-element index whenever possible
// - calculate atomRadiusType only for invariant units
// - factor serialResidueIndex out
var updateChunk = 5000;
export function computeArea(runtime, ctx) {
return __awaiter(this, void 0, void 0, function () {
var atomRadius, i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
atomRadius = ctx.atomRadiusType;
i = 0;
_a.label = 1;
case 1:
if (!(i < atomRadius.length)) return [3 /*break*/, 5];
if (!runtime.shouldUpdate) return [3 /*break*/, 3];
return [4 /*yield*/, runtime.update({ message: 'Computing per residue surface accessibility...', current: i, max: atomRadius.length })];
case 2:
_a.sent();
_a.label = 3;
case 3:
computeRange(ctx, i, Math.min(i + updateChunk, atomRadius.length));
_a.label = 4;
case 4:
i += updateChunk;
return [3 /*break*/, 1];
case 5: return [2 /*return*/];
}
});
});
}
function computeRange(ctx, begin, end) {
var structure = ctx.structure, atomRadiusType = ctx.atomRadiusType, serialResidueIndex = ctx.serialResidueIndex, area = ctx.area, spherePoints = ctx.spherePoints, scalingConstant = ctx.scalingConstant, maxLookupRadius = ctx.maxLookupRadius, probeSize = ctx.probeSize;
var lookup3d = structure.lookup3d, serialMapping = structure.serialMapping, unitIndexMap = structure.unitIndexMap, units = structure.units;
var cumulativeUnitElementCount = serialMapping.cumulativeUnitElementCount, elementIndices = serialMapping.elementIndices, unitIndices = serialMapping.unitIndices;
for (var aI = begin; aI < end; ++aI) {
var vdw1 = VdWLookup[atomRadiusType[aI]];
if (vdw1 === VdWLookup[0])
continue;
var aUnit = units[unitIndices[aI]];
var aElementIndex = elementIndices[aI];
var aX = aUnit.conformation.x(aElementIndex);
var aY = aUnit.conformation.y(aElementIndex);
var aZ = aUnit.conformation.z(aElementIndex);
// pre-filter by lookup3d (provides >10x speed-up compared to naive evaluation)
var _a = lookup3d.find(aX, aY, aZ, maxLookupRadius), count = _a.count, lUnits = _a.units, indices = _a.indices, squaredDistances = _a.squaredDistances;
// see optimizations proposed in Eisenhaber et al., 1995 (https://doi.org/10.1002/jcc.540160303)
// collect neighbors for each atom
var radius1 = probeSize + vdw1;
var cutoff1 = probeSize + radius1;
var neighbors = []; // TODO reuse
for (var iI = 0; iI < count; ++iI) {
var bUnit = lUnits[iI];
var bI = cumulativeUnitElementCount[unitIndexMap.get(bUnit.id)] + indices[iI];
var bElementIndex = elementIndices[bI];
var vdw2 = VdWLookup[atomRadiusType[bI]];
if ((aUnit === bUnit && aElementIndex === bElementIndex) || vdw2 === VdWLookup[0])
continue;
var radius2 = probeSize + vdw2;
if (squaredDistances[iI] < (cutoff1 + vdw2) * (cutoff1 + vdw2)) {
var bElementIndex_1 = elementIndices[bI];
// while here: compute values for later lookup
neighbors[neighbors.length] = [squaredDistances[iI],
(squaredDistances[iI] + radius1 * radius1 - radius2 * radius2) / (2 * radius1),
bUnit.conformation.x(bElementIndex_1) - aX,
bUnit.conformation.y(bElementIndex_1) - aY,
bUnit.conformation.z(bElementIndex_1) - aZ];
}
}
// sort ascendingly by distance for improved downstream performance
neighbors.sort(function (a, b) { return a[0] - b[0]; });
var accessiblePointCount = 0;
sl: for (var sI = 0; sI < spherePoints.length; ++sI) {
var _b = spherePoints[sI], sX = _b[0], sY = _b[1], sZ = _b[2];
for (var nI = 0; nI < neighbors.length; ++nI) {
var _c = neighbors[nI], sqRadius = _c[1], nX = _c[2], nY = _c[3], nZ = _c[4];
var dot = sX * nX + sY * nY + sZ * nZ;
if (dot > sqRadius) {
continue sl;
}
}
++accessiblePointCount;
}
area[serialResidueIndex[aI]] += scalingConstant * accessiblePointCount * radius1 * radius1;
}
}
//# sourceMappingURL=area.js.map