UNPKG

molstar

Version:

A comprehensive macromolecular library.

287 lines (286 loc) 13 kB
"use strict"; /** * Copyright (c) 2017-2025 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> * @author Sebastian Bittrich <sebastian.bittrich@rcsb.org> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.CCDFormat = exports.MmcifFormat = void 0; exports.trajectoryFromMmCIF = trajectoryFromMmCIF; exports.trajectoryFromCCD = trajectoryFromCCD; const model_1 = require("../../mol-model/structure/model/model"); const mol_task_1 = require("../../mol-task"); const cif_1 = require("../../mol-io/reader/cif"); const parser_1 = require("./basic/parser"); const symmetry_1 = require("./property/symmetry"); const secondary_structure_1 = require("./property/secondary-structure"); const db_1 = require("../../mol-data/db"); const anisotropic_1 = require("./property/anisotropic"); const chem_comp_1 = require("./property/bonds/chem_comp"); const struct_conn_1 = require("./property/bonds/struct_conn"); const structure_1 = require("../../mol-model/structure"); const global_transform_1 = require("../../mol-model/structure/model/properties/global-transform"); const schema_1 = require("./basic/schema"); const entity_1 = require("./common/entity"); const types_1 = require("../../mol-model/structure/model/types"); const component_1 = require("./common/component"); const util_1 = require("../../mol-data/util"); const index_pair_1 = require("./property/bonds/index-pair"); const schema_2 = require("../../mol-io/reader/cif/schema"); const molstar_bond_site_1 = require("../../mol-model/structure/export/categories/molstar_bond_site"); function modelSymmetryFromMmcif(model) { if (!MmcifFormat.is(model.sourceData)) return; return symmetry_1.ModelSymmetry.fromData(model.sourceData.data.db); } symmetry_1.ModelSymmetry.Provider.formatRegistry.add('mmCIF', modelSymmetryFromMmcif); function secondaryStructureFromMmcif(model) { if (!MmcifFormat.is(model.sourceData)) return; const { struct_conf, struct_sheet_range } = model.sourceData.data.db; return secondary_structure_1.ModelSecondaryStructure.fromStruct(struct_conf, struct_sheet_range, model.atomicHierarchy); } secondary_structure_1.ModelSecondaryStructure.Provider.formatRegistry.add('mmCIF', secondaryStructureFromMmcif); function atomSiteAnisotropFromMmcif(model) { if (!MmcifFormat.is(model.sourceData)) return; const { atom_site_anisotrop } = model.sourceData.data.db; const data = db_1.Table.ofColumns(anisotropic_1.AtomSiteAnisotrop.Schema, atom_site_anisotrop); const elementToAnsiotrop = anisotropic_1.AtomSiteAnisotrop.getElementToAnsiotrop(model.atomicConformation.atomId, atom_site_anisotrop.id); return { data, elementToAnsiotrop }; } function atomSiteAnisotropApplicableMmcif(model) { if (!MmcifFormat.is(model.sourceData)) return false; return model.sourceData.data.db.atom_site_anisotrop.U.isDefined; } anisotropic_1.AtomSiteAnisotrop.Provider.formatRegistry.add('mmCIF', atomSiteAnisotropFromMmcif, atomSiteAnisotropApplicableMmcif); function componentBondFromMmcif(model) { if (!MmcifFormat.is(model.sourceData)) return; const { chem_comp_bond } = model.sourceData.data.db; if (chem_comp_bond._rowCount === 0) return; return { data: chem_comp_bond, entries: chem_comp_1.ComponentBond.getEntriesFromChemCompBond(chem_comp_bond) }; } chem_comp_1.ComponentBond.Provider.formatRegistry.add('mmCIF', componentBondFromMmcif); function structConnFromMmcif(model) { if (!MmcifFormat.is(model.sourceData)) return; const { struct_conn } = model.sourceData.data.db; if (struct_conn._rowCount === 0) return; const entries = struct_conn_1.StructConn.getEntriesFromStructConn(struct_conn, model); const residueCantorPairs = new Set(); for (const e of entries) { if (e.partnerA.residueIndex !== e.partnerB.residueIndex) { residueCantorPairs.add((0, util_1.sortedCantorPairing)(e.partnerA.residueIndex, e.partnerB.residueIndex)); } } return { data: struct_conn, byAtomIndex: struct_conn_1.StructConn.getAtomIndexFromEntries(entries), residueCantorPairs, entries, }; } struct_conn_1.StructConn.Provider.formatRegistry.add('mmCIF', structConnFromMmcif); function indexPairBondsFromMolstarBondSite(model) { if (!MmcifFormat.is(model.sourceData)) return; const { molstar_bond_site: entries } = (0, schema_2.toDatabase)(molstar_bond_site_1.MolstarBondSiteSchema, model.sourceData.data.frame); if (entries._rowCount === 0) return; const idToIndex = new Map(); const { atomId } = model.atomicConformation; for (let i = 0; i < atomId.rowCount; i++) { idToIndex.set(atomId.value(i), i); } const indexA = []; const indexB = []; const orders = []; const flags = []; const { atom_id_1, atom_id_2, value_order, type_id } = entries; for (let i = 0; i < entries._rowCount; i++) { indexA.push(idToIndex.get(atom_id_1.value(i))); indexB.push(idToIndex.get(atom_id_2.value(i))); let flag = types_1.BondType.Flag.None; let order = 1; switch (value_order.value(i)) { case 'sing': order = 1; break; case 'doub': order = 2; break; case 'trip': order = 3; break; case 'quad': order = 4; break; case 'arom': order = 1; flag = types_1.BondType.Flag.Aromatic; break; default: break; } switch (type_id.value(i)) { case 'covale': flag |= types_1.BondType.Flag.Covalent; break; case 'disulf': flag |= types_1.BondType.Flag.Covalent | types_1.BondType.Flag.Disulfide; break; case 'hydrog': flag |= types_1.BondType.Flag.HydrogenBond; break; case 'metalc': flag |= types_1.BondType.Flag.MetallicCoordination; break; } orders.push(order); flags.push(flag); } const pairBonds = index_pair_1.IndexPairBonds.fromData({ pairs: { indexA: db_1.Column.ofIntArray(indexA), indexB: db_1.Column.ofIntArray(indexB), order: db_1.Column.ofIntArray(orders), flag: db_1.Column.ofArray({ array: flags, schema: db_1.Column.Schema.int }), }, count: model.atomicHierarchy.atoms._rowCount, }, { maxDistance: Infinity }); return pairBonds; } index_pair_1.IndexPairBonds.Provider.formatRegistry.add('mmCIF', indexPairBondsFromMolstarBondSite); global_transform_1.GlobalModelTransformInfo.Provider.formatRegistry.add('mmCIF', global_transform_1.GlobalModelTransformInfo.fromMmCif, global_transform_1.GlobalModelTransformInfo.hasData); var MmcifFormat; (function (MmcifFormat) { function is(x) { return (x === null || x === void 0 ? void 0 : x.kind) === 'mmCIF'; } MmcifFormat.is = is; function fromFrame(frame, db, source, file) { if (!db) db = cif_1.CIF.schema.mmCIF(frame); return { kind: 'mmCIF', name: db._name, data: { db, file, frame, source } }; } MmcifFormat.fromFrame = fromFrame; })(MmcifFormat || (exports.MmcifFormat = MmcifFormat = {})); function trajectoryFromMmCIF(frame, file) { const format = MmcifFormat.fromFrame(frame, undefined, undefined, file); const basic = (0, schema_1.createBasic)(format.data.db, true); return mol_task_1.Task.create('Create mmCIF Model', ctx => (0, parser_1.createModels)(basic, format, ctx)); } var CCDFormat; (function (CCDFormat) { const CoordinateTypeProp = '__CcdCoordinateType__'; CCDFormat.CoordinateType = { get(model) { return model._staticPropertyData[CoordinateTypeProp]; }, set(model, type) { return model._staticPropertyData[CoordinateTypeProp] = type; } }; function is(x) { return (x === null || x === void 0 ? void 0 : x.kind) === 'CCD'; } CCDFormat.is = is; function fromFrame(frame, db) { if (!db) db = cif_1.CIF.schema.CCD(frame); return { kind: 'CCD', name: db._name, data: { db, frame } }; } CCDFormat.fromFrame = fromFrame; })(CCDFormat || (exports.CCDFormat = CCDFormat = {})); function trajectoryFromCCD(frame) { const format = CCDFormat.fromFrame(frame); return mol_task_1.Task.create('Create CCD Models', ctx => createCcdModels(format.data.db, CCDFormat.fromFrame(frame), ctx)); } async function createCcdModels(data, format, ctx) { const ideal = await createCcdModel(data, format, { coordinateType: 'ideal', cartn_x: 'pdbx_model_Cartn_x_ideal', cartn_y: 'pdbx_model_Cartn_y_ideal', cartn_z: 'pdbx_model_Cartn_z_ideal' }, ctx); const model = await createCcdModel(data, format, { coordinateType: 'model', cartn_x: 'model_Cartn_x', cartn_y: 'model_Cartn_y', cartn_z: 'model_Cartn_z' }, ctx); const models = []; if (ideal) models.push(ideal); if (model) models.push(model); for (let i = 0, il = models.length; i < il; ++i) { model_1.Model.TrajectoryInfo.set(models[i], { index: i, size: models.length }); } return new structure_1.ArrayTrajectory(models); } async function createCcdModel(data, format, props, ctx) { const { chem_comp, chem_comp_atom, chem_comp_bond } = data; const { coordinateType, cartn_x, cartn_y, cartn_z } = props; const name = chem_comp.name.value(0); const id = chem_comp.id.value(0); const { atom_id, charge, comp_id, pdbx_ordinal, type_symbol } = chem_comp_atom; const atomCount = chem_comp_atom._rowCount; const filteredRows = []; for (let i = 0; i < atomCount; i++) { if (chem_comp_atom[cartn_x].valueKind(i) > 0) continue; filteredRows[filteredRows.length] = i; } const filteredRowCount = filteredRows.length; const A = db_1.Column.ofConst('A', filteredRowCount, db_1.Column.Schema.str); const seq_id = db_1.Column.ofConst(1, filteredRowCount, db_1.Column.Schema.int); const entity_id = db_1.Column.ofConst('1', filteredRowCount, db_1.Column.Schema.str); const occupancy = db_1.Column.ofConst(1, filteredRowCount, db_1.Column.Schema.float); const model_num = db_1.Column.ofConst(1, filteredRowCount, db_1.Column.Schema.int); const filteredAtomId = db_1.Column.view(atom_id, filteredRows); const filteredCompId = db_1.Column.view(comp_id, filteredRows); const filteredX = db_1.Column.view(chem_comp_atom[cartn_x], filteredRows); const filteredY = db_1.Column.view(chem_comp_atom[cartn_y], filteredRows); const filteredZ = db_1.Column.view(chem_comp_atom[cartn_z], filteredRows); const filteredId = db_1.Column.view(pdbx_ordinal, filteredRows); const filteredTypeSymbol = db_1.Column.view(type_symbol, filteredRows); const filteredCharge = db_1.Column.view(charge, filteredRows); const model_atom_site = db_1.Table.ofPartialColumns(schema_1.BasicSchema.atom_site, { auth_asym_id: A, auth_atom_id: filteredAtomId, auth_comp_id: filteredCompId, auth_seq_id: seq_id, Cartn_x: filteredX, Cartn_y: filteredY, Cartn_z: filteredZ, id: filteredId, label_asym_id: A, label_atom_id: filteredAtomId, label_comp_id: filteredCompId, label_seq_id: seq_id, label_entity_id: entity_id, occupancy, type_symbol: filteredTypeSymbol, pdbx_PDB_model_num: model_num, pdbx_formal_charge: filteredCharge }, filteredRowCount); const entityBuilder = new entity_1.EntityBuilder(); entityBuilder.setNames([[id, `${name} (${coordinateType})`]]); entityBuilder.getEntityId(id, types_1.MoleculeType.Unknown, 'A'); const componentBuilder = new component_1.ComponentBuilder(seq_id, type_symbol); componentBuilder.setNames([[id, `${name} (${coordinateType})`]]); componentBuilder.add(id, 0); const basicModel = (0, schema_1.createBasic)({ entity: entityBuilder.getEntityTable(), chem_comp: componentBuilder.getChemCompTable(), atom_site: model_atom_site }); const models = await (0, parser_1.createModels)(basicModel, format, ctx); // all ideal or model coordinates might be absent if (!models.representative) return; const first = models.representative; const entries = chem_comp_1.ComponentBond.getEntriesFromChemCompBond(chem_comp_bond); chem_comp_1.ComponentBond.Provider.set(first, { data: chem_comp_bond, entries }); CCDFormat.CoordinateType.set(first, coordinateType); return models.representative; }