UNPKG

molstar

Version:

A comprehensive macromolecular library.

217 lines (216 loc) 9.99 kB
"use strict"; /** * Copyright (c) 2017-2022 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.createModels = createModels; const db_1 = require("../../../mol-data/db"); const uuid_1 = require("../../../mol-util/uuid"); const model_1 = require("../../../mol-model/structure/model/model"); const custom_property_1 = require("../../../mol-model/custom-property"); const atomic_1 = require("./atomic"); const coarse_1 = require("./coarse"); const sequence_1 = require("./sequence"); const sort_1 = require("./sort"); const atomic_ranges_1 = require("../../../mol-model/structure/model/properties/utils/atomic-ranges"); const properties_1 = require("./properties"); const entities_1 = require("./entities"); const util_1 = require("./util"); const trajectory_1 = require("../../../mol-model/structure/trajectory"); async function createModels(data, format, ctx) { const properties = getCommonProperties(data, format); const models = data.ihm_model_list._rowCount > 0 ? await readIntegrative(ctx, data, properties, format) : await readStandard(ctx, data, properties, format); for (let i = 0; i < models.length; i++) { model_1.Model.TrajectoryInfo.set(models[i], { index: i, size: models.length }); } return new trajectory_1.ArrayTrajectory(models); } function getCommonProperties(data, format) { return { missingResidues: (0, properties_1.getMissingResidues)(data), chemicalComponentMap: (0, properties_1.getChemicalComponentMap)(data), saccharideComponentMap: (0, properties_1.getSaccharideComponentMap)(data) }; } /** Standard atomic model */ function createStandardModel(data, atom_site, sourceIndex, entities, properties, format, previous) { const atomic = (0, atomic_1.getAtomicHierarchyAndConformation)(atom_site, sourceIndex, entities, properties.chemicalComponentMap, format, previous); const modelNum = atom_site.pdbx_PDB_model_num.value(0); if (previous && atomic.sameAsPrevious) { return { ...previous, id: uuid_1.UUID.create22(), modelNum, atomicConformation: atomic.conformation, _dynamicPropertyData: Object.create(null) }; } const coarse = coarse_1.EmptyCoarse; const sequence = (0, sequence_1.getSequence)(data, entities, atomic.hierarchy, coarse.hierarchy); const atomicRanges = (0, atomic_ranges_1.getAtomicRanges)(atomic.hierarchy, entities, atomic.conformation, sequence); const structAsymMap = (0, properties_1.getStructAsymMap)(atomic.hierarchy); const entry = data.entry.id.valueKind(0) === db_1.Column.ValueKinds.Present ? data.entry.id.value(0) : format.name; const label = []; if (entry) label.push(entry); if (data.struct.title.valueKind(0) === db_1.Column.ValueKinds.Present) label.push(data.struct.title.value(0)); return { id: uuid_1.UUID.create22(), entryId: entry, label: label.join(' | '), entry, sourceData: format, modelNum, parent: undefined, entities: (0, entities_1.getEntitiesWithPRD)(data, entities, structAsymMap), sequence, atomicHierarchy: atomic.hierarchy, atomicConformation: atomic.conformation, atomicRanges, atomicChainOperatorMappinng: atomic.chainOperatorMapping, coarseHierarchy: coarse.hierarchy, coarseConformation: coarse.conformation, properties: { ...properties, structAsymMap }, customProperties: new custom_property_1.CustomProperties(), _staticPropertyData: Object.create(null), _dynamicPropertyData: Object.create(null) }; } /** Integrative model with atomic/coarse parts */ function createIntegrativeModel(data, ihm, properties, format) { const atomic = (0, atomic_1.getAtomicHierarchyAndConformation)(ihm.atom_site, ihm.atom_site_sourceIndex, ihm.entities, properties.chemicalComponentMap, format); const coarse = (0, coarse_1.getCoarse)(ihm, properties.chemicalComponentMap); const sequence = (0, sequence_1.getSequence)(data, ihm.entities, atomic.hierarchy, coarse.hierarchy); const atomicRanges = (0, atomic_ranges_1.getAtomicRanges)(atomic.hierarchy, ihm.entities, atomic.conformation, sequence); const entry = data.entry.id.valueKind(0) === db_1.Column.ValueKinds.Present ? data.entry.id.value(0) : format.name; const label = []; if (entry) label.push(entry); if (data.struct.title.valueKind(0) === db_1.Column.ValueKinds.Present) label.push(data.struct.title.value(0)); if (ihm.model_name) label.push(ihm.model_name); if (ihm.model_group_name) label.push(ihm.model_group_name); const structAsymMap = (0, properties_1.getStructAsymMap)(atomic.hierarchy, data); return { id: uuid_1.UUID.create22(), entryId: entry, label: label.join(' | '), entry, sourceData: format, modelNum: ihm.model_id, parent: undefined, entities: (0, entities_1.getEntitiesWithPRD)(data, ihm.entities, structAsymMap), sequence, atomicHierarchy: atomic.hierarchy, atomicConformation: atomic.conformation, atomicRanges, atomicChainOperatorMappinng: atomic.chainOperatorMapping, coarseHierarchy: coarse.hierarchy, coarseConformation: coarse.conformation, properties: { ...properties, structAsymMap }, customProperties: new custom_property_1.CustomProperties(), _staticPropertyData: Object.create(null), _dynamicPropertyData: Object.create(null) }; } function findModelEnd(num, startIndex) { const rowCount = num.rowCount; if (!num.isDefined) return rowCount; let endIndex = startIndex + 1; while (endIndex < rowCount && num.areValuesEqual(startIndex, endIndex)) endIndex++; return endIndex; } async function readStandard(ctx, data, properties, format) { const models = []; if (data.atom_site) { const atomCount = data.atom_site.id.rowCount; const entities = (0, entities_1.getEntityData)(data); let modelStart = 0; while (modelStart < atomCount) { const modelEnd = findModelEnd(data.atom_site.pdbx_PDB_model_num, modelStart); const { atom_site, sourceIndex } = await (0, sort_1.sortAtomSite)(ctx, data.atom_site, modelStart, modelEnd); const model = createStandardModel(data, atom_site, sourceIndex, entities, properties, format, models.length > 0 ? models[models.length - 1] : void 0); models.push(model); modelStart = modelEnd; } } return models; } function splitTable(table, col) { const ret = new Map(); const rowCount = table._rowCount; let modelStart = 0; while (modelStart < rowCount) { const modelEnd = findModelEnd(col, modelStart); const id = col.value(modelStart); ret.set(id, { table: db_1.Table.window(table, table._schema, modelStart, modelEnd), start: modelStart, end: modelEnd }); modelStart = modelEnd; } return ret; } async function readIntegrative(ctx, data, properties, format) { const entities = (0, entities_1.getEntityData)(data); // when `atom_site.ihm_model_id` is undefined fall back to `atom_site.pdbx_PDB_model_num` const atom_sites_modelColumn = data.atom_site.ihm_model_id.isDefined ? data.atom_site.ihm_model_id : data.atom_site.pdbx_PDB_model_num; const atom_sites = splitTable(data.atom_site, atom_sites_modelColumn); // TODO: will coarse IHM records require sorting or will we trust it? // ==> Probably implement a sort as as well and store the sourceIndex same as with atomSite // If the sorting is implemented, updated mol-model/structure/properties: atom.sourceIndex const sphere_sites = splitTable(data.ihm_sphere_obj_site, data.ihm_sphere_obj_site.model_id); const gauss_sites = splitTable(data.ihm_gaussian_obj_site, data.ihm_gaussian_obj_site.model_id); const models = []; if (data.ihm_model_list) { const { model_id, model_name } = data.ihm_model_list; for (let i = 0; i < data.ihm_model_list._rowCount; i++) { const id = model_id.value(i); let atom_site, atom_site_sourceIndex; if (atom_sites.has(id)) { const e = atom_sites.get(id); // need to sort `data.atom_site` as `e.start` and `e.end` are indices into that const { atom_site: sorted, sourceIndex } = await (0, sort_1.sortAtomSite)(ctx, data.atom_site, e.start, e.end); atom_site = sorted; atom_site_sourceIndex = sourceIndex; } else { atom_site = db_1.Table.window(data.atom_site, data.atom_site._schema, 0, 0); atom_site_sourceIndex = db_1.Column.ofIntArray([]); } const ihm = { model_id: id, model_name: model_name.value(i), model_group_name: (0, util_1.getModelGroupName)(id, data), entities, atom_site, atom_site_sourceIndex, ihm_sphere_obj_site: sphere_sites.has(id) ? sphere_sites.get(id).table : db_1.Table.window(data.ihm_sphere_obj_site, data.ihm_sphere_obj_site._schema, 0, 0), ihm_gaussian_obj_site: gauss_sites.has(id) ? gauss_sites.get(id).table : db_1.Table.window(data.ihm_gaussian_obj_site, data.ihm_gaussian_obj_site._schema, 0, 0) }; const model = createIntegrativeModel(data, ihm, properties, format); models.push(model); } } return models; }