molstar
Version:
A comprehensive macromolecular library.
83 lines (82 loc) • 3.85 kB
JavaScript
"use strict";
/**
* Copyright (c) 2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeContacts = computeContacts;
const interactions_1 = require("../../mol-model-props/computed/interactions/interactions");
const structure_1 = require("../../mol-model/structure");
const assets_1 = require("../../mol-util/assets");
const model_1 = require("./model");
async function computeContacts(ctx, selection, options) {
var _a, _b;
const unitIdToStructureRef = new Map();
const unitIdToContactGroupId = new Map();
const units = [];
let contactGroupId = 0;
const builder = structure_1.Structure.Builder();
for (const { structureRef, loci } of selection) {
const s = structure_1.StructureElement.Loci.toStructure(loci);
for (const unit of s.units) {
const newUnit = builder.copyUnit(unit, { propagateTransientCache: true });
units.push(newUnit);
unitIdToStructureRef.set(newUnit.id, structureRef);
unitIdToContactGroupId.set(newUnit.id, contactGroupId);
}
contactGroupId++;
}
const structure = builder.getStructure();
const interactions = await (0, interactions_1.computeInteractions)({ runtime: ctx, assetManager: new assets_1.AssetManager() }, structure, (_a = options === null || options === void 0 ? void 0 : options.interactions) !== null && _a !== void 0 ? _a : {}, {
skipIntraContacts: true,
unitPairTest: (a, b) => unitIdToContactGroupId.get(a.id) !== unitIdToContactGroupId.get(b.id)
});
const { edges } = interactions.contacts;
const result = { kind: 'structure-interactions', elements: [] };
for (const e of edges) {
if (e.unitA > e.unitB)
continue;
const [a, aType] = processFeature(structure, interactions, e.unitA, e.indexA);
const [b] = processFeature(structure, interactions, e.unitB, e.indexB);
const kind = (_b = model_1.InteractionTypeToKind[e.props.type]) !== null && _b !== void 0 ? _b : 'unknown';
const info = { kind };
if (kind === 'hydrogen-bond' || kind === 'weak-hydrogen-bond') {
const isADonor = aType === 4 /* FeatureType.HydrogenDonor */ || aType === 9 /* FeatureType.WeakHydrogenDonor */;
result.elements.push({
info,
aStructureRef: isADonor ? unitIdToStructureRef.get(e.unitA) : unitIdToStructureRef.get(e.unitB),
bStructureRef: isADonor ? unitIdToStructureRef.get(e.unitB) : unitIdToStructureRef.get(e.unitA),
a: isADonor ? a : b,
b: isADonor ? b : a,
});
}
else {
result.elements.push({
info,
aStructureRef: unitIdToStructureRef.get(e.unitA),
bStructureRef: unitIdToStructureRef.get(e.unitB),
a,
b,
});
}
}
return result;
}
const _loc = structure_1.StructureElement.Location.create();
function processFeature(structure, interactions, unitId, featureIndex) {
_loc.structure = structure;
_loc.unit = structure.unitMap.get(unitId);
const xs = interactions.unitsFeatures.get(unitId);
let type = 0 /* FeatureType.None */;
const builder = structure.subsetBuilder(false);
builder.beginUnit(_loc.unit.id);
for (let o = xs.offsets[featureIndex], uIEnd = xs.offsets[featureIndex + 1]; o < uIEnd; o++) {
const unitIndex = xs.members[o];
_loc.element = _loc.unit.elements[unitIndex];
builder.addElement(_loc.element);
type = xs.types[o];
}
builder.commitUnit();
return [structure_1.Structure.toStructureElementLoci(builder.getStructure()), type];
}