molstar
Version:
A comprehensive macromolecular library.
288 lines (287 loc) • 14.2 kB
JavaScript
/**
* Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { __assign, __spreadArray } from "tslib";
import { Queries, StructureSymmetry, StructureProperties } from '../../../mol-model/structure';
import { getAtomsTests } from '../query/atoms';
import { QuerySchemas } from '../query/schemas';
import { Mat4 } from '../../../mol-math/linear-algebra';
export var QueryParamType;
(function (QueryParamType) {
QueryParamType[QueryParamType["JSON"] = 0] = "JSON";
QueryParamType[QueryParamType["String"] = 1] = "String";
QueryParamType[QueryParamType["Integer"] = 2] = "Integer";
QueryParamType[QueryParamType["Boolean"] = 3] = "Boolean";
QueryParamType[QueryParamType["Float"] = 4] = "Float";
})(QueryParamType || (QueryParamType = {}));
export var CommonQueryParamsInfo = [
{ name: 'model_nums', type: QueryParamType.String, description: "A comma-separated list of model ids (i.e. 1,2). If set, only include atoms with the corresponding '_atom_site.pdbx_PDB_model_num' field." },
{ name: 'encoding', type: QueryParamType.String, defaultValue: 'cif', description: "Determines the output encoding (text based 'CIF' or binary 'BCIF'). Ligands can also be exported as 'SDF', 'MOL', or 'MOL2'.", supportedValues: ['cif', 'bcif', 'sdf', 'mol', 'mol2'] },
{ name: 'copy_all_categories', type: QueryParamType.Boolean, defaultValue: false, description: 'If true, copy all categories from the input file.' },
{ name: 'data_source', type: QueryParamType.String, defaultValue: '', description: 'Allows to control how the provided data source ID maps to input file (as specified by the server instance config).' },
{ name: 'transform', type: QueryParamType.String, description: "Transformation to apply to coordinates in '_atom_site'. Accepts a 4x4 transformation matrix, provided as array of 16 float values." },
{ name: 'download', type: QueryParamType.Boolean, defaultValue: false, description: 'If true, browser will download text files.' },
{ name: 'filename', type: QueryParamType.String, defaultValue: '', description: "Controls the filename for downloaded files. Will force download if specified." }
];
export var AtomSiteSchemaElement = {
label_entity_id: { type: QueryParamType.String, groupName: 'atom_site' },
label_asym_id: { type: QueryParamType.String, groupName: 'atom_site' },
auth_asym_id: { type: QueryParamType.String, groupName: 'atom_site' },
label_comp_id: { type: QueryParamType.String, groupName: 'atom_site' },
auth_comp_id: { type: QueryParamType.String, groupName: 'atom_site' },
label_seq_id: { type: QueryParamType.Integer, groupName: 'atom_site' },
auth_seq_id: { type: QueryParamType.Integer, groupName: 'atom_site' },
pdbx_PDB_ins_code: { type: QueryParamType.String, groupName: 'atom_site' },
label_atom_id: { type: QueryParamType.String, groupName: 'atom_site' },
auth_atom_id: { type: QueryParamType.String, groupName: 'atom_site' },
type_symbol: { type: QueryParamType.String, groupName: 'atom_site' }
};
var AtomSiteTestJsonParam = {
name: 'atom_site',
type: QueryParamType.JSON,
description: 'Object or array of objects describing atom properties. Names are same as in wwPDB mmCIF dictionary of the atom_site category.',
exampleValues: [[{ label_seq_id: 30, label_asym_id: 'A' }, { label_seq_id: 31, label_asym_id: 'A' }], { label_comp_id: 'ALA' }]
};
export var AtomSiteTestRestParams = (function () {
var params = [];
for (var _i = 0, _a = Object.keys(AtomSiteSchemaElement); _i < _a.length; _i++) {
var k = _a[_i];
var p = AtomSiteSchemaElement[k];
p.name = k;
params.push(p);
}
return params;
})();
var RadiusParam = {
name: 'radius',
type: QueryParamType.Float,
defaultValue: 5,
exampleValues: [5],
description: 'Value in Angstroms.',
validation: function (v) {
if (v < 1 || v > 10) {
throw new Error('Invalid radius for residue interaction query (must be a value between 1 and 10).');
}
}
};
var AssemblyNameParam = {
name: 'assembly_name',
type: QueryParamType.String,
description: 'Assembly name. If none is provided, crystal symmetry (where available) or deposited model is used.'
};
var OmitWaterParam = {
name: 'omit_water',
type: QueryParamType.Boolean,
required: false,
defaultValue: false
};
function Q(definition) {
return definition;
}
var QueryMap = {
'full': Q({ niceName: 'Full Structure', query: function () { return Queries.generators.all; }, description: 'The full structure.' }),
'ligand': Q({
niceName: 'Ligand',
description: 'Coordinates of the first group satisfying the given criteria.',
query: function (p, _s, numModels) {
var tests = getAtomsTests(p.atom_site);
var ligands = Queries.combinators.merge(tests.map(function (test) { return Queries.generators.atoms(__assign(__assign({}, test), { unitTest: function (ctx) { return StructureProperties.unit.model_num(ctx.element) === numModels[0]; }, groupBy: function (ctx) { return StructureProperties.residue.key(ctx.element); } })); }));
return Queries.filters.first(ligands);
},
jsonParams: [AtomSiteTestJsonParam],
restParams: AtomSiteTestRestParams
}),
'atoms': Q({
niceName: 'Atoms',
description: 'Atoms satisfying the given criteria.',
query: function (p) {
return Queries.combinators.merge(getAtomsTests(p.atom_site).map(function (test) { return Queries.generators.atoms(test); }));
},
jsonParams: [AtomSiteTestJsonParam],
restParams: AtomSiteTestRestParams
}),
'symmetryMates': Q({
niceName: 'Symmetry Mates',
description: 'Computes crystal symmetry mates within the specified radius.',
query: function () { return Queries.generators.all; },
structureTransform: function (p, s) {
return StructureSymmetry.builderSymmetryMates(s, p.radius).run();
},
jsonParams: [RadiusParam],
filter: QuerySchemas.assembly
}),
'assembly': Q({
niceName: 'Assembly',
description: 'Computes structural assembly.',
query: function () { return Queries.generators.all; },
structureTransform: function (p, s) {
return StructureSymmetry.buildAssembly(s, '' + (p.name || '1')).run();
},
jsonParams: [{
name: 'name',
type: QueryParamType.String,
defaultValue: '1',
exampleValues: ['1'],
description: 'Assembly name.'
}],
filter: QuerySchemas.assembly
}),
'residueInteraction': Q({
niceName: 'Residue Interaction',
description: 'Identifies all residues within the given radius from the source residue. Takes crystal symmetry into account.',
query: function (p) {
var tests = getAtomsTests(p.atom_site);
var center = Queries.combinators.merge(tests.map(function (test) { return Queries.generators.atoms(__assign(__assign({}, test), { entityTest: test.entityTest
? function (ctx) { return test.entityTest(ctx) && ctx.element.unit.conformation.operator.isIdentity; }
: function (ctx) { return ctx.element.unit.conformation.operator.isIdentity; } })); }));
return Queries.modifiers.includeSurroundings(center, { radius: p.radius !== void 0 ? p.radius : 5, wholeResidues: true });
},
structureTransform: function (p, s) {
if (p.assembly_name)
return StructureSymmetry.buildAssembly(s, '' + p.assembly_name).run();
return StructureSymmetry.builderSymmetryMates(s, p.radius !== void 0 ? p.radius : 5).run();
},
jsonParams: [AtomSiteTestJsonParam, RadiusParam, AssemblyNameParam],
restParams: __spreadArray(__spreadArray([], AtomSiteTestRestParams, true), [RadiusParam, AssemblyNameParam], false),
filter: QuerySchemas.interaction
}),
'residueSurroundings': Q({
niceName: 'Residue Surroundings',
description: 'Identifies all residues within the given radius from the source residue.',
query: function (p) {
var center = Queries.combinators.merge(getAtomsTests(p.atom_site).map(function (test) { return Queries.generators.atoms(test); }));
return Queries.modifiers.includeSurroundings(center, { radius: p.radius, wholeResidues: true });
},
jsonParams: [AtomSiteTestJsonParam, RadiusParam],
restParams: __spreadArray(__spreadArray([], AtomSiteTestRestParams, true), [RadiusParam], false),
filter: QuerySchemas.interaction
}),
'surroundingLigands': Q({
niceName: 'Surrounding Ligands',
description: 'Identifies (complete) ligands within the given radius from the source atom set. Takes crystal symmetry into account.',
query: function (p) {
var tests = getAtomsTests(p.atom_site);
var center = Queries.combinators.merge(tests.map(function (test) { return Queries.generators.atoms(__assign(__assign({}, test), { entityTest: test.entityTest
? function (ctx) { return test.entityTest(ctx) && ctx.element.unit.conformation.operator.isIdentity; }
: function (ctx) { return ctx.element.unit.conformation.operator.isIdentity; } })); }));
return Queries.modifiers.surroundingLigands({ query: center, radius: p.radius !== void 0 ? p.radius : 5, includeWater: !p.omit_water });
},
structureTransform: function (p, s) {
if (p.assembly_name)
return StructureSymmetry.buildAssembly(s, '' + p.assembly_name).run();
return StructureSymmetry.builderSymmetryMates(s, p.radius !== void 0 ? p.radius : 5).run();
},
jsonParams: [AtomSiteTestJsonParam, RadiusParam, OmitWaterParam, AssemblyNameParam],
restParams: __spreadArray(__spreadArray([], AtomSiteTestRestParams, true), [RadiusParam, OmitWaterParam, AssemblyNameParam], false),
filter: QuerySchemas.interaction
}),
};
export function getQueryByName(name) {
return QueryMap[name];
}
export var QueryList = (function () {
var list = [];
for (var _i = 0, _a = Object.keys(QueryMap); _i < _a.length; _i++) {
var k = _a[_i];
list.push({ name: k, definition: QueryMap[k] });
}
list.sort(function (a, b) { return a.name < b.name ? -1 : a.name > b.name ? 1 : 0; });
return list;
})();
// normalize the queries
(function () {
for (var _i = 0, QueryList_1 = QueryList; _i < QueryList_1.length; _i++) {
var q = QueryList_1[_i];
var m = q.definition;
m.name = q.name;
m.jsonParams = m.jsonParams || [];
m.restParams = m.restParams || m.jsonParams;
}
})();
function _normalizeQueryParams(params, paramList) {
var ret = {};
for (var _i = 0, paramList_1 = paramList; _i < paramList_1.length; _i++) {
var p = paramList_1[_i];
var key = p.name;
var value = params[key];
var el = void 0;
if (typeof value === 'undefined' || (typeof value !== 'undefined' && value !== null && value['length'] === 0)) {
if (p.required) {
throw new Error("The parameter '".concat(key, "' is required."));
}
if (typeof p.defaultValue !== 'undefined')
el = p.defaultValue;
}
else {
switch (p.type) {
case QueryParamType.JSON:
el = JSON.parse(value);
break;
case QueryParamType.String:
el = value;
break;
case QueryParamType.Integer:
el = parseInt(value);
break;
case QueryParamType.Float:
el = parseFloat(value);
break;
case QueryParamType.Boolean:
el = Boolean(+value);
break;
}
if (p.validation)
p.validation(el);
}
if (typeof el === 'undefined')
continue;
if (p.groupName) {
if (typeof ret[p.groupName] === 'undefined')
ret[p.groupName] = {};
ret[p.groupName][key] = el;
}
else {
ret[key] = el;
}
}
return ret;
}
export function normalizeRestQueryParams(query, params) {
// return params;
return _normalizeQueryParams(params, query.restParams);
}
export function normalizeRestCommonParams(params) {
return {
model_nums: params.model_nums ? ('' + params.model_nums).split(',').map(function (n) { return n.trim(); }).filter(function (n) { return !!n; }).map(function (n) { return +n; }) : void 0,
data_source: params.data_source,
copy_all_categories: isTrue(params.copy_all_categories),
encoding: mapEncoding(('' + params.encoding).toLocaleLowerCase()),
transform: params.transform ? ('' + params.transform).split(',').map(function (n) { return n.trim(); }).map(function (n) { return +n; }) : Mat4.identity(),
download: isTrue(params.download) || !!params.filename,
filename: params.filename
};
}
function isTrue(val) {
var b = Boolean(val);
if (!b)
return false;
if (typeof val === 'string')
return val !== '0' && val.toLowerCase() !== 'false';
return b;
}
function mapEncoding(value) {
switch (value) {
case 'bcif':
return 'bcif';
case 'mol':
return 'mol';
case 'mol2':
return 'mol2';
case 'sdf':
return 'sdf';
default:
return 'cif';
}
}