molstar
Version:
A comprehensive macromolecular library.
194 lines (193 loc) • 8.55 kB
JavaScript
/**
* Copyright (c) 2018-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 { ModelCrossLinkRestraint } from './format';
import { Bond } from '../../../mol-model/structure';
import { PairRestraints } from '../pair-restraints';
import { CustomStructureProperty } from '../../common/custom-structure-property';
import { DataLocation } from '../../../mol-model/location';
import { DataLoci } from '../../../mol-model/loci';
import { CentroidHelper } from '../../../mol-math/geometry/centroid-helper';
import { bondLabel } from '../../../mol-theme/label';
import { Vec3 } from '../../../mol-math/linear-algebra';
import { CustomPropertyDescriptor } from '../../../mol-model/custom-property';
export var CrossLinkRestraintProvider = CustomStructureProperty.createProvider({
label: 'Cross Link Restraint',
descriptor: CustomPropertyDescriptor({
name: 'integrative-cross-link-restraint',
// TODO `cifExport` and `symbol`
}),
type: 'local',
defaultParams: {},
getParams: function (data) { return ({}); },
isApplicable: function (data) { return data.models.some(function (m) { return !!ModelCrossLinkRestraint.Provider.get(m); }); },
obtain: function (ctx, data, props) { return __awaiter(void 0, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, { value: extractCrossLinkRestraints(data) }];
});
}); }
});
export { CrossLinkRestraint };
var CrossLinkRestraint;
(function (CrossLinkRestraint) {
var Tag;
(function (Tag) {
Tag["CrossLinkRestraint"] = "cross-link-restraint";
})(Tag = CrossLinkRestraint.Tag || (CrossLinkRestraint.Tag = {}));
function isApplicable(structure) {
return structure.models.some(function (m) { return !!ModelCrossLinkRestraint.Provider.get(m); });
}
CrossLinkRestraint.isApplicable = isApplicable;
var distVecA = Vec3(), distVecB = Vec3();
function distance(pair) {
pair.unitA.conformation.position(pair.unitA.elements[pair.indexA], distVecA);
pair.unitB.conformation.position(pair.unitB.elements[pair.indexB], distVecB);
return Vec3.distance(distVecA, distVecB);
}
CrossLinkRestraint.distance = distance;
function Location(crossLinkRestraints, structure, index) {
return DataLocation('cross-link-restraints', { structure: structure, crossLinkRestraints: crossLinkRestraints }, index);
}
CrossLinkRestraint.Location = Location;
function isLocation(x) {
return !!x && x.kind === 'data-location' && x.tag === 'cross-link-restraints';
}
CrossLinkRestraint.isLocation = isLocation;
function areLocationsEqual(locA, locB) {
return (locA.data.structure === locB.data.structure &&
locA.data.crossLinkRestraints === locB.data.crossLinkRestraints &&
locA.element === locB.element);
}
CrossLinkRestraint.areLocationsEqual = areLocationsEqual;
function _label(crossLinkRestraints, element) {
var p = crossLinkRestraints.pairs[element];
return "Cross Link Restraint | Type: ".concat(p.restraintType, " | Threshold: ").concat(p.distanceThreshold, " \u212B | Psi: ").concat(p.psi, " | Sigma 1: ").concat(p.sigma1, " | Sigma 2: ").concat(p.sigma2, " | Distance: ").concat(distance(p).toFixed(2), " \u212B");
}
function locationLabel(location) {
return _label(location.data.crossLinkRestraints, location.element);
}
CrossLinkRestraint.locationLabel = locationLabel;
function Loci(structure, crossLinkRestraints, elements) {
return DataLoci('cross-link-restraints', { structure: structure, crossLinkRestraints: crossLinkRestraints }, elements, function (boundingSphere) { return getBoundingSphere(crossLinkRestraints, elements, boundingSphere); }, function () { return getLabel(structure, crossLinkRestraints, elements); });
}
CrossLinkRestraint.Loci = Loci;
function isLoci(x) {
return !!x && x.kind === 'data-loci' && x.tag === 'interactions';
}
CrossLinkRestraint.isLoci = isLoci;
function getBoundingSphere(crossLinkRestraints, elements, boundingSphere) {
return CentroidHelper.fromPairProvider(elements.length, function (i, pA, pB) {
var p = crossLinkRestraints.pairs[elements[i]];
p.unitA.conformation.position(p.unitA.elements[p.indexA], pA);
p.unitB.conformation.position(p.unitB.elements[p.indexB], pB);
}, boundingSphere);
}
CrossLinkRestraint.getBoundingSphere = getBoundingSphere;
function getLabel(structure, crossLinkRestraints, elements) {
var element = elements[0];
if (element === undefined)
return '';
var p = crossLinkRestraints.pairs[element];
return [
_label(crossLinkRestraints, element),
bondLabel(Bond.Location(structure, p.unitA, p.indexA, structure, p.unitB, p.indexB))
].join('</br>');
}
CrossLinkRestraint.getLabel = getLabel;
})(CrossLinkRestraint || (CrossLinkRestraint = {}));
//
function _addRestraints(map, unit, restraints) {
var elements = unit.elements;
var elementCount = elements.length;
var kind = unit.kind;
var _loop_1 = function (i) {
var e = elements[i];
restraints.getIndicesByElement(e, kind).forEach(function (ri) { return map.set(ri, i); });
};
for (var i = 0; i < elementCount; i++) {
_loop_1(i);
}
}
function extractInter(pairs, unitA, unitB) {
if (unitA.model !== unitB.model)
return;
if (unitA.model.sourceData.kind !== 'mmCIF')
return;
var restraints = ModelCrossLinkRestraint.Provider.get(unitA.model);
if (!restraints)
return;
var rA = new Map();
var rB = new Map();
_addRestraints(rA, unitA, restraints);
_addRestraints(rB, unitB, restraints);
rA.forEach(function (indexA, ri) {
var indexB = rB.get(ri);
if (indexB !== undefined) {
pairs.push(createCrossLinkRestraint(unitA, indexA, unitB, indexB, restraints, ri), createCrossLinkRestraint(unitB, indexB, unitA, indexA, restraints, ri));
}
});
}
function extractIntra(pairs, unit) {
if (unit.model.sourceData.kind !== 'mmCIF')
return;
var restraints = ModelCrossLinkRestraint.Provider.get(unit.model);
if (!restraints)
return;
var elements = unit.elements;
var elementCount = elements.length;
var kind = unit.kind;
var r = new Map();
var _loop_2 = function (i) {
var e = elements[i];
restraints.getIndicesByElement(e, kind).forEach(function (ri) {
var il = r.get(ri);
if (il)
il.push(i);
else
r.set(ri, [i]);
});
};
for (var i = 0; i < elementCount; i++) {
_loop_2(i);
}
r.forEach(function (il, ri) {
if (il.length < 2)
return;
var indexA = il[0], indexB = il[1];
pairs.push(createCrossLinkRestraint(unit, indexA, unit, indexB, restraints, ri), createCrossLinkRestraint(unit, indexB, unit, indexA, restraints, ri));
});
}
function createCrossLinkRestraint(unitA, indexA, unitB, indexB, restraints, row) {
return {
unitA: unitA,
indexA: indexA,
unitB: unitB,
indexB: indexB,
restraintType: restraints.data.restraint_type.value(row),
distanceThreshold: restraints.data.distance_threshold.value(row),
psi: restraints.data.psi.value(row),
sigma1: restraints.data.sigma_1.value(row),
sigma2: restraints.data.sigma_2.value(row),
};
}
function extractCrossLinkRestraints(structure) {
var pairs = [];
if (!structure.models.some(function (m) { return ModelCrossLinkRestraint.Provider.get(m); })) {
return new PairRestraints(pairs);
}
var n = structure.units.length;
for (var i = 0; i < n; ++i) {
var unitA = structure.units[i];
extractIntra(pairs, unitA);
for (var j = i + 1; j < n; ++j) {
var unitB = structure.units[j];
if (unitA.model === unitB.model) {
extractInter(pairs, unitA, unitB);
}
}
}
return new PairRestraints(pairs);
}