Browse Source

mol-model/query intersectBy, exceptBy, union

David Sehnal 6 years ago
parent
commit
4ec57eb89b

+ 1 - 1
src/mol-model/structure/query/queries/filters.ts

@@ -9,7 +9,7 @@ import { Unit } from '../../structure';
 import { QueryContext, QueryFn, QueryPredicate } from '../context';
 import { StructureQuery } from '../query';
 import { StructureSelection } from '../selection';
-import { structureAreIntersecting } from '../utils/structure';
+import { structureAreIntersecting } from '../utils/structure-set';
 import { Vec3 } from 'mol-math/linear-algebra';
 import { checkStructureMaxRadiusDistance, checkStructureMinMaxDistance } from '../utils/structure-distance';
 

+ 1 - 1
src/mol-model/structure/query/queries/generators.ts

@@ -14,7 +14,7 @@ import { UnitRing } from '../../structure/unit/rings';
 import Structure from '../../structure/structure';
 import { ElementIndex } from '../../model';
 import { UniqueArray } from 'mol-data/generic';
-import { structureSubtract } from '../utils/structure';
+import { structureSubtract } from '../utils/structure-set';
 
 export const none: StructureQuery = ctx => StructureSelection.Sequence(ctx.inputStructure, []);
 export const all: StructureQuery = ctx => StructureSelection.Singletons(ctx.inputStructure, ctx.inputStructure);

+ 50 - 6
src/mol-model/structure/query/queries/modifiers.ts

@@ -11,6 +11,7 @@ import { StructureSelection } from '../selection';
 import { UniqueStructuresBuilder } from '../utils/builders';
 import { StructureUniqueSubsetBuilder } from '../../structure/util/unique-subset-builder';
 import { QueryContext } from '../context';
+import { structureIntersect, structureSubtract } from '../utils/structure-set';
 
 function getWholeResidues(ctx: QueryContext, source: Structure, structure: Structure) {
     const builder = source.subsetBuilder(true);
@@ -39,7 +40,7 @@ function getWholeResidues(ctx: QueryContext, source: Structure, structure: Struc
     return builder.getStructure();
 }
 
-export function wholeResidues(query: StructureQuery, isFlat: boolean): StructureQuery {
+export function wholeResidues(query: StructureQuery): StructureQuery {
     return ctx => {
         const inner = query(ctx);
         if (StructureSelection.isSingleton(inner)) {
@@ -54,9 +55,6 @@ export function wholeResidues(query: StructureQuery, isFlat: boolean): Structure
     };
 }
 
-
-// export function groupBy()  ...
-
 export interface IncludeSurroundingsParams {
     radius: number,
     // TODO
@@ -112,9 +110,55 @@ export function querySelection(selection: StructureQuery, query: StructureQuery)
             StructureSelection.forEach(query(ctx), add);
             ctx.popInputStructure();
             if (sI % 10 === 0) ctx.throwIfTimedOut();
-        })
+        });
         return ret.getSelection();
     }
 }
 
-// TODO: intersectBy, exceptBy, unionBy, union, cluster, includeConnected
+export function intersectBy(query: StructureQuery, by: StructureQuery): StructureQuery {
+    return ctx => {
+        const selection = query(ctx);
+        if (StructureSelection.structureCount(selection) === 0) return selection;
+
+        const bySel = by(ctx);
+        if (StructureSelection.structureCount(bySel) === 0) return StructureSelection.Empty(ctx.inputStructure);
+        const unionBy = StructureSelection.unionStructure(bySel);
+
+        const ret = StructureSelection.UniqueBuilder(ctx.inputStructure);
+        StructureSelection.forEach(selection, (s, sI) => {
+            const ii = structureIntersect(unionBy, s);
+            if (ii.elementCount !== 0) ret.add(ii);
+        });
+
+        return ret.getSelection();
+    };
+}
+
+export function exceptBy(query: StructureQuery, by: StructureQuery): StructureQuery {
+    return ctx => {
+        const selection = query(ctx);
+        if (StructureSelection.structureCount(selection) === 0) return selection;
+
+        const bySel = by(ctx);
+        if (StructureSelection.structureCount(bySel) === 0) return StructureSelection.Empty(ctx.inputStructure);
+        const subtractBy = StructureSelection.unionStructure(bySel);
+
+        const ret = StructureSelection.UniqueBuilder(ctx.inputStructure);
+        StructureSelection.forEach(selection, (s, sI) => {
+            const diff = structureSubtract(s, subtractBy);
+            if (diff.elementCount !== 0) ret.add(diff);
+        });
+
+        return ret.getSelection();
+    };
+}
+
+export function union(query: StructureQuery): StructureQuery {
+    return ctx => {
+        const ret = StructureSelection.LinearBuilder(ctx.inputStructure);
+        ret.add(StructureSelection.unionStructure(query(ctx)));
+        return ret.getSelection();
+    };
+}
+
+// TODO: unionBy (skip this one?), cluster, includeConnected, includeSurroundings with "radii", expandProperty

+ 1 - 1
src/mol-model/structure/query/selection.ts

@@ -6,7 +6,7 @@
 
 import { HashSet } from 'mol-data/generic'
 import { Structure, StructureElement, Unit } from '../structure'
-import { structureUnion } from './utils/structure';
+import { structureUnion } from './utils/structure-set';
 import { OrderedSet, SortedArray } from 'mol-data/int';
 
 // A selection is a pair of a Structure and a sequence of unique AtomSets

+ 1 - 1
src/mol-model/structure/query/utils/builders.ts

@@ -7,7 +7,7 @@
 import { StructureElement, Structure } from '../../structure';
 import { StructureSelection } from '../selection';
 import { HashSet } from 'mol-data/generic';
-import { structureUnion } from './structure';
+import { structureUnion } from './structure-set';
 import { StructureSubsetBuilder } from '../../structure/util/subset-builder';
 import { ElementIndex } from '../../model';
 

+ 0 - 0
src/mol-model/structure/query/utils/structure.ts → src/mol-model/structure/query/utils/structure-set.ts