UNPKG

molstar

Version:

A comprehensive macromolecular library.

120 lines (119 loc) 4.52 kB
/** * Copyright (c) 2025 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> */ import { Column } from '../../../../mol-data/db'; import { CifWriter } from '../../../../mol-io/writer/cif'; import { BondType } from '../../model/types'; import { StructureElement, StructureProperties, Unit } from '../../structure'; import { sortedCantorPairing } from '../../../../mol-data/util'; export function molstar_bond_site(ctx) { const entries = getEntries(ctx); if (entries.length === 0) return; return [Category, entries, { ignoreFilter: true }]; } export const MolstarBondSiteSchema = { molstar_bond_site: { atom_id_1: Column.Schema.int, atom_id_2: Column.Schema.int, value_order: Column.Schema.Aliased(Column.Schema.lstr), type_id: Column.Schema.Aliased(Column.Schema.lstr), } }; const Fields = CifWriter.fields() .int('atom_id_1', (i, xs) => xs[i].atom_id_1) .int('atom_id_2', (i, xs) => xs[i].atom_id_2) .str('value_order', (i, xs) => { var _a; return (_a = xs[i].value_order) !== null && _a !== void 0 ? _a : ''; }, { valueKind: (i, xs) => xs[i].value_order === undefined ? 1 /* Column.ValueKinds.NotPresent */ : 0 /* Column.ValueKinds.Present */, }) .str('type_id', (i, xs) => { var _a; return (_a = xs[i].type_id) !== null && _a !== void 0 ? _a : ''; }, { valueKind: (i, xs) => xs[i].type_id === undefined ? 1 /* Column.ValueKinds.NotPresent */ : 0 /* Column.ValueKinds.Present */, }) .getFields(); const Category = { name: 'molstar_bond_site', instance(entries) { return { fields: Fields, source: [{ data: entries, rowCount: entries.length }] }; } }; function assignValueOrder(order, flags, out) { out[0] = undefined; out[1] = undefined; if (order === 1) out[0] = 'sing'; else if (order === 2) out[0] = 'doub'; else if (order === 3) out[0] = 'trip'; else if (order === 4) out[0] = 'quad'; if (BondType.is(flags, 16 /* BondType.Flag.Aromatic */)) out[0] = 'arom'; if (BondType.is(flags, 8 /* BondType.Flag.Disulfide */)) out[1] = 'disulf'; else if (BondType.is(flags, 1 /* BondType.Flag.Covalent */)) out[1] = 'covale'; else if (BondType.is(flags, 2 /* BondType.Flag.MetallicCoordination */)) out[1] = 'metalc'; else if (BondType.is(flags, 4 /* BondType.Flag.HydrogenBond */)) out[1] = 'hydrog'; } function getEntries(ctx) { const entries = []; const added = new Set(); const loc = StructureElement.Location.create(); const { id: atom_id } = StructureProperties.atom; const info = [undefined, undefined]; const add = (a, b) => { const key = sortedCantorPairing(a, b); if (added.has(key)) return; added.add(key); if (a > b) { entries.push({ atom_id_1: b, atom_id_2: a, value_order: info[0], type_id: info[1] }); } else { entries.push({ atom_id_1: a, atom_id_2: b, value_order: info[0], type_id: info[1] }); } }; for (const s of ctx.structures) { loc.structure = s; for (const u of s.units) { if (!Unit.isAtomic(u)) continue; const { elements } = u; const { a, b, edgeProps } = u.bonds; loc.unit = u; for (let i = 0; i < a.length; i++) { loc.element = elements[a[i]]; const atom_id_1 = atom_id(loc); loc.element = elements[b[i]]; const atom_id_2 = atom_id(loc); assignValueOrder(edgeProps.order[i], edgeProps.flags[i], info); add(atom_id_1, atom_id_2); } } s.interUnitBonds.edges.forEach((e) => { let u = s.unitMap.get(e.unitA); loc.unit = u; loc.element = u.elements[e.indexA]; const atom_id_1 = atom_id(loc); u = s.unitMap.get(e.unitB); loc.unit = u; loc.element = u.elements[e.indexB]; const atom_id_2 = atom_id(loc); assignValueOrder(e.props.order, e.props.flag, info); add(atom_id_1, atom_id_2); }); } entries.sort((a, b) => { if (a.atom_id_1 !== b.atom_id_1) return a.atom_id_1 - b.atom_id_1; if (a.atom_id_2 !== b.atom_id_2) return a.atom_id_2 - b.atom_id_2; return 0; }); return entries; }