UNPKG

molstar

Version:

A comprehensive macromolecular library.

298 lines (297 loc) 14 kB
"use strict"; /** * Copyright (c) 2018-2019 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.QueryList = exports.AtomSiteTestRestParams = exports.AtomSiteSchemaElement = exports.CommonQueryParamsInfo = exports.QueryParamType = void 0; exports.getQueryByName = getQueryByName; exports.normalizeRestQueryParams = normalizeRestQueryParams; exports.normalizeRestCommonParams = normalizeRestCommonParams; const structure_1 = require("../../../mol-model/structure"); const atoms_1 = require("../query/atoms"); const schemas_1 = require("../query/schemas"); const linear_algebra_1 = require("../../../mol-math/linear-algebra"); 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 || (exports.QueryParamType = QueryParamType = {})); exports.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.` } ]; exports.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' } }; const 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' }] }; exports.AtomSiteTestRestParams = (function () { const params = []; for (const k of Object.keys(exports.AtomSiteSchemaElement)) { const p = exports.AtomSiteSchemaElement[k]; p.name = k; params.push(p); } return params; })(); const RadiusParam = { name: 'radius', type: QueryParamType.Float, defaultValue: 5, exampleValues: [5], description: 'Value in Angstroms.', validation(v) { if (v < 1 || v > 10) { throw new Error('Invalid radius for residue interaction query (must be a value between 1 and 10).'); } } }; const AssemblyNameParam = { name: 'assembly_name', type: QueryParamType.String, description: 'Assembly name. If none is provided, crystal symmetry (where available) or deposited model is used.' }; const OmitWaterParam = { name: 'omit_water', type: QueryParamType.Boolean, required: false, defaultValue: false }; function Q(definition) { return definition; } const QueryMap = { 'full': Q({ niceName: 'Full Structure', query: () => structure_1.Queries.generators.all, description: 'The full structure.' }), 'ligand': Q({ niceName: 'Ligand', description: 'Coordinates of the first group satisfying the given criteria.', query: (p, _s, numModels) => { const tests = (0, atoms_1.getAtomsTests)(p.atom_site); const ligands = structure_1.Queries.combinators.merge(tests.map(test => structure_1.Queries.generators.atoms({ ...test, unitTest: ctx => structure_1.StructureProperties.unit.model_num(ctx.element) === numModels[0], groupBy: ctx => structure_1.StructureProperties.residue.key(ctx.element) }))); return structure_1.Queries.filters.first(ligands); }, jsonParams: [AtomSiteTestJsonParam], restParams: exports.AtomSiteTestRestParams }), 'atoms': Q({ niceName: 'Atoms', description: 'Atoms satisfying the given criteria.', query: p => { return structure_1.Queries.combinators.merge((0, atoms_1.getAtomsTests)(p.atom_site).map(test => structure_1.Queries.generators.atoms(test))); }, jsonParams: [AtomSiteTestJsonParam], restParams: exports.AtomSiteTestRestParams }), 'symmetryMates': Q({ niceName: 'Symmetry Mates', description: 'Computes crystal symmetry mates within the specified radius.', query: () => structure_1.Queries.generators.all, structureTransform(p, s) { return structure_1.StructureSymmetry.builderSymmetryMates(s, p.radius).run(); }, jsonParams: [RadiusParam], filter: schemas_1.QuerySchemas.assembly }), 'assembly': Q({ niceName: 'Assembly', description: 'Computes structural assembly.', query: () => structure_1.Queries.generators.all, structureTransform(p, s) { return structure_1.StructureSymmetry.buildAssembly(s, '' + (p.name || '1')).run(); }, jsonParams: [{ name: 'name', type: QueryParamType.String, defaultValue: '1', exampleValues: ['1'], description: 'Assembly name.' }], filter: schemas_1.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(p) { const tests = (0, atoms_1.getAtomsTests)(p.atom_site); const center = structure_1.Queries.combinators.merge(tests.map(test => structure_1.Queries.generators.atoms({ ...test, entityTest: test.entityTest ? ctx => test.entityTest(ctx) && ctx.element.unit.conformation.operator.isIdentity : ctx => ctx.element.unit.conformation.operator.isIdentity }))); return structure_1.Queries.modifiers.includeSurroundings(center, { radius: p.radius !== void 0 ? p.radius : 5, wholeResidues: true }); }, structureTransform(p, s) { if (p.assembly_name) return structure_1.StructureSymmetry.buildAssembly(s, '' + p.assembly_name).run(); return structure_1.StructureSymmetry.builderSymmetryMates(s, p.radius !== void 0 ? p.radius : 5).run(); }, jsonParams: [AtomSiteTestJsonParam, RadiusParam, AssemblyNameParam], restParams: [...exports.AtomSiteTestRestParams, RadiusParam, AssemblyNameParam], filter: schemas_1.QuerySchemas.interaction }), 'residueSurroundings': Q({ niceName: 'Residue Surroundings', description: 'Identifies all residues within the given radius from the source residue.', query(p) { const center = structure_1.Queries.combinators.merge((0, atoms_1.getAtomsTests)(p.atom_site).map(test => structure_1.Queries.generators.atoms(test))); return structure_1.Queries.modifiers.includeSurroundings(center, { radius: p.radius, wholeResidues: true }); }, jsonParams: [AtomSiteTestJsonParam, RadiusParam], restParams: [...exports.AtomSiteTestRestParams, RadiusParam], filter: schemas_1.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(p) { const tests = (0, atoms_1.getAtomsTests)(p.atom_site); const center = structure_1.Queries.combinators.merge(tests.map(test => structure_1.Queries.generators.atoms({ ...test, entityTest: test.entityTest ? ctx => test.entityTest(ctx) && ctx.element.unit.conformation.operator.isIdentity : ctx => ctx.element.unit.conformation.operator.isIdentity }))); return structure_1.Queries.modifiers.surroundingLigands({ query: center, radius: p.radius !== void 0 ? p.radius : 5, includeWater: !p.omit_water }); }, structureTransform(p, s) { if (p.assembly_name) return structure_1.StructureSymmetry.buildAssembly(s, '' + p.assembly_name).run(); return structure_1.StructureSymmetry.builderSymmetryMates(s, p.radius !== void 0 ? p.radius : 5).run(); }, jsonParams: [AtomSiteTestJsonParam, RadiusParam, OmitWaterParam, AssemblyNameParam], restParams: [...exports.AtomSiteTestRestParams, RadiusParam, OmitWaterParam, AssemblyNameParam], filter: schemas_1.QuerySchemas.interaction }), }; function getQueryByName(name) { return QueryMap[name]; } exports.QueryList = (function () { const list = []; for (const k of Object.keys(QueryMap)) 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 (const q of exports.QueryList) { const m = q.definition; m.name = q.name; m.jsonParams = m.jsonParams || []; m.restParams = m.restParams || m.jsonParams; } })(); function _normalizeQueryParams(params, paramList) { const ret = {}; for (const p of paramList) { const key = p.name; const value = params[key]; let el; if (typeof value === 'undefined' || (typeof value !== 'undefined' && value !== null && value['length'] === 0)) { if (p.required) { throw new Error(`The parameter '${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; } function normalizeRestQueryParams(query, params) { // return params; return _normalizeQueryParams(params, query.restParams); } function normalizeRestCommonParams(params) { return { model_nums: params.model_nums ? ('' + params.model_nums).split(',').map(n => n.trim()).filter(n => !!n).map(n => +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(n => n.trim()).map(n => +n) : linear_algebra_1.Mat4.identity(), download: isTrue(params.download) || !!params.filename, filename: params.filename }; } function isTrue(val) { const 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'; } }