From 75956de8cc06c52bcf07273fdc0ff54760697062 Mon Sep 17 00:00:00 2001
From: David Sehnal <david.sehnal@gmail.com>
Date: Thu, 9 Nov 2017 20:38:42 +0100
Subject: [PATCH] assembly generation working

---
 src/mol-math/linear-algebra/3d.ts             |  5 ++
 src/mol-model/structure/model.ts              |  4 +-
 .../structure/model/properties/symmetry.ts    |  2 +-
 src/mol-model/structure/structure.ts          |  3 +-
 src/mol-model/structure/structure/symmetry.ts | 51 +++++++++++++++++++
 src/perf-tests/structure.ts                   | 12 ++++-
 6 files changed, 72 insertions(+), 5 deletions(-)
 create mode 100644 src/mol-model/structure/structure/symmetry.ts

diff --git a/src/mol-math/linear-algebra/3d.ts b/src/mol-math/linear-algebra/3d.ts
index ed1a97900..1609b99cf 100644
--- a/src/mol-math/linear-algebra/3d.ts
+++ b/src/mol-math/linear-algebra/3d.ts
@@ -439,6 +439,11 @@ export namespace Mat4 {
         return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
     }
 
+    /**
+     * Check if the matrix has the form
+     * [ Rotation    Translation ]
+     * [ 0           1           ]
+     */
     export function isRotationAndTranslation(a: Mat4, eps?: number) {
         return _isRotationAndTranslation(a, typeof eps !== 'undefined' ? eps : EPSILON.Value)
     }
diff --git a/src/mol-model/structure/model.ts b/src/mol-model/structure/model.ts
index 4c0002317..c53fd0986 100644
--- a/src/mol-model/structure/model.ts
+++ b/src/mol-model/structure/model.ts
@@ -7,6 +7,6 @@
 import Model from './model/model'
 import * as Types from './model/types'
 import Format from './model/format'
-import Symmetry from './model/properties/symmetry'
+import ModelSymmetry from './model/properties/symmetry'
 
-export { Model, Types, Format, Symmetry }
\ No newline at end of file
+export { Model, Types, Format, ModelSymmetry }
\ No newline at end of file
diff --git a/src/mol-model/structure/model/properties/symmetry.ts b/src/mol-model/structure/model/properties/symmetry.ts
index 994d358de..38303de0e 100644
--- a/src/mol-model/structure/model/properties/symmetry.ts
+++ b/src/mol-model/structure/model/properties/symmetry.ts
@@ -21,7 +21,7 @@ export class Assembly {
     readonly details: string;
 
     private _operators: OperatorGroups;
-    get operators(): OperatorGroups {
+    get operatorGroups(): OperatorGroups {
         if (this._operators) return this._operators;
         this._operators = this.operatorsProvider();
         return this._operators;
diff --git a/src/mol-model/structure/structure.ts b/src/mol-model/structure/structure.ts
index 4fe835cfa..0d5c8bad6 100644
--- a/src/mol-model/structure/structure.ts
+++ b/src/mol-model/structure/structure.ts
@@ -8,5 +8,6 @@ import Atom from './structure/atom'
 import AtomSet from './structure/atom/set'
 import Structure from './structure/structure'
 import Unit from './structure/unit'
+import Symmetry from './structure/symmetry'
 
-export { Atom, AtomSet, Structure, Unit }
\ No newline at end of file
+export { Atom, AtomSet, Structure, Unit, Symmetry }
\ No newline at end of file
diff --git a/src/mol-model/structure/structure/symmetry.ts b/src/mol-model/structure/structure/symmetry.ts
new file mode 100644
index 000000000..2a4ef8c37
--- /dev/null
+++ b/src/mol-model/structure/structure/symmetry.ts
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import Structure from './structure'
+import AtomSet from './atom/set'
+import Unit from './unit'
+import { Selection } from '../query'
+import { ModelSymmetry } from '../model'
+
+namespace Symmetry {
+    export const  buildAssembly = buildAssemblyImpl;
+}
+
+export default Symmetry;
+
+function buildAssemblyImpl(structure: Structure, name: string) {
+    const models = Structure.getModels(structure);
+    if (models.length !== 1) throw new Error('Can only build assemblies from structures based on 1 model.');
+
+    const assembly = ModelSymmetry.findAssembly(models[0], name);
+    if (!assembly) throw new Error(`Assembly '${name}' is not defined.`);
+
+    const { operatorGroups } = assembly;
+
+    const assemblyUnits = Object.create(null);
+    const assemblyAtoms = Object.create(null);
+
+    for (const g of operatorGroups) {
+        const selection = g.selector(structure);
+        if (Selection.structureCount(selection) === 0) continue;
+        const { units, atoms } = Selection.union(selection);
+
+        const unitIds = AtomSet.unitIds(atoms);
+
+        for (const oper of g.operators) {
+            for (let uI = 0, _uI = unitIds.length; uI < _uI; uI++) {
+                const unitId = unitIds[uI];
+                const unit = units[unitId];
+
+                const newUnit = Unit.create(unit.model, oper);
+                assemblyUnits[newUnit.id] = newUnit;
+                assemblyAtoms[newUnit.id] = AtomSet.unitGetByIndex(atoms, uI);
+            }
+        }
+    }
+
+    return Structure.create(assemblyUnits, AtomSet.create(assemblyAtoms));
+}
\ No newline at end of file
diff --git a/src/perf-tests/structure.ts b/src/perf-tests/structure.ts
index e610c871f..5a7e48b41 100644
--- a/src/perf-tests/structure.ts
+++ b/src/perf-tests/structure.ts
@@ -10,7 +10,7 @@ import * as util from 'util'
 import * as fs from 'fs'
 import CIF from 'mol-io/reader/cif'
 
-import { Structure, Model, Queries as Q, Atom, AtomSet, Selection } from 'mol-model/structure'
+import { Structure, Model, Queries as Q, Atom, AtomSet, Selection, Symmetry } from 'mol-model/structure'
 import { OrderedSet as OrdSet, Segmentation } from 'mol-data/int'
 
 import to_mmCIF from 'mol-model/structure/export/mmcif'
@@ -241,6 +241,13 @@ export namespace PropertyAccess {
         console.log(to_mmCIF('test', s));
     }
 
+    export function testAssembly(s: Structure) {
+        const a = Symmetry.buildAssembly(s, '1');
+        fs.writeFileSync('e:/test/molstar/1hrv_assembly.cif', to_mmCIF('test', a, false));
+        console.log('exported');
+        //write(a);
+    }
+
     export async function run() {
         //const { structures, models, mmcif } = await readCIF('./examples/1cbs_full.bcif');
         //const { structures, models, mmcif } = await readCIF('e:/test/quick/3j3q_full.bcif');
@@ -250,6 +257,9 @@ export namespace PropertyAccess {
         //console.log(mmcif.pdbx_struct_oper_list.matrix.toArray());
         // console.log(mmcif.pdbx_struct_oper_list.vector.toArray());
 
+        testAssembly(structures[0]);
+        throw '';
+
         console.log(models[0].symmetry.assemblies);
 
 
-- 
GitLab