molstar
Version:
A comprehensive macromolecular library.
120 lines (119 loc) • 4.52 kB
JavaScript
/**
* 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;
}