UNPKG

molstar

Version:

A comprehensive macromolecular library.

255 lines (254 loc) 14.2 kB
/** * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import { __awaiter, __generator } from "tslib"; import { Column, Table } from '../../mol-data/db'; import { Task } from '../../mol-task'; import { createModels } from './basic/parser'; import { BasicSchema, createBasic } from './basic/schema'; import { ComponentBuilder } from './common/component'; import { EntityBuilder } from './common/entity'; import { CIF } from '../../mol-io/reader/cif'; import { Spacegroup, SpacegroupCell } from '../../mol-math/geometry'; import { Vec3 } from '../../mol-math/linear-algebra'; import { ModelSymmetry } from './property/symmetry'; import { IndexPairBonds } from './property/bonds/index-pair'; import { AtomSiteAnisotrop } from './property/anisotropic'; import { guessElementSymbolString } from './util'; import { cantorPairing } from '../../mol-data/util'; function getSpacegroupNameOrNumber(space_group) { var groupNumber = space_group.it_number.value(0); var groupName = space_group['name_h-m_full'].value(0).replace('-', ' '); if (!space_group.it_number.isDefined) return groupName; if (!space_group['name_h-m_full'].isDefined) return groupNumber; return groupNumber; } function getSymmetry(db) { var cell = db.cell, space_group = db.space_group; var nameOrNumber = getSpacegroupNameOrNumber(space_group); var spaceCell = SpacegroupCell.create(nameOrNumber, Vec3.create(cell.length_a.value(0), cell.length_b.value(0), cell.length_c.value(0)), Vec3.scale(Vec3(), Vec3.create(cell.angle_alpha.value(0), cell.angle_beta.value(0), cell.angle_gamma.value(0)), Math.PI / 180)); return { spacegroup: Spacegroup.create(spaceCell), assemblies: [], isNonStandardCrystalFrame: false, ncsOperators: [] }; } function getModels(db, format, ctx) { var _a; return __awaiter(this, void 0, void 0, function () { var atomCount, MOL, A, seq_id, symmetry, m, _b, fract_x, fract_y, fract_z, x, y, z, v, i, _c, type_symbol, label, typeSymbol, formalCharge, element_symbol, formal_charge, i, ts, n, element_symbol, i, atom_site, name, entityBuilder, componentBuilder, basic, models, first, bondCount, labelIndexMap, label_1, i, il, bond_type, indexA, indexB, order, dist, flag, included, j, _d, atom_site_label_1, atom_site_label_2, valence, distance, i, iA, iB, id, t; return __generator(this, function (_e) { switch (_e.label) { case 0: atomCount = db.atom_site._rowCount; MOL = Column.ofConst('MOL', atomCount, Column.Schema.str); A = Column.ofConst('A', atomCount, Column.Schema.str); seq_id = Column.ofConst(1, atomCount, Column.Schema.int); symmetry = getSymmetry(db); m = symmetry.spacegroup.cell.fromFractional; _b = db.atom_site, fract_x = _b.fract_x, fract_y = _b.fract_y, fract_z = _b.fract_z; x = new Float32Array(atomCount); y = new Float32Array(atomCount); z = new Float32Array(atomCount); v = Vec3(); for (i = 0; i < atomCount; ++i) { Vec3.set(v, fract_x.value(i), fract_y.value(i), fract_z.value(i)); Vec3.transformMat4(v, v, m); x[i] = v[0], y[i] = v[1], z[i] = v[2]; } _c = db.atom_site, type_symbol = _c.type_symbol, label = _c.label; if (type_symbol.isDefined) { element_symbol = new Array(atomCount); formal_charge = new Int8Array(atomCount); for (i = 0; i < atomCount; ++i) { ts = type_symbol.value(i); n = ts.length; if (ts[n - 1] === '+') { element_symbol[i] = ts.substring(0, n - 2); formal_charge[i] = parseInt(ts[n - 2]); } else if (ts[n - 2] === '+') { element_symbol[i] = ts.substring(0, n - 2); formal_charge[i] = parseInt(ts[n - 1]); } else if (ts[n - 1] === '-') { element_symbol[i] = ts.substring(0, n - 2); formal_charge[i] = -parseInt(ts[n - 2]); } else if (ts[n - 2] === '-') { element_symbol[i] = ts.substring(0, n - 2); formal_charge[i] = -parseInt(ts[n - 1]); } else { element_symbol[i] = ts; formal_charge[i] = 0; } } typeSymbol = Column.ofStringArray(element_symbol); formalCharge = Column.ofIntArray(formal_charge); } else { element_symbol = new Array(atomCount); for (i = 0; i < atomCount; ++i) { // TODO can take as is if type_symbol not given? element_symbol[i] = guessElementSymbolString(label.value(i), ''); } typeSymbol = Column.ofStringArray(element_symbol); formalCharge = Column.Undefined(atomCount, Column.Schema.int); } atom_site = Table.ofPartialColumns(BasicSchema.atom_site, { auth_asym_id: A, auth_atom_id: label, auth_comp_id: MOL, auth_seq_id: seq_id, Cartn_x: Column.ofFloatArray(x), Cartn_y: Column.ofFloatArray(y), Cartn_z: Column.ofFloatArray(z), id: Column.range(0, atomCount - 1), label_asym_id: A, label_atom_id: label, label_comp_id: MOL, label_seq_id: seq_id, label_entity_id: Column.ofConst('1', atomCount, Column.Schema.str), occupancy: db.atom_site.occupancy.isDefined ? db.atom_site.occupancy : Column.ofConst(1, atomCount, Column.Schema.float), type_symbol: typeSymbol, pdbx_formal_charge: formalCharge, pdbx_PDB_model_num: Column.ofConst(1, atomCount, Column.Schema.int), B_iso_or_equiv: db.atom_site.u_iso_or_equiv, }, atomCount); name = (db.chemical.name_common.value(0) || db.chemical.name_systematic.value(0) || db.chemical_formula.sum.value(0)); entityBuilder = new EntityBuilder(); entityBuilder.setNames([['MOL', name || 'Unknown Entity']]); entityBuilder.getEntityId('MOL', 0 /* MoleculeType.Unknown */, 'A'); componentBuilder = new ComponentBuilder(seq_id, db.atom_site.type_symbol); componentBuilder.setNames([['MOL', name || 'Unknown Molecule']]); componentBuilder.add('MOL', 0); basic = createBasic({ entity: entityBuilder.getEntityTable(), chem_comp: componentBuilder.getChemCompTable(), atom_site: atom_site }); return [4 /*yield*/, createModels(basic, format, ctx)]; case 1: models = _e.sent(); if (models.frameCount > 0) { first = models.representative; ModelSymmetry.Provider.set(first, symmetry); bondCount = db.geom_bond._rowCount; if (bondCount > 0) { labelIndexMap = {}; label_1 = db.atom_site.label; for (i = 0, il = label_1.rowCount; i < il; ++i) { labelIndexMap[label_1.value(i)] = i; } bond_type = (_a = format.data.frame.categories.ccdc_geom_bond_type) === null || _a === void 0 ? void 0 : _a.getField(''); indexA = []; indexB = []; order = []; dist = []; flag = []; included = new Set(); j = 0; _d = db.geom_bond, atom_site_label_1 = _d.atom_site_label_1, atom_site_label_2 = _d.atom_site_label_2, valence = _d.valence, distance = _d.distance; for (i = 0; i < bondCount; ++i) { iA = labelIndexMap[atom_site_label_1.value(i)]; iB = labelIndexMap[atom_site_label_2.value(i)]; id = iA < iB ? cantorPairing(iA, iB) : cantorPairing(iB, iA); if (included.has(id)) continue; included.add(id); indexA[j] = iA; indexB[j] = iB; dist[j] = distance.value(i) || -1; if (bond_type) { t = bond_type.str(i); if (t === 'D') { order[j] = 2; flag[j] = 1 /* BondType.Flag.Covalent */; } else if (t === 'A') { order[j] = 1; flag[j] = 1 /* BondType.Flag.Covalent */ | 16 /* BondType.Flag.Aromatic */; } else if (t === 'S') { order[j] = 1; flag[j] = 1 /* BondType.Flag.Covalent */; } else { order[j] = 1; flag[j] = 1 /* BondType.Flag.Covalent */; } } else { flag[j] = 1 /* BondType.Flag.Covalent */; // TODO derive order from bond length if undefined order[j] = valence.isDefined ? valence.value(i) : 1; } j += 1; } IndexPairBonds.Provider.set(first, IndexPairBonds.fromData({ pairs: { indexA: Column.ofIntArray(indexA), indexB: Column.ofIntArray(indexB), order: Column.ofIntArray(order), distance: Column.ofFloatArray(dist), flag: Column.ofIntArray(flag) }, count: atomCount })); } } return [2 /*return*/, models]; } }); }); } function atomSiteAnisotropFromCifCore(model) { if (!CifCoreFormat.is(model.sourceData)) return; var _a = model.sourceData.data.db, atom_site = _a.atom_site, atom_site_aniso = _a.atom_site_aniso; var data = Table.ofPartialColumns(AtomSiteAnisotrop.Schema, { U: atom_site_aniso.u, }, atom_site_aniso._rowCount); var elementToAnsiotrop = AtomSiteAnisotrop.getElementToAnsiotropFromLabel(atom_site.label, atom_site_aniso.label); return { data: data, elementToAnsiotrop: elementToAnsiotrop }; } function atomSiteAnisotropApplicableCifCore(model) { if (!CifCoreFormat.is(model.sourceData)) return false; return model.sourceData.data.db.atom_site_aniso.u.isDefined; } AtomSiteAnisotrop.Provider.formatRegistry.add('cifCore', atomSiteAnisotropFromCifCore, atomSiteAnisotropApplicableCifCore); // export { CifCoreFormat }; var CifCoreFormat; (function (CifCoreFormat) { function is(x) { return (x === null || x === void 0 ? void 0 : x.kind) === 'cifCore'; } CifCoreFormat.is = is; function fromFrame(frame, db) { if (!db) db = CIF.schema.cifCore(frame); var name = (db.database_code.depnum_ccdc_archive.value(0) || db.database_code.depnum_ccdc_fiz.value(0) || db.database_code.icsd.value(0) || db.database_code.mdf.value(0) || db.database_code.nbs.value(0) || db.database_code.csd.value(0) || db.database_code.cod.value(0) || db._name); return { kind: 'cifCore', name: name, data: { db: db, frame: frame } }; } CifCoreFormat.fromFrame = fromFrame; })(CifCoreFormat || (CifCoreFormat = {})); export function trajectoryFromCifCore(frame) { var format = CifCoreFormat.fromFrame(frame); return Task.create('Parse CIF Core', function (ctx) { return getModels(format.data.db, format, ctx); }); }