molstar
Version:
A comprehensive macromolecular library.
152 lines • 6.69 kB
JavaScript
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { __assign } from "tslib";
import { createGrid3dComputeRenderable } from '../../../mol-gl/compute/grid3d';
import { TextureSpec, UniformSpec } from '../../../mol-gl/renderable/schema';
import { ValueCell } from '../../../mol-util';
import { arrayMin } from '../../../mol-util/array';
import { normalizeBasicOrder } from '../spherical-functions';
import { MAIN, UTILS } from './shader.frag';
var Schema = {
tCenters: TextureSpec('image-float32', 'rgba', 'float', 'nearest'),
tInfo: TextureSpec('image-float32', 'rgba', 'float', 'nearest'),
tCoeff: TextureSpec('image-float32', 'rgb', 'float', 'nearest'),
tAlpha: TextureSpec('image-float32', 'alpha', 'float', 'nearest'),
uNCenters: UniformSpec('i'),
uNAlpha: UniformSpec('i'),
uNCoeff: UniformSpec('i'),
uMaxCoeffs: UniformSpec('i'),
};
var Orbitals = createGrid3dComputeRenderable({
schema: Schema,
loopBounds: ['uNCenters', 'uMaxCoeffs'],
mainCode: MAIN,
utilCode: UTILS,
returnCode: 'v',
values: function (params) {
return createTextureData(params.grid, params.orbital);
}
});
var Density = createGrid3dComputeRenderable({
schema: __assign(__assign({}, Schema), { uOccupancy: UniformSpec('f') }),
loopBounds: ['uNCenters', 'uMaxCoeffs'],
mainCode: MAIN,
utilCode: UTILS,
returnCode: 'current + uOccupancy * v * v',
values: function (params) {
return __assign(__assign({}, createTextureData(params.grid, params.orbitals[0])), { uOccupancy: 0 });
},
cumulative: {
states: function (params) {
return params.orbitals.filter(function (o) { return o.occupancy !== 0; });
},
update: function (_a, state, values) {
var grid = _a.grid;
var alpha = getNormalizedAlpha(grid.params.basis, state.alpha, grid.params.sphericalOrder);
ValueCell.updateIfChanged(values.uOccupancy, state.occupancy);
ValueCell.update(values.tAlpha, { width: alpha.length, height: 1, array: alpha });
}
}
});
export function gpuComputeAlphaOrbitalsGridValues(ctx, webgl, grid, orbital) {
return Orbitals(ctx, webgl, grid, { grid: grid, orbital: orbital });
}
export function gpuComputeAlphaOrbitalsDensityGridValues(ctx, webgl, grid, orbitals) {
return Density(ctx, webgl, grid, { grid: grid, orbitals: orbitals });
}
function getNormalizedAlpha(basis, alphaOrbitals, sphericalOrder) {
var alpha = new Float32Array(alphaOrbitals.length);
var aO = 0;
for (var _i = 0, _a = basis.atoms; _i < _a.length; _i++) {
var atom = _a[_i];
for (var _b = 0, _c = atom.shells; _b < _c.length; _b++) {
var shell = _c[_b];
for (var _d = 0, _e = shell.angularMomentum; _d < _e.length; _d++) {
var L = _e[_d];
var a0 = normalizeBasicOrder(L, alphaOrbitals.slice(aO, aO + 2 * L + 1), sphericalOrder);
for (var i = 0; i < a0.length; i++)
alpha[aO + i] = a0[i];
aO += 2 * L + 1;
}
}
}
return alpha;
}
function createTextureData(grid, orbital) {
var _a = grid.params, basis = _a.basis, sphericalOrder = _a.sphericalOrder, cutoffThreshold = _a.cutoffThreshold;
var centerCount = 0;
var baseCount = 0;
var coeffCount = 0;
for (var _i = 0, _b = basis.atoms; _i < _b.length; _i++) {
var atom = _b[_i];
for (var _c = 0, _d = atom.shells; _c < _d.length; _c++) {
var shell = _d[_c];
for (var _e = 0, _f = shell.angularMomentum; _e < _f.length; _e++) {
var L = _f[_e];
if (L > 4) {
// TODO: will L > 4 be required? Would need to precompute more functions in that case.
throw new Error('Angular momentum L > 4 not supported.');
}
centerCount++;
baseCount += 2 * L + 1;
coeffCount += shell.exponents.length;
}
}
}
var centers = new Float32Array(4 * centerCount);
// L, alpha_offset, coeff_offset_start, coeff_offset_end
var info = new Float32Array(4 * centerCount);
var alpha = new Float32Array(baseCount);
var coeff = new Float32Array(3 * coeffCount);
var maxCoeffs = 0;
var cO = 0, aO = 0, coeffO = 0;
for (var _g = 0, _h = basis.atoms; _g < _h.length; _g++) {
var atom = _h[_g];
for (var _j = 0, _k = atom.shells; _j < _k.length; _j++) {
var shell = _k[_j];
var amIndex = 0;
for (var _l = 0, _m = shell.angularMomentum; _l < _m.length; _l++) {
var L = _m[_l];
var a0 = normalizeBasicOrder(L, orbital.alpha.slice(aO, aO + 2 * L + 1), sphericalOrder);
var cutoffRadius = cutoffThreshold > 0
? Math.sqrt(-Math.log(cutoffThreshold) / arrayMin(shell.exponents))
: 10000;
centers[4 * cO + 0] = atom.center[0];
centers[4 * cO + 1] = atom.center[1];
centers[4 * cO + 2] = atom.center[2];
centers[4 * cO + 3] = cutoffRadius * cutoffRadius;
info[4 * cO + 0] = L;
info[4 * cO + 1] = aO;
info[4 * cO + 2] = coeffO;
info[4 * cO + 3] = coeffO + shell.exponents.length;
for (var i = 0; i < a0.length; i++)
alpha[aO + i] = a0[i];
var c0 = shell.coefficients[amIndex++];
for (var i = 0; i < shell.exponents.length; i++) {
coeff[3 * (coeffO + i) + 0] = c0[i];
coeff[3 * (coeffO + i) + 1] = shell.exponents[i];
}
if (c0.length > maxCoeffs) {
maxCoeffs = c0.length;
}
cO++;
aO += 2 * L + 1;
coeffO += shell.exponents.length;
}
}
}
return {
uNCenters: centerCount,
uNAlpha: baseCount,
uNCoeff: coeffCount,
uMaxCoeffs: maxCoeffs,
tCenters: { width: centerCount, height: 1, array: centers },
tInfo: { width: centerCount, height: 1, array: info },
tCoeff: { width: coeffCount, height: 1, array: coeff },
tAlpha: { width: baseCount, height: 1, array: alpha },
};
}
//# sourceMappingURL=compute.js.map