UNPKG

molstar

Version:

A comprehensive macromolecular library.

262 lines (261 loc) 12.2 kB
/** * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import { __assign } from "tslib"; import { BondType } from '../../../../mol-model/structure/model/types'; import { Unit, StructureElement, Structure, Bond } from '../../../../mol-model/structure'; import { ParamDefinition as PD } from '../../../../mol-util/param-definition'; import { LocationIterator } from '../../../../mol-geo/util/location-iterator'; import { LinkCylinderParams, LinkLineParams } from './link'; import { ObjectKeys } from '../../../../mol-util/type-helpers'; import { EmptyLoci } from '../../../../mol-model/loci'; import { Interval, OrderedSet, SortedArray } from '../../../../mol-data/int'; import { isH, isHydrogen } from './common'; export var BondParams = { includeTypes: PD.MultiSelect(ObjectKeys(BondType.Names), PD.objectToOptions(BondType.Names)), excludeTypes: PD.MultiSelect([], PD.objectToOptions(BondType.Names)), ignoreHydrogens: PD.Boolean(false), aromaticBonds: PD.Boolean(true, { description: 'Display aromatic bonds with dashes' }), multipleBonds: PD.Select('symmetric', PD.arrayToOptions(['off', 'symmetric', 'offset'])), }; export var DefaultBondProps = PD.getDefaultValues(BondParams); export var BondCylinderParams = __assign(__assign(__assign({}, LinkCylinderParams), BondParams), { adjustCylinderLength: PD.Boolean(false, { description: 'Shorten cylinders to reduce overlap with spheres. Useful for for transparent bonds. Not working well with aromatic bonds.' }) }); export var DefaultBondCylinderProps = PD.getDefaultValues(BondCylinderParams); export var BondLineParams = __assign(__assign({}, LinkLineParams), BondParams); export var DefaultBondLineProps = PD.getDefaultValues(BondLineParams); export function ignoreBondType(include, exclude, f) { return !BondType.is(include, f) || BondType.is(exclude, f); } export function makeIntraBondIgnoreTest(structure, unit, props) { var elements = unit.elements; var atomicNumber = unit.model.atomicHierarchy.derived.atom.atomicNumber; var bonds = unit.bonds; var a = bonds.a, b = bonds.b, edgeProps = bonds.edgeProps; var _flags = edgeProps.flags; var ignoreHydrogens = props.ignoreHydrogens, includeTypes = props.includeTypes, excludeTypes = props.excludeTypes; var include = BondType.fromNames(includeTypes); var exclude = BondType.fromNames(excludeTypes); var allBondTypes = BondType.isAll(include) && 0 /* BondType.Flag.None */ === exclude; var child = structure.child; var childUnit = child === null || child === void 0 ? void 0 : child.unitMap.get(unit.id); if (child && !childUnit) throw new Error('expected childUnit to exist if child exists'); if (allBondTypes && !ignoreHydrogens && !child) return; return function (edgeIndex) { return ((!!childUnit && !SortedArray.has(childUnit.elements, elements[a[edgeIndex]])) || (ignoreHydrogens && (isH(atomicNumber, elements[a[edgeIndex]]) || isH(atomicNumber, elements[b[edgeIndex]]))) || (!allBondTypes && ignoreBondType(include, exclude, _flags[edgeIndex]))); }; } export function makeInterBondIgnoreTest(structure, props) { var bonds = structure.interUnitBonds; var edges = bonds.edges; var ignoreHydrogens = props.ignoreHydrogens, includeTypes = props.includeTypes, excludeTypes = props.excludeTypes; var include = BondType.fromNames(includeTypes); var exclude = BondType.fromNames(excludeTypes); var allBondTypes = BondType.isAll(include) && 0 /* BondType.Flag.None */ === exclude; var child = structure.child; if (allBondTypes && !ignoreHydrogens && !child) return; return function (edgeIndex) { if (child) { var b = edges[edgeIndex]; var childUnitA = child.unitMap.get(b.unitA); if (!childUnitA) return true; var unitA = structure.unitMap.get(b.unitA); var eA = unitA.elements[b.indexA]; if (!SortedArray.has(childUnitA.elements, eA)) return true; } if (ignoreHydrogens) { var b = edges[edgeIndex]; var uA = structure.unitMap.get(b.unitA); var uB = structure.unitMap.get(b.unitB); if (isHydrogen(uA, uA.elements[b.indexA]) || isHydrogen(uB, uB.elements[b.indexB])) return true; } if (!allBondTypes) { if (ignoreBondType(include, exclude, edges[edgeIndex].props.flag)) return true; } return false; }; } export var BondIterator; (function (BondIterator) { function fromGroup(structureGroup) { var group = structureGroup.group, structure = structureGroup.structure; var unit = group.units[0]; var groupCount = Unit.isAtomic(unit) ? unit.bonds.edgeCount * 2 : 0; var instanceCount = group.units.length; var location = Bond.Location(structure, undefined, undefined, structure, undefined, undefined); var getLocation = function (groupIndex, instanceIndex) { var unit = group.units[instanceIndex]; location.aUnit = unit; location.bUnit = unit; location.aIndex = unit.bonds.a[groupIndex]; location.bIndex = unit.bonds.b[groupIndex]; return location; }; return LocationIterator(groupCount, instanceCount, 1, getLocation); } BondIterator.fromGroup = fromGroup; function fromStructure(structure) { var groupCount = structure.interUnitBonds.edgeCount; var instanceCount = 1; var location = Bond.Location(structure, undefined, undefined, structure, undefined, undefined); var getLocation = function (groupIndex) { var bond = structure.interUnitBonds.edges[groupIndex]; location.aUnit = structure.unitMap.get(bond.unitA); location.aIndex = bond.indexA; location.bUnit = structure.unitMap.get(bond.unitB); location.bIndex = bond.indexB; return location; }; return LocationIterator(groupCount, instanceCount, 1, getLocation, true); } BondIterator.fromStructure = fromStructure; })(BondIterator || (BondIterator = {})); // export function getIntraBondLoci(pickingId, structureGroup, id) { var objectId = pickingId.objectId, instanceId = pickingId.instanceId, groupId = pickingId.groupId; if (id === objectId) { var structure = structureGroup.structure, group = structureGroup.group; var unit = group.units[instanceId]; if (Unit.isAtomic(unit)) { var target = structure.target; var iA = unit.bonds.a[groupId]; var iB = unit.bonds.b[groupId]; return Bond.Loci(target, [ Bond.Location(target, unit, iA, target, unit, iB), Bond.Location(target, unit, iB, target, unit, iA) ]); } } return EmptyLoci; } export function eachIntraBond(loci, structureGroup, apply, isMarking) { var changed = false; if (Bond.isLoci(loci)) { var structure = structureGroup.structure, group = structureGroup.group; if (!Structure.areEquivalent(loci.structure, structure)) return false; var unit = group.units[0]; if (!Unit.isAtomic(unit)) return false; var groupCount = unit.bonds.edgeCount * 2; for (var _i = 0, _a = loci.bonds; _i < _a.length; _i++) { var b = _a[_i]; if (b.aUnit !== b.bUnit) continue; var unitIdx = group.unitIndexMap.get(b.aUnit.id); if (unitIdx !== undefined) { var idx = unit.bonds.getDirectedEdgeIndex(b.aIndex, b.bIndex); if (idx !== -1) { if (apply(Interval.ofSingleton(unitIdx * groupCount + idx))) changed = true; } } } } else if (StructureElement.Loci.is(loci)) { var structure = structureGroup.structure, group = structureGroup.group; if (!Structure.areEquivalent(loci.structure, structure)) return false; var unit = group.units[0]; if (!Unit.isAtomic(unit)) return false; var groupCount_1 = unit.bonds.edgeCount * 2; var _loop_1 = function (e) { var unitIdx = group.unitIndexMap.get(e.unit.id); if (unitIdx !== undefined) { var _d = unit.bonds, offset_1 = _d.offset, b_1 = _d.b; OrderedSet.forEach(e.indices, function (v) { for (var t = offset_1[v], _t = offset_1[v + 1]; t < _t; t++) { if (!isMarking || OrderedSet.has(e.indices, b_1[t])) { if (apply(Interval.ofSingleton(unitIdx * groupCount_1 + t))) changed = true; } } }); } }; for (var _b = 0, _c = loci.elements; _b < _c.length; _b++) { var e = _c[_b]; _loop_1(e); } } return changed; } // export function getInterBondLoci(pickingId, structure, id) { var objectId = pickingId.objectId, groupId = pickingId.groupId; if (id === objectId) { var target = structure.target; var b = structure.interUnitBonds.edges[groupId]; var uA = structure.unitMap.get(b.unitA); var uB = structure.unitMap.get(b.unitB); return Bond.Loci(target, [ Bond.Location(target, uA, b.indexA, target, uB, b.indexB), Bond.Location(target, uB, b.indexB, target, uA, b.indexA) ]); } return EmptyLoci; } var __unitMap = new Map(); export function eachInterBond(loci, structure, apply, isMarking) { var changed = false; if (Bond.isLoci(loci)) { if (!Structure.areEquivalent(loci.structure, structure)) return false; for (var _i = 0, _a = loci.bonds; _i < _a.length; _i++) { var b = _a[_i]; var idx = structure.interUnitBonds.getBondIndexFromLocation(b); if (idx !== -1) { if (apply(Interval.ofSingleton(idx))) changed = true; } } } else if (StructureElement.Loci.is(loci)) { if (!Structure.areEquivalent(loci.structure, structure)) return false; if (isMarking && loci.elements.length === 1) return false; // only a single unit for (var _b = 0, _c = loci.elements; _b < _c.length; _b++) { var e = _c[_b]; __unitMap.set(e.unit.id, e.indices); } var _loop_2 = function (e) { var unit = e.unit; if (!Unit.isAtomic(unit)) return "continue"; structure.interUnitBonds.getConnectedUnits(unit.id).forEach(function (b) { var otherLociIndices = __unitMap.get(b.unitB); if (!isMarking || otherLociIndices) { OrderedSet.forEach(e.indices, function (v) { if (!b.connectedIndices.includes(v)) return; b.getEdges(v).forEach(function (bi) { if (!isMarking || (otherLociIndices && OrderedSet.has(otherLociIndices, bi.indexB))) { var idx = structure.interUnitBonds.getEdgeIndex(v, unit.id, bi.indexB, b.unitB); if (apply(Interval.ofSingleton(idx))) changed = true; } }); }); } }); }; for (var _d = 0, _e = loci.elements; _d < _e.length; _d++) { var e = _e[_d]; _loop_2(e); } __unitMap.clear(); } return changed; }