molstar
Version:
A comprehensive macromolecular library.
231 lines • 12.3 kB
JavaScript
/**
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Michal Malý <michal.maly@ibt.cas.cz>
* @author Jiří Černý <jiri.cerny@ibt.cas.cz>
*/
import { __extends } from "tslib";
import { ConfalPyramidsProvider } from './property';
import { OrderedSet, Segmentation } from '../../../mol-data/int';
import { Vec3 } from '../../../mol-math/linear-algebra';
import { StructureElement, StructureProperties } from '../../../mol-model/structure';
export var ConfalPyramidsUtil;
(function (ConfalPyramidsUtil) {
function residueInfoFromLocation(loc) {
return {
PDB_model_num: StructureProperties.unit.model_num(loc),
asym_id: StructureProperties.chain.label_asym_id(loc),
auth_asym_id: StructureProperties.chain.auth_asym_id(loc),
seq_id: StructureProperties.residue.label_seq_id(loc),
auth_seq_id: StructureProperties.residue.auth_seq_id(loc),
comp_id: StructureProperties.atom.label_comp_id(loc),
alt_id: StructureProperties.atom.label_alt_id(loc),
ins_code: StructureProperties.residue.pdbx_PDB_ins_code(loc)
};
}
function hasMultipleModels(unit) {
var prop = ConfalPyramidsProvider.get(unit.model).value;
if (prop === undefined || prop.data === undefined)
throw new Error('No custom properties data');
return prop.data.hasMultipleModels;
}
ConfalPyramidsUtil.hasMultipleModels = hasMultipleModels;
function getPossibleAltIdsIndices(eIFirst, eILast, structure, unit) {
var loc = StructureElement.Location.create(structure, unit, -1);
var uIFirst = OrderedSet.indexOf(unit.elements, eIFirst);
var uILast = OrderedSet.indexOf(unit.elements, eILast);
var possibleAltIds = [];
for (var uI = uIFirst; uI <= uILast; uI++) {
loc.element = unit.elements[uI];
var altId = StructureProperties.atom.label_alt_id(loc);
if (altId !== '' && !possibleAltIds.includes(altId))
possibleAltIds.push(altId);
}
return possibleAltIds;
}
function getPossibleAltIdsResidue(residue, structure, unit) {
return getPossibleAltIdsIndices(unit.elements[residue.start], unit.elements[residue.end - 1], structure, unit);
}
var Utility = /** @class */ (function () {
function Utility(unit) {
var prop = ConfalPyramidsProvider.get(unit.model).value;
if (prop === undefined || prop.data === undefined)
throw new Error('No custom properties data');
this.data = prop.data;
this.hasMultipleModels = hasMultipleModels(unit);
this.entryId = unit.model.entryId.toLowerCase();
this.modelNum = unit.model.modelNum;
}
Utility.prototype.getPyramidByName = function (name) {
var index = this.data.names.get(name);
if (index === undefined)
return { pyramid: undefined, index: -1 };
return { pyramid: this.data.pyramids[index], index: index };
};
Utility.prototype.stepToName = function (entry_id, modelNum, locFirst, locSecond, fakeAltId_1, fakeAltId_2) {
var first = residueInfoFromLocation(locFirst);
var second = residueInfoFromLocation(locSecond);
var model_id = this.hasMultipleModels ? "-m" + modelNum : '';
var alt_id_1 = fakeAltId_1 !== '' ? "." + fakeAltId_1 : (first.alt_id.length ? "." + first.alt_id : '');
var alt_id_2 = fakeAltId_2 !== '' ? "." + fakeAltId_2 : (second.alt_id.length ? "." + second.alt_id : '');
var ins_code_1 = first.ins_code.length ? "." + first.ins_code : '';
var ins_code_2 = second.ins_code.length ? "." + second.ins_code : '';
return "" + entry_id + model_id + "_" + first.auth_asym_id + "_" + first.comp_id + alt_id_1 + "_" + first.auth_seq_id + ins_code_1 + "_" + second.comp_id + alt_id_2 + "_" + second.auth_seq_id + ins_code_2;
};
return Utility;
}());
var UnitWalker = /** @class */ (function (_super) {
__extends(UnitWalker, _super);
function UnitWalker(structure, unit, handler) {
var _this = _super.call(this, unit) || this;
_this.structure = structure;
_this.unit = unit;
_this.handler = handler;
_this.chainIt = Segmentation.transientSegments(unit.model.atomicHierarchy.chainAtomSegments, unit.elements);
_this.residueIt = Segmentation.transientSegments(unit.model.atomicHierarchy.residueAtomSegments, unit.elements);
return _this;
}
UnitWalker.prototype.getAtomIndices = function (names, residue) {
var rI = residue.start;
var rILast = residue.end - 1;
var indices = [];
for (; rI !== rILast; rI++) {
var eI = this.unit.elements[rI];
var loc = StructureElement.Location.create(this.structure, this.unit, eI);
var thisName = StructureProperties.atom.label_atom_id(loc);
if (names.includes(thisName))
indices.push(eI);
}
if (indices.length === 0)
throw new Error("Element " + name + " not found on residue " + residue.index);
return indices;
};
UnitWalker.prototype.getAtomPositions = function (indices) {
var pos = this.unit.conformation.invariantPosition;
var positions = [];
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
var eI = indices_1[_i];
var v = Vec3.zero();
pos(eI, v);
positions.push(v);
}
return positions;
};
UnitWalker.prototype.handleStep = function (firstAtoms, secondAtoms) {
var _this = this;
var modelNum = this.hasMultipleModels ? this.modelNum : -1;
var ok = false;
var firstLoc = StructureElement.Location.create(this.structure, this.unit, -1);
var secondLoc = StructureElement.Location.create(this.structure, this.unit, -1);
for (var i = 0; i < firstAtoms.length; i++) {
var first = firstAtoms[i];
for (var j = 0; j < secondAtoms.length; j++) {
var second = secondAtoms[j];
firstLoc.element = first.O3.index;
secondLoc.element = second.OP1.index;
var name_1 = this.stepToName(this.entryId, modelNum, firstLoc, secondLoc, first.O3.fakeAltId, second.OP1.fakeAltId);
var _a = this.getPyramidByName(name_1), pyramid = _a.pyramid, index = _a.index;
if (pyramid !== undefined) {
var setLoc = function (loc, eI) {
loc.element.structure = _this.structure;
loc.element.unit = _this.unit;
loc.element.element = eI;
};
var locIndex = index * 2;
setLoc(this.data.locations[locIndex], firstLoc.element);
setLoc(this.data.locations[locIndex + 1], secondLoc.element);
this.handler(pyramid, first, second, locIndex, locIndex + 1);
ok = true;
}
}
}
if (!ok)
throw new Error('Bogus step');
};
UnitWalker.prototype.processFirstResidue = function (residue, possibleAltIds) {
var indO3 = this.getAtomIndices(['O3\'', 'O3*'], residue);
var posO3 = this.getAtomPositions(indO3);
var altPos = [
{ O3: { pos: posO3[0], index: indO3[0], fakeAltId: '' } }
];
for (var i = 1; i < indO3.length; i++) {
altPos.push({ O3: { pos: posO3[i], index: indO3[i], fakeAltId: '' } });
}
if (altPos.length === 1 && possibleAltIds.length > 1) {
/* We have some alternate positions on the residue but O3 does not have any - fake them */
altPos[0].O3.fakeAltId = possibleAltIds[0];
for (var i = 1; i < possibleAltIds.length; i++)
altPos.push({ O3: { pos: posO3[0], index: indO3[0], fakeAltId: possibleAltIds[i] } });
}
return altPos;
};
UnitWalker.prototype.processSecondResidue = function (residue, possibleAltIds) {
var indOP1 = this.getAtomIndices(['OP1'], residue);
var indOP2 = this.getAtomIndices(['OP2'], residue);
var indO5 = this.getAtomIndices(['O5\'', 'O5*'], residue);
var indP = this.getAtomIndices(['P'], residue);
var posOP1 = this.getAtomPositions(indOP1);
var posOP2 = this.getAtomPositions(indOP2);
var posO5 = this.getAtomPositions(indO5);
var posP = this.getAtomPositions(indP);
var infoOP1 = [];
/* We use OP1 as "pivotal" atom. There is no specific reason
* to pick OP1, it is as good a choice as any other atom
*/
if (indOP1.length === 1 && possibleAltIds.length > 1) {
/* No altIds on OP1, fake them */
for (var _i = 0, possibleAltIds_1 = possibleAltIds; _i < possibleAltIds_1.length; _i++) {
var altId = possibleAltIds_1[_i];
infoOP1.push({ pos: posOP1[0], index: indOP1[0], fakeAltId: altId });
}
}
else {
for (var i = 0; i < indOP1.length; i++)
infoOP1.push({ pos: posOP1[i], index: indOP1[i], fakeAltId: '' });
}
var mkInfo = function (i, indices, positions, altId) {
if (i >= indices.length) {
var last = indices.length - 1;
return { pos: positions[last], index: indices[last], fakeAltId: altId };
}
return { pos: positions[i], index: indices[i], fakeAltId: altId };
};
var altPos = [];
for (var i = 0; i < infoOP1.length; i++) {
var altId = infoOP1[i].fakeAltId;
var OP2 = mkInfo(i, indOP2, posOP2, altId);
var O5 = mkInfo(i, indO5, posO5, altId);
var P = mkInfo(i, indP, posP, altId);
altPos.push({ OP1: infoOP1[i], OP2: OP2, O5: O5, P: P });
}
return altPos;
};
UnitWalker.prototype.step = function (residue) {
var firstPossibleAltIds = getPossibleAltIdsResidue(residue, this.structure, this.unit);
var firstAtoms = this.processFirstResidue(residue, firstPossibleAltIds);
residue = this.residueIt.move();
var secondPossibleAltIds = getPossibleAltIdsResidue(residue, this.structure, this.unit);
var secondAtoms = this.processSecondResidue(residue, secondPossibleAltIds);
return { firstAtoms: firstAtoms, secondAtoms: secondAtoms };
};
UnitWalker.prototype.walk = function () {
while (this.chainIt.hasNext) {
this.residueIt.setSegment(this.chainIt.move());
var residue = this.residueIt.move();
while (this.residueIt.hasNext) {
try {
var _a = this.step(residue), firstAtoms = _a.firstAtoms, secondAtoms = _a.secondAtoms;
this.handleStep(firstAtoms, secondAtoms);
}
catch (error) {
/* Skip and move along */
residue = this.residueIt.move();
}
}
}
};
return UnitWalker;
}(Utility));
ConfalPyramidsUtil.UnitWalker = UnitWalker;
})(ConfalPyramidsUtil || (ConfalPyramidsUtil = {}));
//# sourceMappingURL=util.js.map