UNPKG

molstar

Version:

A comprehensive macromolecular library.

124 lines (123 loc) 4.91 kB
"use strict"; /** * Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * Inspired by https://github.com/dgasmith/gau2grid. * * @author David Sehnal <david.sehnal@gmail.com> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.computeOrbitalIsocontourValues = exports.createSphericalCollocationGrid = 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 collocation_1 = require("./collocation"); var data_model_1 = require("./data-model"); var compute_1 = require("./gpu/compute"); function createSphericalCollocationGrid(params, orbital, 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('createSphericalCollocationGrid'); return [4 /*yield*/, (0, compute_1.gpuComputeAlphaOrbitalsGridValues)(ctx, webgl, cubeGrid, orbital)]; case 1: matrix = _a.sent(); if (debug_1.isTimingMode) webgl.timer.markEnd('createSphericalCollocationGrid'); return [3 /*break*/, 4]; case 2: return [4 /*yield*/, (0, collocation_1.sphericalCollocation)(cubeGrid, orbital, ctx)]; case 3: // console.time('cpu'); matrix = _a.sent(); _a.label = 4; case 4: grid = (0, data_model_1.createGrid)(cubeGrid, matrix, [0, 1, 2]); if (!params.doNotComputeIsovalues) { isovalues = computeOrbitalIsocontourValues(matrix, 0.85); } return [2 /*return*/, { grid: grid, isovalues: isovalues }]; } }); }); }); } exports.createSphericalCollocationGrid = createSphericalCollocationGrid; function computeOrbitalIsocontourValues(input, cumulativeThreshold) { var weightSum = 0; for (var i = 0, _i = input.length; i < _i; i++) { var v = input[i]; var w = v * 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 = v * 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 = v * 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.computeOrbitalIsocontourValues = computeOrbitalIsocontourValues;