molstar
Version:
A comprehensive macromolecular library.
230 lines • 12.4 kB
JavaScript
/**
* Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeInteractions = exports.InteractionsParams = exports.ContactProviderParams = exports.Interactions = void 0;
var tslib_1 = require("tslib");
var param_definition_1 = require("../../../mol-util/param-definition");
var structure_1 = require("../../../mol-model/structure");
var features_1 = require("./features");
var valence_model_1 = require("../valence-model");
var common_1 = require("./common");
var contacts_builder_1 = require("./contacts-builder");
var int_1 = require("../../../mol-data/int");
var contacts_1 = require("./contacts");
var halogen_bonds_1 = require("./halogen-bonds");
var hydrogen_bonds_1 = require("./hydrogen-bonds");
var charged_1 = require("./charged");
var hydrophobic_1 = require("./hydrophobic");
var set_1 = require("../../../mol-util/set");
var metal_1 = require("./metal");
var refine_1 = require("./refine");
var location_1 = require("../../../mol-model/location");
var centroid_helper_1 = require("../../../mol-math/geometry/centroid-helper");
var loci_1 = require("../../../mol-model/loci");
var label_1 = require("../../../mol-theme/label");
var type_helpers_1 = require("../../../mol-util/type-helpers");
var Interactions;
(function (Interactions) {
function Location(interactions, structure, unitA, indexA, unitB, indexB) {
return (0, location_1.DataLocation)('interactions', { structure: structure, interactions: interactions }, { unitA: unitA, indexA: indexA, unitB: unitB, indexB: indexB });
}
Interactions.Location = Location;
function isLocation(x) {
return !!x && x.kind === 'data-location' && x.tag === 'interactions';
}
Interactions.isLocation = isLocation;
function areLocationsEqual(locA, locB) {
return (locA.data.structure === locB.data.structure &&
locA.data.interactions === locB.data.interactions &&
locA.element.indexA === locB.element.indexA &&
locA.element.indexB === locB.element.indexB &&
locA.element.unitA === locB.element.unitA &&
locA.element.unitB === locB.element.unitB);
}
Interactions.areLocationsEqual = areLocationsEqual;
function _label(interactions, element) {
var unitA = element.unitA, indexA = element.indexA, unitB = element.unitB, indexB = element.indexB;
var contacts = interactions.contacts, unitsContacts = interactions.unitsContacts;
if (unitA === unitB) {
var contacts_2 = unitsContacts.get(unitA.id);
var idx = contacts_2.getDirectedEdgeIndex(indexA, indexB);
return (0, common_1.interactionTypeLabel)(contacts_2.edgeProps.type[idx]);
}
else {
var idx = contacts.getEdgeIndex(indexA, unitA.id, indexB, unitB.id);
return (0, common_1.interactionTypeLabel)(contacts.edges[idx].props.type);
}
}
function locationLabel(location) {
return _label(location.data.interactions, location.element);
}
Interactions.locationLabel = locationLabel;
function Loci(structure, interactions, elements) {
return (0, loci_1.DataLoci)('interactions', { structure: structure, interactions: interactions }, elements, function (boundingSphere) { return getBoundingSphere(interactions, elements, boundingSphere); }, function () { return getLabel(structure, interactions, elements); });
}
Interactions.Loci = Loci;
function isLoci(x) {
return !!x && x.kind === 'data-loci' && x.tag === 'interactions';
}
Interactions.isLoci = isLoci;
function getBoundingSphere(interactions, elements, boundingSphere) {
var unitsFeatures = interactions.unitsFeatures;
return centroid_helper_1.CentroidHelper.fromPairProvider(elements.length, function (i, pA, pB) {
var e = elements[i];
features_1.Features.setPosition(pA, e.unitA, e.indexA, unitsFeatures.get(e.unitA.id));
features_1.Features.setPosition(pB, e.unitB, e.indexB, unitsFeatures.get(e.unitB.id));
}, boundingSphere);
}
Interactions.getBoundingSphere = getBoundingSphere;
function getLabel(structure, interactions, elements) {
var element = elements[0];
if (element === undefined)
return '';
var unitA = element.unitA, indexA = element.indexA, unitB = element.unitB, indexB = element.indexB;
var unitsFeatures = interactions.unitsFeatures;
var _a = unitsFeatures.get(unitA.id), mA = _a.members, oA = _a.offsets;
var _b = unitsFeatures.get(unitB.id), mB = _b.members, oB = _b.offsets;
var options = { granularity: 'element' };
if (oA[indexA + 1] - oA[indexA] > 1 || oB[indexB + 1] - oB[indexB] > 1) {
options.granularity = 'residue';
}
return [
_label(interactions, element),
(0, label_1.bondLabel)(structure_1.Bond.Location(structure, unitA, mA[oA[indexA]], structure, unitB, mB[oB[indexB]]), options)
].join('</br>');
}
Interactions.getLabel = getLabel;
})(Interactions || (Interactions = {}));
exports.Interactions = Interactions;
var FeatureProviders = [
hydrogen_bonds_1.HydrogenDonorProvider, hydrogen_bonds_1.WeakHydrogenDonorProvider, hydrogen_bonds_1.HydrogenAcceptorProvider,
charged_1.NegativChargeProvider, charged_1.PositiveChargeProvider, charged_1.AromaticRingProvider,
halogen_bonds_1.HalogenDonorProvider, halogen_bonds_1.HalogenAcceptorProvider,
hydrophobic_1.HydrophobicAtomProvider,
metal_1.MetalProvider, metal_1.MetalBindingProvider,
];
var ContactProviders = {
'ionic': charged_1.IonicProvider,
'pi-stacking': charged_1.PiStackingProvider,
'cation-pi': charged_1.CationPiProvider,
'halogen-bonds': halogen_bonds_1.HalogenBondsProvider,
'hydrogen-bonds': hydrogen_bonds_1.HydrogenBondsProvider,
'weak-hydrogen-bonds': hydrogen_bonds_1.WeakHydrogenBondsProvider,
'hydrophobic': hydrophobic_1.HydrophobicProvider,
'metal-coordination': metal_1.MetalCoordinationProvider,
};
function getProvidersParams(defaultOn) {
if (defaultOn === void 0) { defaultOn = []; }
var params = Object.create(null);
Object.keys(ContactProviders).forEach(function (k) {
params[k] = param_definition_1.ParamDefinition.MappedStatic(defaultOn.includes(k) ? 'on' : 'off', {
on: param_definition_1.ParamDefinition.Group(ContactProviders[k].params),
off: param_definition_1.ParamDefinition.Group({})
}, { cycle: true });
});
return params;
}
exports.ContactProviderParams = getProvidersParams([
// 'ionic',
'cation-pi',
'pi-stacking',
'hydrogen-bonds',
'halogen-bonds',
// 'hydrophobic',
'metal-coordination',
// 'weak-hydrogen-bonds',
]);
exports.InteractionsParams = {
providers: param_definition_1.ParamDefinition.Group(exports.ContactProviderParams, { isFlat: true }),
contacts: param_definition_1.ParamDefinition.Group(contacts_1.ContactsParams, { label: 'Advanced Options' }),
};
function computeInteractions(ctx, structure, props) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var p, contactTesters, requiredFeatures, featureProviders, unitsFeatures, unitsContacts, i, il, group, features, intraUnitContacts, j, jl, u, contacts, interactions;
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
p = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, param_definition_1.ParamDefinition.getDefaultValues(exports.InteractionsParams)), props);
return [4 /*yield*/, valence_model_1.ValenceModelProvider.attach(ctx, structure)];
case 1:
_a.sent();
contactTesters = [];
(0, type_helpers_1.ObjectKeys)(ContactProviders).forEach(function (k) {
var _a = p.providers[k], name = _a.name, params = _a.params;
if (name === 'on') {
contactTesters.push(ContactProviders[k].createTester(params));
}
});
requiredFeatures = new Set();
contactTesters.forEach(function (l) { return set_1.SetUtils.add(requiredFeatures, l.requiredFeatures); });
featureProviders = FeatureProviders.filter(function (f) { return set_1.SetUtils.areIntersecting(requiredFeatures, f.types); });
unitsFeatures = int_1.IntMap.Mutable();
unitsContacts = int_1.IntMap.Mutable();
i = 0, il = structure.unitSymmetryGroups.length;
_a.label = 2;
case 2:
if (!(i < il)) return [3 /*break*/, 6];
group = structure.unitSymmetryGroups[i];
if (!ctx.runtime.shouldUpdate) return [3 /*break*/, 4];
return [4 /*yield*/, ctx.runtime.update({ message: 'computing interactions', current: i, max: il })];
case 3:
_a.sent();
_a.label = 4;
case 4:
features = findUnitFeatures(structure, group.units[0], featureProviders);
intraUnitContacts = findIntraUnitContacts(structure, group.units[0], features, contactTesters, p.contacts);
for (j = 0, jl = group.units.length; j < jl; ++j) {
u = group.units[j];
unitsFeatures.set(u.id, features);
unitsContacts.set(u.id, intraUnitContacts);
}
_a.label = 5;
case 5:
++i;
return [3 /*break*/, 2];
case 6:
contacts = findInterUnitContacts(structure, unitsFeatures, contactTesters, p.contacts);
interactions = { unitsFeatures: unitsFeatures, unitsContacts: unitsContacts, contacts: contacts };
(0, refine_1.refineInteractions)(structure, interactions);
return [2 /*return*/, interactions];
}
});
});
}
exports.computeInteractions = computeInteractions;
function findUnitFeatures(structure, unit, featureProviders) {
var count = unit.elements.length;
var featuresBuilder = features_1.FeaturesBuilder.create(count, count / 2);
if (structure_1.Unit.isAtomic(unit)) {
for (var _i = 0, featureProviders_1 = featureProviders; _i < featureProviders_1.length; _i++) {
var fp = featureProviders_1[_i];
fp.add(structure, unit, featuresBuilder);
}
}
return featuresBuilder.getFeatures(count);
}
function findIntraUnitContacts(structure, unit, features, contactTesters, props) {
var builder = contacts_builder_1.IntraContactsBuilder.create(features, unit.elements.length);
if (structure_1.Unit.isAtomic(unit)) {
(0, contacts_1.addUnitContacts)(structure, unit, features, builder, contactTesters, props);
}
return builder.getContacts();
}
function findInterUnitContacts(structure, unitsFeatures, contactTesters, props) {
var builder = contacts_builder_1.InterContactsBuilder.create();
structure_1.Structure.eachUnitPair(structure, function (unitA, unitB) {
var featuresA = unitsFeatures.get(unitA.id);
var featuresB = unitsFeatures.get(unitB.id);
(0, contacts_1.addStructureContacts)(structure, unitA, featuresA, unitB, featuresB, builder, contactTesters, props);
}, {
maxRadius: Math.max.apply(Math, contactTesters.map(function (t) { return t.maxDistance; })),
validUnit: function (unit) { return structure_1.Unit.isAtomic(unit); },
validUnitPair: function (unitA, unitB) { return structure_1.Structure.validUnitPair(structure, unitA, unitB); }
});
return builder.getContacts(unitsFeatures);
}
//# sourceMappingURL=interactions.js.map
;