molstar
Version:
A comprehensive macromolecular library.
175 lines (174 loc) • 10.1 kB
JavaScript
"use strict";
/**
* Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.RootStructureDefinition = void 0;
const structure_1 = require("../../mol-model/structure");
const string_1 = require("../../mol-util/string");
const geometry_1 = require("../../mol-math/geometry");
const param_definition_1 = require("../../mol-util/param-definition");
const linear_algebra_1 = require("../../mol-math/linear-algebra");
const symmetry_1 = require("../../mol-model/structure/model/properties/symmetry");
const objects_1 = require("../objects");
const symmetry_2 = require("../../mol-model-formats/structure/property/symmetry");
const type_helpers_1 = require("../../mol-util/type-helpers");
const CommonStructureParams = {
dynamicBonds: param_definition_1.ParamDefinition.Optional(param_definition_1.ParamDefinition.Boolean(false, { description: 'Ensure bonds are recalculated upon model changes. Also enables calculation of inter-unit bonds in water molecules and ions.' })),
};
var RootStructureDefinition;
(function (RootStructureDefinition) {
function getParams(model, defaultValue) {
const symmetry = model && symmetry_2.ModelSymmetry.Provider.get(model);
const assemblyIds = symmetry ? symmetry.assemblies.map(a => [a.id, `${a.id}: ${(0, string_1.stringToWords)(a.details)}`]) : [];
const showSymm = !symmetry ? true : !geometry_1.SpacegroupCell.isZero(symmetry.spacegroup.cell);
const operatorOptions = [];
if (symmetry) {
const { operators } = symmetry.spacegroup;
for (let i = 0, il = operators.length; i < il; i++) {
operatorOptions.push([i, `${i + 1}: ${geometry_1.Spacegroup.getOperatorXyz(operators[i])}`]);
}
}
const asymIdsOptions = [];
if (model) {
model.properties.structAsymMap.forEach(v => {
const label = v.id === v.auth_id ? v.id : `${v.id} [auth ${v.auth_id}]`;
asymIdsOptions.push([v.id, label]);
});
}
const modes = {
auto: param_definition_1.ParamDefinition.Group(CommonStructureParams),
model: param_definition_1.ParamDefinition.Group(CommonStructureParams),
assembly: param_definition_1.ParamDefinition.Group({
id: param_definition_1.ParamDefinition.Optional(model
? param_definition_1.ParamDefinition.Select(assemblyIds.length ? assemblyIds[0][0] : '', assemblyIds, { label: 'Asm Id', description: 'Assembly Id' })
: param_definition_1.ParamDefinition.Text('', { label: 'Asm Id', description: 'Assembly Id (use empty for the 1st assembly)' })),
...CommonStructureParams
}, { isFlat: true }),
'symmetry-mates': param_definition_1.ParamDefinition.Group({
radius: param_definition_1.ParamDefinition.Numeric(5, { min: 0, max: 50, step: 1 }),
...CommonStructureParams
}, { isFlat: true }),
'symmetry': param_definition_1.ParamDefinition.Group({
ijkMin: param_definition_1.ParamDefinition.Vec3(linear_algebra_1.Vec3.create(-1, -1, -1), { step: 1 }, { label: 'Min IJK', fieldLabels: { x: 'I', y: 'J', z: 'K' } }),
ijkMax: param_definition_1.ParamDefinition.Vec3(linear_algebra_1.Vec3.create(1, 1, 1), { step: 1 }, { label: 'Max IJK', fieldLabels: { x: 'I', y: 'J', z: 'K' } }),
...CommonStructureParams
}, { isFlat: true }),
'symmetry-assembly': param_definition_1.ParamDefinition.Group({
generators: param_definition_1.ParamDefinition.ObjectList({
operators: param_definition_1.ParamDefinition.ObjectList({
index: param_definition_1.ParamDefinition.Select(0, operatorOptions),
shift: param_definition_1.ParamDefinition.Vec3((0, linear_algebra_1.Vec3)(), { step: 1 }, { label: 'IJK', fieldLabels: { x: 'I', y: 'J', z: 'K' } })
}, e => `${e.index + 1}_${e.shift.map(a => a + 5).join('')}`, {
defaultValue: []
}),
asymIds: param_definition_1.ParamDefinition.MultiSelect([], asymIdsOptions)
}, e => `${e.asymIds.length} asym ids, ${e.operators.length} operators`, {
defaultValue: []
}),
...CommonStructureParams
}, { isFlat: true })
};
const options = [];
if (defaultValue === 'auto') {
options.push(['auto', 'Auto']);
}
options.push(['model', 'Model']);
if (assemblyIds.length > 0) {
options.push(['assembly', 'Assembly']);
}
if (showSymm) {
options.push(['symmetry-mates', 'Symmetry Mates']);
options.push(['symmetry', 'Symmetry (indices)']);
options.push(['symmetry-assembly', 'Symmetry (assembly)']);
}
return {
type: param_definition_1.ParamDefinition.MappedStatic(defaultValue || 'model', modes, { options })
};
}
RootStructureDefinition.getParams = getParams;
function canAutoUpdate(oldParams, newParams) {
if (newParams.name === 'symmetry-assembly' || (newParams.name === 'symmetry' && oldParams.name === 'symmetry'))
return false;
return true;
}
RootStructureDefinition.canAutoUpdate = canAutoUpdate;
async function buildAssembly(plugin, ctx, model, id, props) {
let asm = void 0;
const symmetry = symmetry_2.ModelSymmetry.Provider.get(model);
// if no id is specified, use the 1st assembly.
if (!id && symmetry && symmetry.assemblies.length !== 0) {
id = symmetry.assemblies[0].id;
}
if (!symmetry || symmetry.assemblies.length === 0) {
plugin.log.warn(`Model '${model.entryId}' has no assembly, returning model structure.`);
}
else {
asm = symmetry_1.Symmetry.findAssembly(model, id || '');
if (!asm) {
plugin.log.warn(`Model '${model.entryId}' has no assembly called '${id}', returning model structure.`);
}
}
const base = structure_1.Structure.ofModel(model, props);
if (!asm) {
const label = { label: 'Model', description: structure_1.Structure.elementDescription(base) };
return new objects_1.PluginStateObject.Molecule.Structure(base, label);
}
id = asm.id;
const s = await structure_1.StructureSymmetry.buildAssembly(base, id).runInContext(ctx);
const objProps = { label: `Assembly ${id}`, description: structure_1.Structure.elementDescription(s) };
return new objects_1.PluginStateObject.Molecule.Structure(s, objProps);
}
async function buildSymmetry(ctx, model, ijkMin, ijkMax, props) {
const base = structure_1.Structure.ofModel(model, props);
const s = await structure_1.StructureSymmetry.buildSymmetryRange(base, ijkMin, ijkMax).runInContext(ctx);
const objProps = { label: `Symmetry [${ijkMin}] to [${ijkMax}]`, description: structure_1.Structure.elementDescription(s) };
return new objects_1.PluginStateObject.Molecule.Structure(s, objProps);
}
async function buildSymmetryMates(ctx, model, radius, props) {
const base = structure_1.Structure.ofModel(model, props);
const s = await structure_1.StructureSymmetry.builderSymmetryMates(base, radius).runInContext(ctx);
const objProps = { label: `Symmetry Mates`, description: structure_1.Structure.elementDescription(s) };
return new objects_1.PluginStateObject.Molecule.Structure(s, objProps);
}
async function buildSymmetryAssembly(ctx, model, generators, symmetry, props) {
const base = structure_1.Structure.ofModel(model, props);
const s = await structure_1.StructureSymmetry.buildSymmetryAssembly(base, generators, symmetry).runInContext(ctx);
const objProps = { label: `Symmetry Assembly`, description: structure_1.Structure.elementDescription(s) };
return new objects_1.PluginStateObject.Molecule.Structure(s, objProps);
}
async function create(plugin, ctx, model, params) {
const props = params === null || params === void 0 ? void 0 : params.params;
const symmetry = symmetry_2.ModelSymmetry.Provider.get(model);
if (!symmetry || !params || params.name === 'model') {
const s = structure_1.Structure.ofModel(model, props);
return new objects_1.PluginStateObject.Molecule.Structure(s, { label: 'Model', description: structure_1.Structure.elementDescription(s) });
}
if (params.name === 'auto') {
if (symmetry.assemblies.length === 0) {
const s = structure_1.Structure.ofModel(model, props);
return new objects_1.PluginStateObject.Molecule.Structure(s, { label: 'Model', description: structure_1.Structure.elementDescription(s) });
}
else {
return buildAssembly(plugin, ctx, model, undefined, props);
}
}
if (params.name === 'assembly') {
return buildAssembly(plugin, ctx, model, params.params.id, props);
}
if (params.name === 'symmetry') {
return buildSymmetry(ctx, model, params.params.ijkMin, params.params.ijkMax, props);
}
if (params.name === 'symmetry-mates') {
return buildSymmetryMates(ctx, model, params.params.radius, props);
}
if (params.name === 'symmetry-assembly') {
return buildSymmetryAssembly(ctx, model, params.params.generators, symmetry, props);
}
(0, type_helpers_1.assertUnreachable)(params);
}
RootStructureDefinition.create = create;
})(RootStructureDefinition || (exports.RootStructureDefinition = RootStructureDefinition = {}));