UNPKG

molstar

Version:

A comprehensive macromolecular library.

108 lines 4.11 kB
/** * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> */ import { __awaiter, __generator } from "tslib"; import { sortArray } from '../../mol-data/util'; import { canComputeGrid3dOnGPU } from '../../mol-gl/compute/grid3d'; import { Task } from '../../mol-task'; import { createGrid, initCubeGrid } from './data-model'; import { gpuComputeAlphaOrbitalsDensityGridValues } from './gpu/compute'; export function createSphericalCollocationDensityGrid(params, orbitals, webgl) { var _this = this; return Task.create('Spherical Collocation Grid', function (ctx) { return __awaiter(_this, void 0, void 0, function () { var cubeGrid, matrix, grid, isovalues; return __generator(this, function (_a) { switch (_a.label) { case 0: cubeGrid = initCubeGrid(params); if (!canComputeGrid3dOnGPU(webgl)) return [3 /*break*/, 2]; return [4 /*yield*/, gpuComputeAlphaOrbitalsDensityGridValues(ctx, webgl, cubeGrid, orbitals)]; case 1: // console.time('gpu'); matrix = _a.sent(); return [3 /*break*/, 3]; case 2: throw new Error('Missing OES_texture_float WebGL extension.'); case 3: grid = createGrid(cubeGrid, matrix, [0, 1, 2]); if (!params.doNotComputeIsovalues) { isovalues = computeDensityIsocontourValues(matrix, 0.85); } return [2 /*return*/, { grid: grid, isovalues: isovalues }]; } }); }); }); } export function computeDensityIsocontourValues(input, cumulativeThreshold) { var weightSum = 0; for (var i = 0, _i = input.length; i < _i; i++) { var v = input[i]; var w = Math.abs(v); weightSum += w; } var avgWeight = weightSum / input.length; var minWeight = 3 * avgWeight; // do not try to identify isovalues for degenerate data // e.g. all values are almost same if (Math.abs(avgWeight - input[0] * input[0]) < 1e-5) { return { negative: void 0, positive: void 0 }; } var size = 0; while (true) { var csum = 0; size = 0; for (var i = 0, _i = input.length; i < _i; i++) { var v = input[i]; var w = Math.abs(v); if (w >= minWeight) { csum += w; size++; } } if (csum / weightSum > cumulativeThreshold) { break; } minWeight -= avgWeight; } var values = new Float32Array(size); var weights = new Float32Array(size); var indices = new Int32Array(size); var o = 0; for (var i = 0, _i = input.length; i < _i; i++) { var v = input[i]; var w = Math.abs(v); if (w >= minWeight) { values[o] = v; weights[o] = w; indices[o] = o; o++; } } sortArray(indices, function (indices, i, j) { return weights[indices[j]] - weights[indices[i]]; }); var cweight = 0, cutoffIndex = 0; for (var i = 0; i < size; i++) { cweight += weights[indices[i]]; if (cweight / weightSum >= cumulativeThreshold) { cutoffIndex = i; break; } } var positive = Number.POSITIVE_INFINITY, negative = Number.NEGATIVE_INFINITY; for (var i = 0; i < cutoffIndex; i++) { var v = values[indices[i]]; if (v > 0) { if (v < positive) positive = v; } else if (v < 0) { if (v > negative) negative = v; } } return { negative: negative !== Number.NEGATIVE_INFINITY ? negative : void 0, positive: positive !== Number.POSITIVE_INFINITY ? positive : void 0, }; } //# sourceMappingURL=density.js.map