Skip to content
Snippets Groups Projects
Commit ed2ca8ae authored by Alexander Rose's avatar Alexander Rose
Browse files

removed Unit.findUnitById, added Unit.SymmetryGroup.unitIndexMap

parent 9152c4e8
No related branches found
No related tags found
No related merge requests found
...@@ -34,6 +34,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis ...@@ -34,6 +34,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
if (!_structure && !structure) { if (!_structure && !structure) {
throw new Error('missing structure') throw new Error('missing structure')
} else if (structure && !_structure) { } else if (structure && !_structure) {
// console.log('initial structure')
// First call with a structure, create visuals for each group. // First call with a structure, create visuals for each group.
_groups = structure.unitSymmetryGroups; _groups = structure.unitSymmetryGroups;
for (let i = 0; i < _groups.length; i++) { for (let i = 0; i < _groups.length; i++) {
...@@ -43,6 +44,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis ...@@ -43,6 +44,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
visuals.set(group.hashCode, { visual, group }) visuals.set(group.hashCode, { visual, group })
} }
} else if (structure && _structure.hashCode !== structure.hashCode) { } else if (structure && _structure.hashCode !== structure.hashCode) {
// console.log('_structure.hashCode !== structure.hashCode')
// Tries to re-use existing visuals for the groups of the new structure. // Tries to re-use existing visuals for the groups of the new structure.
// Creates additional visuals if needed, destroys left-over visuals. // Creates additional visuals if needed, destroys left-over visuals.
_groups = structure.unitSymmetryGroups; _groups = structure.unitSymmetryGroups;
...@@ -77,6 +79,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis ...@@ -77,6 +79,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
// }) // })
// unusedVisuals.forEach(visual => visual.destroy()) // unusedVisuals.forEach(visual => visual.destroy())
} else if (structure && _structure.hashCode === structure.hashCode) { } else if (structure && _structure.hashCode === structure.hashCode) {
// console.log('_structure.hashCode === structure.hashCode')
// Expects that for structures with the same hashCode, // Expects that for structures with the same hashCode,
// the unitSymmetryGroups are the same as well. // the unitSymmetryGroups are the same as well.
// Re-uses existing visuals for the groups of the new structure. // Re-uses existing visuals for the groups of the new structure.
...@@ -92,6 +95,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis ...@@ -92,6 +95,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
} }
} }
} else { } else {
// console.log('no new structure')
// No new structure given, just update all visuals with new props. // No new structure given, just update all visuals with new props.
visuals.forEach(async ({ visual, group }) => { visuals.forEach(async ({ visual, group }) => {
await visual.createOrUpdate(ctx, _props, { group, structure: _structure }) await visual.createOrUpdate(ctx, _props, { group, structure: _structure })
......
...@@ -103,8 +103,8 @@ function markLink(loci: Loci, group: Unit.SymmetryGroup, apply: (interval: Inter ...@@ -103,8 +103,8 @@ function markLink(loci: Loci, group: Unit.SymmetryGroup, apply: (interval: Inter
let changed = false let changed = false
if (Unit.isAtomic(unit) && Link.isLoci(loci)) { if (Unit.isAtomic(unit) && Link.isLoci(loci)) {
for (const b of loci.links) { for (const b of loci.links) {
const unitIdx = Unit.findUnitById(b.aUnit.id, group.units) const unitIdx = group.unitIndexMap.get(b.aUnit.id)
if (unitIdx !== -1) { if (unitIdx !== undefined) {
const idx = unit.links.getDirectedEdgeIndex(b.aIndex, b.bIndex) const idx = unit.links.getDirectedEdgeIndex(b.aIndex, b.bIndex)
if (idx !== -1) { if (idx !== -1) {
if (apply(Interval.ofSingleton(idx))) changed = true if (apply(Interval.ofSingleton(idx))) changed = true
......
...@@ -57,8 +57,8 @@ export function markElement(loci: Loci, group: Unit.SymmetryGroup, apply: (inter ...@@ -57,8 +57,8 @@ export function markElement(loci: Loci, group: Unit.SymmetryGroup, apply: (inter
let changed = false let changed = false
if (StructureElement.isLoci(loci)) { if (StructureElement.isLoci(loci)) {
for (const e of loci.elements) { for (const e of loci.elements) {
const unitIdx = Unit.findUnitById(e.unit.id, group.units) const unitIdx = group.unitIndexMap.get(e.unit.id)
if (unitIdx !== -1) { if (unitIdx !== undefined) {
if (Interval.is(e.indices)) { if (Interval.is(e.indices)) {
const start = unitIdx * elementCount + Interval.start(e.indices); const start = unitIdx * elementCount + Interval.start(e.indices);
const end = unitIdx * elementCount + Interval.end(e.indices); const end = unitIdx * elementCount + Interval.end(e.indices);
......
...@@ -32,6 +32,8 @@ export function getGapRanges(unit: Unit): SortedRanges<ElementIndex> { ...@@ -32,6 +32,8 @@ export function getGapRanges(unit: Unit): SortedRanges<ElementIndex> {
} }
} }
// polymer element
export function getPolymerElementCount(unit: Unit) { export function getPolymerElementCount(unit: Unit) {
let count = 0 let count = 0
const { elements } = unit const { elements } = unit
...@@ -108,6 +110,8 @@ export namespace PolymerLocationIterator { ...@@ -108,6 +110,8 @@ export namespace PolymerLocationIterator {
} }
} }
// polymer gap
export function getPolymerGapCount(unit: Unit) { export function getPolymerGapCount(unit: Unit) {
let count = 0 let count = 0
const { elements } = unit const { elements } = unit
......
...@@ -25,7 +25,9 @@ import { Vec3 } from 'mol-math/linear-algebra'; ...@@ -25,7 +25,9 @@ import { Vec3 } from 'mol-math/linear-algebra';
import { idFactory } from 'mol-util/id-factory'; import { idFactory } from 'mol-util/id-factory';
class Structure { class Structure {
/** Maps unit.id to unit */
readonly unitMap: IntMap<Unit>; readonly unitMap: IntMap<Unit>;
/** Array of all units in the structure, sorted by unit.id */
readonly units: ReadonlyArray<Unit>; readonly units: ReadonlyArray<Unit>;
private _props: { private _props: {
...@@ -67,6 +69,7 @@ class Structure { ...@@ -67,6 +69,7 @@ class Structure {
return hash; return hash;
} }
/** Returns a new element location iterator */
elementLocations(): Iterator<StructureElement> { elementLocations(): Iterator<StructureElement> {
return new Structure.ElementLocationIterator(this); return new Structure.ElementLocationIterator(this);
} }
......
/** /**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
import Structure from './structure' import Structure from './structure'
...@@ -10,7 +11,7 @@ import { ModelSymmetry } from '../model' ...@@ -10,7 +11,7 @@ import { ModelSymmetry } from '../model'
import { Task, RuntimeContext } from 'mol-task'; import { Task, RuntimeContext } from 'mol-task';
import { SortedArray } from 'mol-data/int'; import { SortedArray } from 'mol-data/int';
import Unit from './unit'; import Unit from './unit';
import { EquivalenceClasses, hash2 } from 'mol-data/util'; import { EquivalenceClasses } from 'mol-data/util';
import { Vec3 } from 'mol-math/linear-algebra'; import { Vec3 } from 'mol-math/linear-algebra';
import { SymmetryOperator, Spacegroup, SpacegroupCell } from 'mol-math/geometry'; import { SymmetryOperator, Spacegroup, SpacegroupCell } from 'mol-math/geometry';
...@@ -58,16 +59,12 @@ namespace StructureSymmetry { ...@@ -58,16 +59,12 @@ namespace StructureSymmetry {
return Task.create('Build NCS', ctx => _buildNCS(ctx, structure)); return Task.create('Build NCS', ctx => _buildNCS(ctx, structure));
} }
function hashUnit(u: Unit) {
return hash2(u.invariantId, SortedArray.hashCode(u.elements));
}
export function areUnitsEquivalent(a: Unit, b: Unit) { export function areUnitsEquivalent(a: Unit, b: Unit) {
return a.invariantId === b.invariantId && a.model.id === b.model.id && SortedArray.areEqual(a.elements, b.elements); return a.invariantId === b.invariantId && a.model.id === b.model.id && SortedArray.areEqual(a.elements, b.elements);
} }
export function UnitEquivalenceBuilder() { export function UnitEquivalenceBuilder() {
return EquivalenceClasses<number, Unit>(hashUnit, areUnitsEquivalent); return EquivalenceClasses<number, Unit>(Unit.hashUnit, areUnitsEquivalent);
} }
export function computeTransformGroups(s: Structure): ReadonlyArray<Unit.SymmetryGroup> { export function computeTransformGroups(s: Structure): ReadonlyArray<Unit.SymmetryGroup> {
...@@ -76,12 +73,7 @@ namespace StructureSymmetry { ...@@ -76,12 +73,7 @@ namespace StructureSymmetry {
const ret: Unit.SymmetryGroup[] = []; const ret: Unit.SymmetryGroup[] = [];
for (const eqUnits of groups.groups) { for (const eqUnits of groups.groups) {
const first = s.unitMap.get(eqUnits[0]); ret.push(Unit.SymmetryGroup(eqUnits.map(id => s.unitMap.get(id))))
ret.push({
elements: first.elements,
units: eqUnits.map(id => s.unitMap.get(id)),
hashCode: hashUnit(first)
});
} }
return ret; return ret;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
import { SymmetryOperator } from 'mol-math/geometry/symmetry-operator' import { SymmetryOperator } from 'mol-math/geometry/symmetry-operator'
...@@ -13,6 +14,8 @@ import { ValueRef } from 'mol-util'; ...@@ -13,6 +14,8 @@ import { ValueRef } from 'mol-util';
import { UnitRings } from './unit/rings'; import { UnitRings } from './unit/rings';
import StructureElement from './element' import StructureElement from './element'
import { ChainIndex, ResidueIndex } from '../model/indexing'; import { ChainIndex, ResidueIndex } from '../model/indexing';
import { IntMap, SortedArray } from 'mol-data/int';
import { hash2 } from 'mol-data/util';
// A building block of a structure that corresponds to an atomic or a coarse grained representation // A building block of a structure that corresponds to an atomic or a coarse grained representation
// 'conveniently grouped together'. // 'conveniently grouped together'.
...@@ -36,21 +39,44 @@ namespace Unit { ...@@ -36,21 +39,44 @@ namespace Unit {
/** A group of units that differ only by symmetry operators. */ /** A group of units that differ only by symmetry operators. */
export type SymmetryGroup = { export type SymmetryGroup = {
readonly elements: StructureElement.Set, readonly elements: StructureElement.Set
readonly units: ReadonlyArray<Unit> readonly units: ReadonlyArray<Unit>
/** Maps unit.id to index of unit in units array */
readonly unitIndexMap: IntMap<number>
readonly hashCode: number readonly hashCode: number
} }
function getUnitIndexMap(units: Unit[]) {
const unitIndexMap = IntMap.Mutable<number>();
for (let i = 0, _i = units.length; i < _i; i++) {
unitIndexMap.set(units[i].id, i);
}
return unitIndexMap
}
export function SymmetryGroup(units: Unit[]) {
const props: {
unitIndexMap?: IntMap<number>
} = {}
return {
elements: units[0].elements,
units,
get unitIndexMap () {
if (props.unitIndexMap) return props.unitIndexMap
props.unitIndexMap = getUnitIndexMap(units)
return props.unitIndexMap
},
hashCode: hashUnit(units[0])
}
}
export function conformationId (unit: Unit) { export function conformationId (unit: Unit) {
return Unit.isAtomic(unit) ? unit.model.atomicConformation.id : unit.model.coarseConformation.id 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 hashUnit(u: Unit) {
export function findUnitById(id: number, units: ReadonlyArray<Unit>) { return hash2(u.invariantId, SortedArray.hashCode(u.elements));
for (let i = 0, il = units.length; i < il; ++i) {
if (units[i].id === id) return i
}
return -1
} }
export interface Base { export interface Base {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment