UNPKG

molstar

Version:

A comprehensive macromolecular library.

172 lines (171 loc) 8.71 kB
/** * 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 { __assign } from "tslib"; import { ConfalPyramids, ConfalPyramidsProvider } from './property'; import { ConfalPyramidsIterator } from './util'; import { ConfalPyramidsTypes as CPT } from './types'; import { Mesh } from '../../../mol-geo/geometry/mesh/mesh'; import { MeshBuilder } from '../../../mol-geo/geometry/mesh/mesh-builder'; import { PrimitiveBuilder } from '../../../mol-geo/primitive/primitive'; import { LocationIterator } from '../../../mol-geo/util/location-iterator'; import { Mat4, Vec3 } from '../../../mol-math/linear-algebra'; import { EmptyLoci } from '../../../mol-model/loci'; import { Unit } from '../../../mol-model/structure'; import { Representation } from '../../../mol-repr/representation'; import { StructureRepresentationProvider, StructureRepresentationStateBuilder, UnitsRepresentation } from '../../../mol-repr/structure/representation'; import { UnitsMeshParams, UnitsMeshVisual } from '../../../mol-repr/structure/units-visual'; import { ParamDefinition as PD } from '../../../mol-util/param-definition'; import { NullLocation } from '../../../mol-model/location'; var t = Mat4.identity(); var w = Vec3.zero(); var mp = Vec3.zero(); var posO3 = Vec3(); var posP = Vec3(); var posOP1 = Vec3(); var posOP2 = Vec3(); var posO5 = Vec3(); function calcMidpoint(mp, v, w) { Vec3.sub(mp, v, w); Vec3.scale(mp, mp, 0.5); Vec3.add(mp, mp, w); } function shiftVertex(vec, ref, scale) { Vec3.sub(w, vec, ref); Vec3.scale(w, w, scale); Vec3.add(vec, vec, w); } var ConfalPyramidsMeshParams = __assign({}, UnitsMeshParams); function createConfalPyramidsIterator(structureGroup) { var _a, _b; var structure = structureGroup.structure, group = structureGroup.group; var instanceCount = group.units.length; var data = (_b = (_a = ConfalPyramidsProvider.get(structure.model)) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.data; if (!data) return LocationIterator(0, 1, 1, function () { return NullLocation; }); var halfPyramidsCount = data.steps.length * 2; var getLocation = function (groupIndex, instanceIndex) { if (halfPyramidsCount <= groupIndex) return NullLocation; var idx = Math.floor(groupIndex / 2); // Map groupIndex to a step, see createConfalPyramidsMesh() for full explanation return CPT.Location(data.steps[idx], groupIndex % 2 === 1); }; return LocationIterator(halfPyramidsCount, instanceCount, 1, getLocation); } function createConfalPyramidsMesh(ctx, unit, structure, theme, props, mesh) { var _a, _b; if (!Unit.isAtomic(unit)) return Mesh.createEmpty(mesh); var data = (_b = (_a = ConfalPyramidsProvider.get(structure.model)) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.data; if (!data) return Mesh.createEmpty(mesh); var steps = data.steps, mapping = data.mapping; if (steps.length === 0) return Mesh.createEmpty(mesh); var vertexCount = (6 * steps.length) / mapping.length; var mb = MeshBuilder.createState(vertexCount, vertexCount / 10, mesh); var it = new ConfalPyramidsIterator(structure, unit); while (it.hasNext) { var allPoints = it.move(); for (var _i = 0, allPoints_1 = allPoints; _i < allPoints_1.length; _i++) { var points = allPoints_1[_i]; var O3 = points.O3, P = points.P, OP1 = points.OP1, OP2 = points.OP2, O5 = points.O5, confalScore = points.confalScore; var scale = (confalScore - 20.0) / 100.0; // Steps can be drawn in a different order than they are stored. // To make sure that we can get from the drawn pyramid back to the step in represents, // we need to use an appropriate groupId. The stepIdx passed from the iterator // is an index into the array of all steps in the structure. // Since a step is drawn as two "half-pyramids" we need two ids to map to a single step. // To do that, we just multiply the index by 2. idx*2 marks the "upper" half-pyramid, // (idx*2)+1 the "lower" half-pyramid. var groupIdx = points.stepIdx * 2; unit.conformation.invariantPosition(O3, posO3); unit.conformation.invariantPosition(P, posP); unit.conformation.invariantPosition(OP1, posOP1); unit.conformation.invariantPosition(OP2, posOP2); unit.conformation.invariantPosition(O5, posO5); shiftVertex(posO3, posP, scale); shiftVertex(posOP1, posP, scale); shiftVertex(posOP2, posP, scale); shiftVertex(posO5, posP, scale); calcMidpoint(mp, posO3, posO5); mb.currentGroup = groupIdx; var pb = PrimitiveBuilder(3); /* Upper part (for first residue in step) */ pb.add(posO3, posOP1, posOP2); pb.add(posO3, mp, posOP1); pb.add(posO3, posOP2, mp); MeshBuilder.addPrimitive(mb, t, pb.getPrimitive()); /* Lower part (for second residue in step) */ mb.currentGroup = groupIdx + 1; pb = PrimitiveBuilder(3); pb.add(mp, posO5, posOP1); pb.add(mp, posOP2, posO5); pb.add(posO5, posOP2, posOP1); MeshBuilder.addPrimitive(mb, t, pb.getPrimitive()); } } return MeshBuilder.getMesh(mb); } function getConfalPyramidLoci(pickingId, structureGroup, id) { var _a, _b; var groupId = pickingId.groupId, objectId = pickingId.objectId, instanceId = pickingId.instanceId; if (objectId !== id) return EmptyLoci; var structure = structureGroup.structure; var unit = structureGroup.group.units[instanceId]; if (!Unit.isAtomic(unit)) return EmptyLoci; var data = (_b = (_a = ConfalPyramidsProvider.get(structure.model)) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.data; if (!data) return EmptyLoci; var halfPyramidsCount = data.steps.length * 2; if (halfPyramidsCount <= groupId) return EmptyLoci; var idx = Math.floor(groupId / 2); // Map groupIndex to a step, see createConfalPyramidsMesh() for full explanation var step = data.steps[idx]; return CPT.Loci({ step: step, isLower: groupId % 2 === 1 }, [{}]); } function eachConfalPyramid(loci, structureGroup, apply) { return false; // TODO: Implement me } function ConfalPyramidsVisual(materialId) { return UnitsMeshVisual({ defaultProps: PD.getDefaultValues(ConfalPyramidsMeshParams), createGeometry: createConfalPyramidsMesh, createLocationIterator: createConfalPyramidsIterator, getLoci: getConfalPyramidLoci, eachLocation: eachConfalPyramid, setUpdateState: function (state, newProps, currentProps) { } }, materialId); } var ConfalPyramidsVisuals = { 'confal-pyramids-symbol': function (ctx, getParams) { return UnitsRepresentation('Confal Pyramids Symbol Mesh', ctx, getParams, ConfalPyramidsVisual); }, }; export var ConfalPyramidsParams = __assign({}, UnitsMeshParams); export function getConfalPyramidsParams(ctx, structure) { return PD.clone(ConfalPyramidsParams); } export function ConfalPyramidsRepresentation(ctx, getParams) { var repr = Representation.createMulti('Confal Pyramids', ctx, getParams, StructureRepresentationStateBuilder, ConfalPyramidsVisuals); return repr; } export var ConfalPyramidsRepresentationProvider = StructureRepresentationProvider({ name: 'confal-pyramids', label: 'Confal Pyramids', description: 'Displays schematic depiction of conformer classes and confal values', factory: ConfalPyramidsRepresentation, getParams: getConfalPyramidsParams, defaultValues: PD.getDefaultValues(ConfalPyramidsParams), defaultColorTheme: { name: 'confal-pyramids' }, defaultSizeTheme: { name: 'uniform' }, isApplicable: function (structure) { return structure.models.some(function (m) { return ConfalPyramids.isApplicable(m); }); }, ensureCustomProperties: { attach: function (ctx, structure) { return ConfalPyramidsProvider.attach(ctx, structure.model, void 0, true); }, detach: function (data) { return ConfalPyramidsProvider.ref(data.model, false); }, } });