From 50e69ca41a0d9c185cb2864a34464f40bbc3d6f1 Mon Sep 17 00:00:00 2001
From: Alexander Rose <alex.rose@rcsb.org>
Date: Tue, 28 Aug 2018 19:51:51 -0700
Subject: [PATCH] tweaked model and unit creation w.r.t. ids

---
 src/mol-model/structure/model/formats/mmcif.ts |  7 ++++++-
 src/mol-model/structure/structure/structure.ts | 10 ++++++++--
 src/mol-model/structure/structure/unit.ts      | 15 ++++++++-------
 3 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/src/mol-model/structure/model/formats/mmcif.ts b/src/mol-model/structure/model/formats/mmcif.ts
index 43e072d46..cb9ddfa8c 100644
--- a/src/mol-model/structure/model/formats/mmcif.ts
+++ b/src/mol-model/structure/model/formats/mmcif.ts
@@ -141,7 +141,12 @@ function getFormatData(format: mmCIF_Format): FormatData {
 function createStandardModel(format: mmCIF_Format, atom_site: AtomSite, entities: Entities, formatData: FormatData, previous?: Model): Model {
     const atomic = getAtomicHierarchyAndConformation(format, atom_site, entities, formatData, previous);
     if (previous && atomic.sameAsPrevious) {
-        return { ...previous, atomicConformation: atomic.conformation };
+        return {
+            ...previous,
+            id: UUID.create(),
+            modelNum: atom_site.pdbx_PDB_model_num.value(0),
+            atomicConformation: atomic.conformation
+        };
     }
 
     const coarse = EmptyIHMCoarse;
diff --git a/src/mol-model/structure/structure/structure.ts b/src/mol-model/structure/structure/structure.ts
index 7113f640b..f14a7eec3 100644
--- a/src/mol-model/structure/structure/structure.ts
+++ b/src/mol-model/structure/structure/structure.ts
@@ -8,7 +8,7 @@ import { IntMap, SortedArray, Iterator, Segmentation } from 'mol-data/int'
 import { UniqueArray } from 'mol-data/generic'
 import { SymmetryOperator } from 'mol-math/geometry/symmetry-operator'
 import { Model, ElementIndex } from '../model'
-import { sort, arraySwap, hash1, sortArray } from 'mol-data/util';
+import { sort, arraySwap, hash1, sortArray, hashString } from 'mol-data/util';
 import StructureElement from './element'
 import Unit from './unit'
 import { StructureLookup3D } from './util/lookup3d';
@@ -22,6 +22,7 @@ import { ResidueIndex } from '../model/indexing';
 import { Carbohydrates } from './carbohydrates/data';
 import { computeCarbohydrates } from './carbohydrates/compute';
 import { Vec3 } from 'mol-math/linear-algebra';
+import { idFactory } from 'mol-util/id-factory';
 
 class Structure {
     readonly unitMap: IntMap<Unit>;
@@ -192,9 +193,10 @@ namespace Structure {
 
     export class StructureBuilder {
         private units: Unit[] = [];
+        private invariantId = idFactory()
 
         addUnit(kind: Unit.Kind, model: Model, operator: SymmetryOperator, elements: StructureElement.Set): Unit {
-            const unit = Unit.create(this.units.length, kind, model, operator, elements);
+            const unit = Unit.create(this.units.length, this.invariantId(), kind, model, operator, elements);
             this.units.push(unit);
             return unit;
         }
@@ -220,6 +222,10 @@ namespace Structure {
         return s.hashCode;
     }
 
+    export function conformationHash(s: Structure) {
+        return hashString(s.units.map(u => Unit.conformationId(u)).join('|'))
+    }
+
     export function areEqual(a: Structure, b: Structure) {
         if (a.elementCount !== b.elementCount) return false;
         const len = a.units.length;
diff --git a/src/mol-model/structure/structure/unit.ts b/src/mol-model/structure/structure/unit.ts
index 3bb205123..5cb3aeae4 100644
--- a/src/mol-model/structure/structure/unit.ts
+++ b/src/mol-model/structure/structure/unit.ts
@@ -7,7 +7,6 @@
 import { SymmetryOperator } from 'mol-math/geometry/symmetry-operator'
 import { Model } from '../model'
 import { GridLookup3D, Lookup3D } from 'mol-math/geometry'
-import { idFactory } from 'mol-util/id-factory';
 import { IntraUnitLinks, computeIntraUnitBonds } from './unit/links'
 import { CoarseElements, CoarseSphereConformation, CoarseGaussianConformation } from '../model/properties/coarse';
 import { ValueRef } from 'mol-util';
@@ -27,11 +26,11 @@ namespace Unit {
     export function isSpheres(u: Unit): u is Spheres { return u.kind === Kind.Spheres; }
     export function isGaussians(u: Unit): u is Gaussians { return u.kind === Kind.Gaussians; }
 
-    export function create(id: number, kind: Kind, model: Model, operator: SymmetryOperator, elements: StructureElement.Set): Unit {
+    export function create(id: number, invariantId: number, kind: Kind, model: Model, operator: SymmetryOperator, elements: StructureElement.Set): Unit {
         switch (kind) {
-            case Kind.Atomic: return new Atomic(id, unitIdFactory(), model, elements, SymmetryOperator.createMapping(operator, model.atomicConformation, void 0), AtomicProperties());
-            case Kind.Spheres: return createCoarse(id, unitIdFactory(), model, Kind.Spheres, elements, SymmetryOperator.createMapping(operator, model.coarseConformation.spheres, getSphereRadiusFunc(model)));
-            case Kind.Gaussians: return createCoarse(id, unitIdFactory(), model, Kind.Gaussians, elements, SymmetryOperator.createMapping(operator, model.coarseConformation.gaussians, getGaussianRadiusFunc(model)));
+            case Kind.Atomic: return new Atomic(id, invariantId, model, elements, SymmetryOperator.createMapping(operator, model.atomicConformation, void 0), AtomicProperties());
+            case Kind.Spheres: return createCoarse(id, invariantId, model, Kind.Spheres, elements, SymmetryOperator.createMapping(operator, model.coarseConformation.spheres, getSphereRadiusFunc(model)));
+            case Kind.Gaussians: return createCoarse(id, invariantId, model, Kind.Gaussians, elements, SymmetryOperator.createMapping(operator, model.coarseConformation.gaussians, getGaussianRadiusFunc(model)));
         }
     }
 
@@ -42,6 +41,10 @@ namespace Unit {
         readonly hashCode: number
     }
 
+    export function conformationId (unit: Unit) {
+        return Unit.isAtomic(unit) ? unit.model.atomicConformation.id : unit.model.coarseConformation.id
+    }
+
     /** Find index of unit with given id, returns -1 if not found */
     export function findUnitById(id: number, units: ReadonlyArray<Unit>) {
         for (let i = 0, il = units.length; i < il; ++i) {
@@ -74,8 +77,6 @@ namespace Unit {
         return (i: number) => 0;
     }
 
-    const unitIdFactory = idFactory();
-
     // A bulding block of a structure that corresponds
     // to a "natural group of atoms" (most often a "chain")
     // together with a tranformation (rotation and translation)
-- 
GitLab