UNPKG

molstar

Version:

A comprehensive macromolecular library.

117 lines (116 loc) 4.7 kB
"use strict"; /** * Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.computeDensityIsocontourValues = exports.createSphericalCollocationDensityGrid = void 0; var tslib_1 = require("tslib"); var util_1 = require("../../mol-data/util"); var grid3d_1 = require("../../mol-gl/compute/grid3d"); var mol_task_1 = require("../../mol-task"); var debug_1 = require("../../mol-util/debug"); var data_model_1 = require("./data-model"); var compute_1 = require("./gpu/compute"); function createSphericalCollocationDensityGrid(params, orbitals, webgl) { var _this = this; return mol_task_1.Task.create('Spherical Collocation Grid', function (ctx) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var cubeGrid, matrix, grid, isovalues; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: cubeGrid = (0, data_model_1.initCubeGrid)(params); if (!(0, grid3d_1.canComputeGrid3dOnGPU)(webgl)) return [3 /*break*/, 2]; if (debug_1.isTimingMode) webgl.timer.mark('createSphericalCollocationDensityGrid'); return [4 /*yield*/, (0, compute_1.gpuComputeAlphaOrbitalsDensityGridValues)(ctx, webgl, cubeGrid, orbitals)]; case 1: matrix = _a.sent(); if (debug_1.isTimingMode) webgl.timer.markEnd('createSphericalCollocationDensityGrid'); return [3 /*break*/, 3]; case 2: throw new Error('Missing OES_texture_float WebGL extension.'); case 3: grid = (0, data_model_1.createGrid)(cubeGrid, matrix, [0, 1, 2]); if (!params.doNotComputeIsovalues) { isovalues = computeDensityIsocontourValues(matrix, 0.85); } return [2 /*return*/, { grid: grid, isovalues: isovalues }]; } }); }); }); } exports.createSphericalCollocationDensityGrid = createSphericalCollocationDensityGrid; 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++; } } (0, util_1.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, }; } exports.computeDensityIsocontourValues = computeDensityIsocontourValues;