UNPKG

molstar

Version:

A comprehensive macromolecular library.

299 lines 12.2 kB
/** * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> */ import { SetUtils } from '../../../../mol-util/set'; import { Unit } from '../../structure'; import { StructureSelection } from '../selection'; import { structureAreIntersecting } from '../utils/structure-set'; import { Vec3 } from '../../../../mol-math/linear-algebra'; import { checkStructureMaxRadiusDistance, checkStructureMinMaxDistance } from '../utils/structure-distance'; import { Structure } from '../../structure/structure'; import { SortedArray } from '../../../../mol-data/int'; export function pick(query, pred) { return function (ctx) { var sel = query(ctx); var ret = StructureSelection.LinearBuilder(ctx.inputStructure); ctx.pushCurrentElement(); StructureSelection.forEach(sel, function (s, i) { ctx.currentStructure = s; if (pred(ctx)) ret.add(s); if (i % 100) ctx.throwIfTimedOut(); }); ctx.popCurrentStructure(); return ret.getSelection(); }; } export function first(query) { return function (ctx) { var sel = query(ctx); var ret = StructureSelection.LinearBuilder(ctx.inputStructure); if (sel.kind === 'singletons') { if (sel.structure.elementCount > 0) { var u = sel.structure.units[0]; var s = Structure.create([u.getChild(SortedArray.ofSingleton(u.elements[0]))], { parent: ctx.inputStructure }); ret.add(s); } } else { if (sel.structures.length > 0) { ret.add(sel.structures[0]); } } return ret.getSelection(); }; } export function getCurrentStructureProperties(ctx, props, set) { var units = ctx.currentStructure.units; var l = ctx.pushCurrentElement(); l.structure = ctx.currentStructure; for (var _a = 0, units_1 = units; _a < units_1.length; _a++) { var unit = units_1[_a]; l.unit = unit; var elements = unit.elements; var fn = void 0; if (Unit.isAtomic(unit)) fn = props.atomic; else fn = props.coarse; if (!fn) continue; for (var j = 0, _j = elements.length; j < _j; j++) { l.element = elements[j]; set.add(fn(ctx)); } ctx.throwIfTimedOut(); } ctx.popCurrentElement(); return set; } function getSelectionProperties(ctx, query, props) { var set = new Set(); var sel = query(ctx); ctx.pushCurrentElement(); StructureSelection.forEach(sel, function (s, i) { ctx.currentStructure = s; getCurrentStructureProperties(ctx, props, set); if (i % 10) ctx.throwIfTimedOut(); }); ctx.popCurrentElement(); return set; } export function withSameAtomProperties(query, propertySource, props) { return function (ctx) { var sel = query(ctx); var propSet = getSelectionProperties(ctx, propertySource, props); var ret = StructureSelection.LinearBuilder(ctx.inputStructure); ctx.pushCurrentStructure(); StructureSelection.forEach(sel, function (s, i) { ctx.currentStructure = s; var currentProps = getCurrentStructureProperties(ctx, props, new Set()); if (SetUtils.isSuperset(currentProps, propSet)) { ret.add(s); } if (i % 10) ctx.throwIfTimedOut(); }); ctx.popCurrentStructure(); return ret.getSelection(); }; } export function areIntersectedBy(query, by) { return function (ctx) { var mask = StructureSelection.unionStructure(by(ctx)); var ret = StructureSelection.LinearBuilder(ctx.inputStructure); StructureSelection.forEach(query(ctx), function (s, i) { if (structureAreIntersecting(mask, s)) ret.add(s); if (i % 10) ctx.throwIfTimedOut(); }); return ret.getSelection(); }; } export function within(params) { return function (queryCtx) { var ctx = { queryCtx: queryCtx, selection: params.query(queryCtx), target: params.target(queryCtx), maxRadius: params.maxRadius, minRadius: params.minRadius ? Math.max(0, params.minRadius) : 0, elementRadius: params.elementRadius, invert: !!params.invert, }; if (ctx.minRadius === 0 && typeof params.minRadius === 'undefined') { return withinMaxRadiusLookup(ctx); } else if (ctx.minRadius === 0) { return withinMaxRadius(ctx); } else { return withinMinMaxRadius(ctx); } }; } function withinMaxRadiusLookup(_a) { var queryCtx = _a.queryCtx, selection = _a.selection, target = _a.target, maxRadius = _a.maxRadius, invert = _a.invert; var targetLookup = StructureSelection.unionStructure(target).lookup3d; var ret = StructureSelection.LinearBuilder(queryCtx.inputStructure); var pos = Vec3.zero(); StructureSelection.forEach(selection, function (s, sI) { var units = s.units; var withinRadius = false; for (var i = 0, _i = units.length; i < _i; i++) { var unit = units[i]; var elements = unit.elements, _a = unit.conformation, position = _a.position, r = _a.r; for (var i_1 = 0, _i_1 = elements.length; i_1 < _i_1; i_1++) { var e = elements[i_1]; position(e, pos); if (targetLookup.check(pos[0], pos[1], pos[2], maxRadius + r(e))) { withinRadius = true; break; } } if (withinRadius) break; } if (invert) withinRadius = !withinRadius; if (withinRadius) ret.add(s); if (sI % 10 === 0) queryCtx.throwIfTimedOut(); }); return ret.getSelection(); } function withinMaxRadius(_a) { var queryCtx = _a.queryCtx, selection = _a.selection, target = _a.target, maxRadius = _a.maxRadius, invert = _a.invert, elementRadius = _a.elementRadius; var targetStructure = StructureSelection.unionStructure(target); var ret = StructureSelection.LinearBuilder(queryCtx.inputStructure); queryCtx.pushCurrentElement(); StructureSelection.forEach(selection, function (s, sI) { var withinRadius = checkStructureMaxRadiusDistance(queryCtx, targetStructure, s, maxRadius, elementRadius); if (invert) withinRadius = !withinRadius; if (withinRadius) ret.add(s); if (sI % 10 === 0) queryCtx.throwIfTimedOut(); }); queryCtx.popCurrentElement(); return ret.getSelection(); } function withinMinMaxRadius(_a) { var queryCtx = _a.queryCtx, selection = _a.selection, target = _a.target, minRadius = _a.minRadius, maxRadius = _a.maxRadius, invert = _a.invert, elementRadius = _a.elementRadius; var targetStructure = StructureSelection.unionStructure(target); var ret = StructureSelection.LinearBuilder(queryCtx.inputStructure); queryCtx.pushCurrentElement(); StructureSelection.forEach(selection, function (s, sI) { var withinRadius = checkStructureMinMaxDistance(queryCtx, targetStructure, s, minRadius, maxRadius, elementRadius); if (invert) withinRadius = !withinRadius; if (withinRadius) ret.add(s); if (sI % 10 === 0) queryCtx.throwIfTimedOut(); }); queryCtx.popCurrentElement(); return ret.getSelection(); } function checkConnected(ctx, structure) { var queryCtx = ctx.queryCtx, input = ctx.input, target = ctx.target, disjunct = ctx.disjunct; var atomicBond = queryCtx.atomicBond; var interBonds = input.interUnitBonds; atomicBond.setStructure(input); for (var _a = 0, _b = structure.units; _a < _b.length; _a++) { var unit = _b[_a]; if (!Unit.isAtomic(unit)) continue; var inputUnit = input.unitMap.get(unit.id); var _c = inputUnit.bonds, offset = _c.offset, b = _c.b, _d = _c.edgeProps, flags = _d.flags, order = _d.order; var bondedUnits = interBonds.getConnectedUnits(unit.id); var buCount = bondedUnits.length; var srcElements = unit.elements; var inputElements = inputUnit.elements; for (var i = 0, _i = srcElements.length; i < _i; i++) { var inputIndex = SortedArray.indexOf(inputElements, srcElements[i]); atomicBond.a.unit = inputUnit; atomicBond.b.unit = inputUnit; // tElement.unit = unit; for (var l = offset[inputIndex], _l = offset[inputIndex + 1]; l < _l; l++) { // tElement.element = inputElements[b[l]]; atomicBond.b.element = inputUnit.elements[b[l]]; if (disjunct && SortedArray.has(unit.elements, atomicBond.b.element)) continue; if (!target.hasElement(atomicBond.b)) continue; atomicBond.aIndex = inputIndex; atomicBond.a.element = srcElements[i]; atomicBond.bIndex = b[l]; atomicBond.type = flags[l]; atomicBond.order = order[l]; if (atomicBond.test(queryCtx, true)) return true; } for (var li = 0; li < buCount; li++) { var lu = bondedUnits[li]; var bUnit = input.unitMap.get(lu.unitB); var bElements = bUnit.elements; var bonds = lu.getEdges(inputIndex); for (var bi = 0, _bi = bonds.length; bi < _bi; bi++) { var bond = bonds[bi]; atomicBond.b.unit = bUnit; atomicBond.b.element = bElements[bond.indexB]; if (!target.hasElement(atomicBond.b)) continue; if (disjunct && structure.hasElement(atomicBond.b)) continue; atomicBond.a.unit = inputUnit; atomicBond.aIndex = inputIndex; atomicBond.a.element = srcElements[i]; atomicBond.bIndex = bond.indexB; atomicBond.type = bond.props.flag; atomicBond.order = bond.props.order; if (atomicBond.test(queryCtx, true)) return true; } } } } return false; } export function isConnectedTo(_a) { var query = _a.query, target = _a.target, disjunct = _a.disjunct, invert = _a.invert, bondTest = _a.bondTest; return function (ctx) { var targetSel = target(ctx); if (StructureSelection.isEmpty(targetSel)) return targetSel; var selection = query(ctx); if (StructureSelection.isEmpty(selection)) return selection; var connCtx = { queryCtx: ctx, input: ctx.inputStructure, disjunct: disjunct, target: StructureSelection.unionStructure(targetSel) }; var ret = StructureSelection.LinearBuilder(ctx.inputStructure); ctx.pushCurrentBond(); ctx.atomicBond.setTestFn(bondTest); StructureSelection.forEach(selection, function (s, sI) { if (checkConnected(connCtx, s)) { ret.add(s); } else if (invert) { ret.add(s); } if (sI % 5 === 0) ctx.throwIfTimedOut(); }); ctx.popCurrentBond(); return ret.getSelection(); }; } //# sourceMappingURL=filters.js.map