From 4ec57eb89befa08072acf6573d7d0348239e89d5 Mon Sep 17 00:00:00 2001
From: David Sehnal <david.sehnal@gmail.com>
Date: Thu, 23 Aug 2018 17:15:34 +0200
Subject: [PATCH] mol-model/query intersectBy, exceptBy, union

---
 .../structure/query/queries/filters.ts        |  2 +-
 .../structure/query/queries/generators.ts     |  2 +-
 .../structure/query/queries/modifiers.ts      | 56 +++++++++++++++++--
 src/mol-model/structure/query/selection.ts    |  2 +-
 .../structure/query/utils/builders.ts         |  2 +-
 .../utils/{structure.ts => structure-set.ts}  |  0
 6 files changed, 54 insertions(+), 10 deletions(-)
 rename src/mol-model/structure/query/utils/{structure.ts => structure-set.ts} (100%)

diff --git a/src/mol-model/structure/query/queries/filters.ts b/src/mol-model/structure/query/queries/filters.ts
index a84879bbf..60c47c067 100644
--- a/src/mol-model/structure/query/queries/filters.ts
+++ b/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';
 
diff --git a/src/mol-model/structure/query/queries/generators.ts b/src/mol-model/structure/query/queries/generators.ts
index e24ae2589..9a75838c9 100644
--- a/src/mol-model/structure/query/queries/generators.ts
+++ b/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);
diff --git a/src/mol-model/structure/query/queries/modifiers.ts b/src/mol-model/structure/query/queries/modifiers.ts
index 0756c86f3..c249fa266 100644
--- a/src/mol-model/structure/query/queries/modifiers.ts
+++ b/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
\ No newline at end of file
+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
\ No newline at end of file
diff --git a/src/mol-model/structure/query/selection.ts b/src/mol-model/structure/query/selection.ts
index c4c804faf..650c0ae04 100644
--- a/src/mol-model/structure/query/selection.ts
+++ b/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
diff --git a/src/mol-model/structure/query/utils/builders.ts b/src/mol-model/structure/query/utils/builders.ts
index c27ff79ef..9da400cba 100644
--- a/src/mol-model/structure/query/utils/builders.ts
+++ b/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';
 
diff --git a/src/mol-model/structure/query/utils/structure.ts b/src/mol-model/structure/query/utils/structure-set.ts
similarity index 100%
rename from src/mol-model/structure/query/utils/structure.ts
rename to src/mol-model/structure/query/utils/structure-set.ts
-- 
GitLab