UNPKG

molstar

Version:

A comprehensive macromolecular library.

377 lines 19.4 kB
"use strict"; /** * Copyright (c) 2018-2020 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.abortingObserver = exports.resolveJob = void 0; var tslib_1 = require("tslib"); var path = (0, tslib_1.__importStar)(require("path")); var cif_1 = require("../../../mol-io/writer/cif"); var structure_1 = require("../../../mol-model/structure"); var mmcif_1 = require("../../../mol-model/structure/export/mmcif"); var console_logger_1 = require("../../../mol-util/console-logger"); var now_1 = require("../../../mol-util/now"); var performance_monitor_1 = require("../../../mol-util/performance-monitor"); var config_1 = require("../config"); var property_provider_1 = require("../property-provider"); var version_1 = require("../version"); var structure_wrapper_1 = require("./structure-wrapper"); var CifField = cif_1.CifWriter.Field; var string_1 = require("../../../mol-util/string"); var chem_comp_1 = require("../../../mol-model-formats/structure/property/bonds/chem_comp"); var sdf_1 = require("../../../mol-io/writer/sdf"); var mol_1 = require("../../../mol-io/writer/mol"); var mol2_1 = require("../../../mol-io/writer/mol2"); var encoder_1 = require("../../../mol-io/writer/mol/encoder"); var encoder_2 = require("../../../mol-io/writer/mol2/encoder"); var chem_comp_2 = require("../../../mol-model-formats/structure/property/atoms/chem_comp"); var linear_algebra_1 = require("../../../mol-math/linear-algebra"); var global_transform_1 = require("../../../mol-model/structure/model/properties/global-transform"); var perf = new performance_monitor_1.PerformanceMonitor(); var _propertyProvider; function propertyProvider() { if (_propertyProvider) return _propertyProvider; _propertyProvider = (0, property_provider_1.createModelPropertiesProviderFromConfig)() || (function () { return []; }); return _propertyProvider; } function resolveJob(job) { return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { return (0, tslib_1.__generator)(this, function (_a) { if (job.responseFormat.tarball) { return [2 /*return*/, resolveMultiFile(job)]; } else { return [2 /*return*/, resolveSingleFile(job)]; } return [2 /*return*/]; }); }); } exports.resolveJob = resolveJob; var SharedParams = { encoderName: "ModelServer " + version_1.VERSION }; var SharedLigandWritingParams = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, SharedParams), { hydrogens: true }); function createEncoder(job) { switch (job.responseFormat.encoding) { case 'bcif': return cif_1.CifWriter.createEncoder((0, tslib_1.__assign)((0, tslib_1.__assign)({}, SharedParams), { binary: true, binaryAutoClassifyEncoding: true })); case 'sdf': ensureCompatibleQueryType(job); return sdf_1.SdfWriter.createEncoder((0, tslib_1.__assign)({}, SharedLigandWritingParams)); case 'mol': ensureCompatibleQueryType(job); return mol_1.MolWriter.createEncoder((0, tslib_1.__assign)({}, SharedLigandWritingParams)); case 'mol2': ensureCompatibleQueryType(job); return mol2_1.Mol2Writer.createEncoder((0, tslib_1.__assign)({}, SharedLigandWritingParams)); default: return cif_1.CifWriter.createEncoder((0, tslib_1.__assign)((0, tslib_1.__assign)({}, SharedParams), { binary: false, binaryAutoClassifyEncoding: true })); } } function ensureCompatibleQueryType(job) { job.entries.forEach(function (e) { if (e.queryDefinition.niceName !== 'Ligand') { throw Error("sdf, mol and mol2 encoding are only available for queries of type 'Ligand'"); } }); } function resolveSingleFile(job) { return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { var encoder, headerMap, _i, _a, entry, hasDataBlock, structure, header, i, e_1; return (0, tslib_1.__generator)(this, function (_b) { switch (_b.label) { case 0: console_logger_1.ConsoleLogger.logId(job.id, 'Query', "Starting (format: " + job.responseFormat.encoding + ")."); encoder = createEncoder(job); headerMap = new Map(); _i = 0, _a = job.entries; _b.label = 1; case 1: if (!(_i < _a.length)) return [3 /*break*/, 7]; entry = _a[_i]; hasDataBlock = false; _b.label = 2; case 2: _b.trys.push([2, 5, , 6]); return [4 /*yield*/, (0, structure_wrapper_1.createStructureWrapperFromJobEntry)(entry, propertyProvider())]; case 3: structure = _b.sent(); header = structure.cifFrame.header.toUpperCase(); if (headerMap.has(header)) { i = headerMap.get(header) + 1; headerMap.set(header, i); header += ' ' + i; } else { headerMap.set(header, 0); } encoder.startDataBlock(header); hasDataBlock = true; return [4 /*yield*/, resolveJobEntry(entry, structure, encoder)]; case 4: _b.sent(); return [3 /*break*/, 6]; case 5: e_1 = _b.sent(); if (job.entries.length === 1) { throw e_1; } else { if (!hasDataBlock) { createErrorDataBlock(entry, encoder); } doError(entry, encoder, e_1); console_logger_1.ConsoleLogger.errorId(entry.job.id, '' + e_1); } return [3 /*break*/, 6]; case 6: _i++; return [3 /*break*/, 1]; case 7: console_logger_1.ConsoleLogger.logId(job.id, 'Query', 'Encoding.'); encoder.encode(); encoder.writeTo(job.writer); return [2 /*return*/]; } }); }); } function getFilename(i, entry, header, encoding) { return i + "_" + header.toLowerCase() + "_" + (0, string_1.splitCamelCase)(entry.queryDefinition.name.replace(/\s/g, '_'), '-').toLowerCase() + "." + encoding; } function resolveMultiFile(job) { return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { var i, _i, _a, entry, encoder, hasDataBlock, header, structure, e_2; return (0, tslib_1.__generator)(this, function (_b) { switch (_b.label) { case 0: console_logger_1.ConsoleLogger.logId(job.id, 'Query', 'Starting.'); i = 0; _i = 0, _a = job.entries; _b.label = 1; case 1: if (!(_i < _a.length)) return [3 /*break*/, 8]; entry = _a[_i]; encoder = createEncoder(job); hasDataBlock = false; header = ''; _b.label = 2; case 2: _b.trys.push([2, 5, , 6]); return [4 /*yield*/, (0, structure_wrapper_1.createStructureWrapperFromJobEntry)(entry, propertyProvider())]; case 3: structure = _b.sent(); header = structure.cifFrame.header; encoder.startDataBlock(structure.cifFrame.header); hasDataBlock = true; return [4 /*yield*/, resolveJobEntry(entry, structure, encoder)]; case 4: _b.sent(); return [3 /*break*/, 6]; case 5: e_2 = _b.sent(); if (!hasDataBlock) { header = createErrorDataBlock(entry, encoder); } console_logger_1.ConsoleLogger.errorId(entry.job.id, '' + e_2); doError(entry, encoder, e_2); return [3 /*break*/, 6]; case 6: console_logger_1.ConsoleLogger.logId(job.id, 'Query', "Encoding " + entry.key + "/" + entry.queryDefinition.name); encoder.encode(); job.writer.beginEntry(getFilename(++i, entry, header, job.responseFormat.encoding), encoder.getSize()); encoder.writeTo(job.writer); job.writer.endEntry(); console_logger_1.ConsoleLogger.logId(job.id, 'Query', "Written " + entry.key + "/" + entry.queryDefinition.name); _b.label = 7; case 7: _i++; return [3 /*break*/, 1]; case 8: return [2 /*return*/]; } }); }); } function createErrorDataBlock(job, encoder) { var header; if (job.sourceId === '_local_') header = path.basename(job.entryId).replace(/[^a-z0-9\-]/gi, '').toUpperCase(); else header = job.entryId.replace(/[^a-z0-9\-]/gi, '').toUpperCase(); encoder.startDataBlock(header); return header; } function resolveJobEntry(entry, structure, encoder) { return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { var sourceStructures, structures, _i, sourceStructures_1, s, _a, _b, modelNums_1, queries, result, i, s, stats, e_3; return (0, tslib_1.__generator)(this, function (_c) { switch (_c.label) { case 0: console_logger_1.ConsoleLogger.logId(entry.job.id, 'Query', "Start " + entry.key + "/" + entry.queryDefinition.name + "."); _c.label = 1; case 1: _c.trys.push([1, 7, 8, 9]); perf.start('query'); return [4 /*yield*/, (0, structure_wrapper_1.resolveStructures)(structure, entry.modelNums)]; case 2: sourceStructures = _c.sent(); if (!sourceStructures.length) throw new Error('Model not available'); structures = sourceStructures; if (!entry.queryDefinition.structureTransform) return [3 /*break*/, 6]; structures = []; _i = 0, sourceStructures_1 = sourceStructures; _c.label = 3; case 3: if (!(_i < sourceStructures_1.length)) return [3 /*break*/, 6]; s = sourceStructures_1[_i]; _b = (_a = structures).push; return [4 /*yield*/, entry.queryDefinition.structureTransform(entry.normalizedParams, s)]; case 4: _b.apply(_a, [_c.sent()]); _c.label = 5; case 5: _i++; return [3 /*break*/, 3]; case 6: modelNums_1 = entry.modelNums || structure.models.map(function (m) { return m.modelNum; }); queries = structures.map(function (s) { return entry.queryDefinition.query(entry.normalizedParams, s, modelNums_1); }); result = []; for (i = 0; i < structures.length; i++) { s = structure_1.StructureSelection.unionStructure(structure_1.StructureQuery.run(queries[i], structures[i], { timeoutMs: config_1.ModelServerConfig.queryTimeoutMs })); if (s.elementCount > 0) { if (!entry.transform || linear_algebra_1.Mat4.isIdentity(entry.transform)) { result.push(s); } else { result.push(structure_1.Structure.transform(s, entry.transform)); } } } perf.end('query'); console_logger_1.ConsoleLogger.logId(entry.job.id, 'Query', "Queried " + entry.key + "/" + entry.queryDefinition.name + "."); perf.start('encode'); encoder.binaryEncodingProvider = getEncodingProvider(structure); // TODO: this actually needs to "reversible" in case of error. encoder.writeCategory(_model_server_result, entry); encoder.writeCategory(_model_server_params, entry); if (entry.queryDefinition.niceName === 'Ligand') { if (encoder instanceof encoder_1.MolEncoder) { encoder.setComponentAtomData(chem_comp_2.ComponentAtom.Provider.get(structure.models[0])); } if (encoder instanceof encoder_1.MolEncoder || encoder instanceof encoder_2.Mol2Encoder) { encoder.setComponentBondData(chem_comp_1.ComponentBond.Provider.get(structure.models[0])); } } // TODO propagate data for cif/bcif as well? if (!entry.copyAllCategories && entry.queryDefinition.filter) encoder.setFilter(entry.queryDefinition.filter); if (result.length > 0) (0, mmcif_1.encode_mmCIF_categories)(encoder, result, { copyAllCategories: entry.copyAllCategories }); else console_logger_1.ConsoleLogger.logId(entry.job.id, 'Warning', "Empty result for Query " + entry.key + "/" + entry.queryDefinition.name); if (entry.transform && !linear_algebra_1.Mat4.isIdentity(entry.transform)) global_transform_1.GlobalModelTransformInfo.writeMmCif(encoder, entry.transform); if (!entry.copyAllCategories && entry.queryDefinition.filter) encoder.setFilter(); perf.end('encode'); stats = { structure: structure, queryTimeMs: perf.time('query'), encodeTimeMs: perf.time('encode'), resultSize: result.reduce(function (n, s) { return n + s.elementCount; }, 0) }; encoder.writeCategory(_model_server_stats, stats); console_logger_1.ConsoleLogger.logId(entry.job.id, 'Query', "Written " + entry.key + "/" + entry.queryDefinition.name + "."); return [2 /*return*/, encoder]; case 7: e_3 = _c.sent(); console_logger_1.ConsoleLogger.errorId(entry.job.id, e_3); doError(entry, encoder, e_3); return [3 /*break*/, 9]; case 8: encoder.binaryEncodingProvider = void 0; return [7 /*endfinally*/]; case 9: return [2 /*return*/]; } }); }); } function getEncodingProvider(structure) { if (!structure.isBinary) return void 0; return cif_1.CifWriter.createEncodingProviderFromCifFrame(structure.cifFrame); } function doError(entry, encoder, e) { encoder.writeCategory(_model_server_result, entry); encoder.writeCategory(_model_server_params, entry); encoder.writeCategory(_model_server_error, '' + e); } var maxTime = config_1.ModelServerConfig.queryTimeoutMs; function abortingObserver(p) { if ((0, now_1.now)() - p.root.progress.startedTime > maxTime) { p.requestAbort("Exceeded maximum allowed time for a query (" + maxTime + "ms)"); } } exports.abortingObserver = abortingObserver; function string(name, str, isSpecified) { if (isSpecified) { return CifField.str(name, function (i, d) { return str(d, i); }, { valueKind: function (i, d) { return isSpecified(d) ? 0 /* Present */ : 1 /* NotPresent */; } }); } return CifField.str(name, function (i, d) { return str(d, i); }); } function int32(name, value) { return CifField.int(name, function (i, d) { return value(d); }); } var _model_server_result_fields = [ string('job_id', function (ctx) { return '' + ctx.job.id; }), string('datetime_utc', function (ctx) { return ctx.job.datetime_utc; }), string('server_version', function (ctx) { return version_1.VERSION; }), string('query_name', function (ctx) { return ctx.queryDefinition.name; }), string('source_id', function (ctx) { return ctx.sourceId; }), string('entry_id', function (ctx) { return ctx.entryId; }), ]; var _model_server_params_fields = [ string('name', function (ctx, i) { return ctx[i][0]; }), string('value', function (ctx, i) { return ctx[i][1]; }) ]; var _model_server_error_fields = [ string('message', function (ctx, i) { return ctx; }) ]; var _model_server_stats_fields = [ int32('io_time_ms', function (ctx) { return ctx.structure.info.readTime | 0; }), int32('parse_time_ms', function (ctx) { return ctx.structure.info.parseTime | 0; }), // int32<Stats>('attach_props_time_ms', ctx => ctx.structure.info.attachPropsTime | 0), int32('create_model_time_ms', function (ctx) { return ctx.structure.info.createModelTime | 0; }), int32('query_time_ms', function (ctx) { return ctx.queryTimeMs | 0; }), int32('encode_time_ms', function (ctx) { return ctx.encodeTimeMs | 0; }), int32('element_count', function (ctx) { return ctx.resultSize | 0; }), ]; var _model_server_result = { name: 'model_server_result', instance: function (job) { return cif_1.CifWriter.categoryInstance(_model_server_result_fields, { data: job, rowCount: 1 }); } }; var _model_server_error = { name: 'model_server_error', instance: function (message) { return cif_1.CifWriter.categoryInstance(_model_server_error_fields, { data: message, rowCount: 1 }); } }; var _model_server_params = { name: 'model_server_params', instance: function (job) { var params = []; for (var _i = 0, _a = Object.keys(job.normalizedParams); _i < _a.length; _i++) { var k = _a[_i]; params.push([k, JSON.stringify(job.normalizedParams[k])]); } return cif_1.CifWriter.categoryInstance(_model_server_params_fields, { data: params, rowCount: params.length }); } }; var _model_server_stats = { name: 'model_server_stats', instance: function (stats) { return cif_1.CifWriter.categoryInstance(_model_server_stats_fields, { data: stats, rowCount: 1 }); } }; //# sourceMappingURL=query.js.map