From 57f577953124d6ada15facc8c997a0bd52891380 Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Tue, 9 Apr 2019 13:53:51 +0200 Subject: [PATCH] mol-model: added parent & coordinate system to Structure --- .../structure/query/queries/filters.ts | 2 +- .../structure/query/queries/generators.ts | 8 +-- .../structure/query/queries/internal.ts | 8 +-- src/mol-model/structure/query/selection.ts | 2 +- .../structure/query/utils/structure-set.ts | 4 +- .../structure/structure/structure.ts | 55 +++++++++++++++---- src/mol-model/structure/structure/symmetry.ts | 6 +- .../structure/util/subset-builder.ts | 2 +- .../structure/util/unique-subset-builder.ts | 2 +- 9 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/mol-model/structure/query/queries/filters.ts b/src/mol-model/structure/query/queries/filters.ts index 17200a1bf..4b08350f6 100644 --- a/src/mol-model/structure/query/queries/filters.ts +++ b/src/mol-model/structure/query/queries/filters.ts @@ -38,7 +38,7 @@ export function first(query: StructureQuery): StructureQuery { if (sel.kind === 'singletons') { if (sel.structure.elementCount > 0) { const u = sel.structure.units[0]; - const s = Structure.create([u.getChild(SortedArray.ofSingleton(u.elements[0]))]); + const s = Structure.create([u.getChild(SortedArray.ofSingleton(u.elements[0]))], ctx.inputStructure); ret.add(s); } } else { diff --git a/src/mol-model/structure/query/queries/generators.ts b/src/mol-model/structure/query/queries/generators.ts index 34ce3fd62..24f49db0f 100644 --- a/src/mol-model/structure/query/queries/generators.ts +++ b/src/mol-model/structure/query/queries/generators.ts @@ -168,10 +168,10 @@ function atomGroupsGrouped({ entityTest, chainTest, residueTest, atomTest, group }; } -function getRingStructure(unit: Unit.Atomic, ring: UnitRing) { +function getRingStructure(unit: Unit.Atomic, ring: UnitRing, inputStructure: Structure) { const elements = new Int32Array(ring.length) as any as ElementIndex[]; for (let i = 0, _i = ring.length; i < _i; i++) elements[i] = unit.elements[ring[i]]; - return Structure.create([unit.getChild(SortedArray.ofSortedArray(elements))]) + return Structure.create([unit.getChild(SortedArray.ofSortedArray(elements))], inputStructure); } export function rings(fingerprints?: ArrayLike<UnitRing.Fingerprint>): StructureQuery { @@ -184,7 +184,7 @@ export function rings(fingerprints?: ArrayLike<UnitRing.Fingerprint>): Structure if (!Unit.isAtomic(u)) continue; for (const r of u.rings.all) { - ret.add(getRingStructure(u, r)); + ret.add(getRingStructure(u, r, ctx.inputStructure)); } } } else { @@ -198,7 +198,7 @@ export function rings(fingerprints?: ArrayLike<UnitRing.Fingerprint>): Structure for (const fp of uniqueFps.array) { if (!rings.byFingerprint.has(fp)) continue; for (const r of rings.byFingerprint.get(fp)!) { - ret.add(getRingStructure(u, rings.all[r])); + ret.add(getRingStructure(u, rings.all[r], ctx.inputStructure)); } } } diff --git a/src/mol-model/structure/query/queries/internal.ts b/src/mol-model/structure/query/queries/internal.ts index 8cf107811..d451ca422 100644 --- a/src/mol-model/structure/query/queries/internal.ts +++ b/src/mol-model/structure/query/queries/internal.ts @@ -35,7 +35,7 @@ export function atomicSequence(): StructureQuery { units.push(unit); } - return StructureSelection.Singletons(inputStructure, new Structure(units)); + return StructureSelection.Singletons(inputStructure, new Structure(units, inputStructure, )); }; } @@ -54,7 +54,7 @@ export function water(): StructureQuery { if (P.entity.type(l) !== 'water') continue; units.push(unit); } - return StructureSelection.Singletons(inputStructure, new Structure(units)); + return StructureSelection.Singletons(inputStructure, new Structure(units, inputStructure)); }; } @@ -84,7 +84,7 @@ export function atomicHet(): StructureQuery { units.push(unit); } - return StructureSelection.Singletons(inputStructure, new Structure(units)); + return StructureSelection.Singletons(inputStructure, new Structure(units, inputStructure)); }; } @@ -97,6 +97,6 @@ export function spheres(): StructureQuery { if (unit.kind !== Unit.Kind.Spheres) continue; units.push(unit); } - return StructureSelection.Singletons(inputStructure, new Structure(units)); + return StructureSelection.Singletons(inputStructure, new Structure(units, inputStructure)); }; } diff --git a/src/mol-model/structure/query/selection.ts b/src/mol-model/structure/query/selection.ts index c13c370da..9fe6201be 100644 --- a/src/mol-model/structure/query/selection.ts +++ b/src/mol-model/structure/query/selection.ts @@ -135,7 +135,7 @@ namespace StructureSelection { const { elements } = unit; for (let i = 0, _i = elements.length; i < _i; i++) { // TODO: optimize this somehow??? - const s = Structure.create([unit.getChild(SortedArray.ofSingleton(elements[i]))]); + const s = Structure.create([unit.getChild(SortedArray.ofSingleton(elements[i]))], sel.source); fn(s, idx++); } } diff --git a/src/mol-model/structure/query/utils/structure-set.ts b/src/mol-model/structure/query/utils/structure-set.ts index 0ab6a9bbf..4f61dbc78 100644 --- a/src/mol-model/structure/query/utils/structure-set.ts +++ b/src/mol-model/structure/query/utils/structure-set.ts @@ -80,7 +80,7 @@ export function structureIntersect(sA: Structure, sB: Structure): Structure { } } - return Structure.create(units); + return Structure.create(units, sA.parent || sB.parent); } export function structureSubtract(a: Structure, b: Structure): Structure { @@ -100,5 +100,5 @@ export function structureSubtract(a: Structure, b: Structure): Structure { } } - return Structure.create(units); + return Structure.create(units, a.parent || b.parent); } \ No newline at end of file diff --git a/src/mol-model/structure/structure/structure.ts b/src/mol-model/structure/structure/structure.ts index f3bde2da2..b344d0e67 100644 --- a/src/mol-model/structure/structure/structure.ts +++ b/src/mol-model/structure/structure/structure.ts @@ -34,6 +34,7 @@ class Structure { readonly units: ReadonlyArray<Unit>; private _props: { + parent?: Structure, lookup3d?: StructureLookup3D, links?: InterUnitBonds, crossLinkRestraints?: PairRestraints<CrossLinkRestraint>, @@ -49,7 +50,14 @@ class Structure { transformHash: number, elementCount: number, polymerResidueCount: number, - } = { hashCode: -1, transformHash: -1, elementCount: 0, polymerResidueCount: 0 }; + coordinateSystem: SymmetryOperator + } = { + hashCode: -1, + transformHash: -1, + elementCount: 0, + polymerResidueCount: 0, + coordinateSystem: SymmetryOperator.Default + }; subsetBuilder(isSorted: boolean) { return new StructureSubsetBuilder(this, isSorted); @@ -106,6 +114,14 @@ class Structure { return new Structure.ElementLocationIterator(this); } + get parent() { + return this._props.parent; + } + + get coordinateSystem() { + return this._props.coordinateSystem; + } + get boundary() { return this.lookup3d.boundary; } @@ -174,7 +190,7 @@ class Structure { return SortedArray.has(this.unitMap.get(e.unit.id).elements, e.element); } - constructor(units: ArrayLike<Unit>) { + private initUnits(units: ArrayLike<Unit>) { const map = IntMap.Mutable<Unit>(); let elementCount = 0; let polymerResidueCount = 0; @@ -188,11 +204,18 @@ class Structure { if (u.id < lastId) isSorted = false; lastId = u.id; } - if (!isSorted) sort(units, 0, units.length, cmpUnits, arraySwap) - this.unitMap = map; - this.units = units as ReadonlyArray<Unit>; + if (!isSorted) sort(units, 0, units.length, cmpUnits, arraySwap); this._props.elementCount = elementCount; this._props.polymerResidueCount = polymerResidueCount; + return map; + } + + constructor(units: ArrayLike<Unit>, parent: Structure | undefined, coordinateSystem?: SymmetryOperator) { + this.unitMap = this.initUnits(units); + this.units = units as ReadonlyArray<Unit>; + if (parent) this._props.parent = parent; + if (coordinateSystem) this._props.coordinateSystem = coordinateSystem; + else if (parent) this._props.coordinateSystem = parent.coordinateSystem; } } @@ -283,7 +306,7 @@ function getUniqueAtomicResidueIndices(structure: Structure): ReadonlyMap<UUID, } namespace Structure { - export const Empty = new Structure([]); + export const Empty = new Structure([], void 0, void 0); /** Represents a single structure */ export interface Loci { @@ -302,7 +325,9 @@ namespace Structure { return a.structure === b.structure } - export function create(units: ReadonlyArray<Unit>): Structure { return new Structure(units); } + export function create(units: ReadonlyArray<Unit>, parent: Structure | undefined, coordinateSystem?: SymmetryOperator): Structure { + return new Structure(units, parent, coordinateSystem); + } /** * Construct a Structure from a model. @@ -312,7 +337,7 @@ namespace Structure { */ export function ofModel(model: Model): Structure { const chains = model.atomicHierarchy.chainAtomSegments; - const builder = new StructureBuilder(); + const builder = new StructureBuilder(void 0, void 0); for (let c = 0; c < chains.count; c++) { const start = chains.offsets[c]; @@ -385,7 +410,9 @@ namespace Structure { units.push(u.applyOperator(u.id, op)); } - return new Structure(units); + const cs = s.coordinateSystem; + const newCS = SymmetryOperator.compose(SymmetryOperator.create(cs.name, transform, cs.assembly, cs.ncsId, cs.hkl), cs); + return new Structure(units, s, newCS); } export class StructureBuilder { @@ -405,15 +432,21 @@ namespace Structure { } getStructure(): Structure { - return create(this.units); + return create(this.units, this.parent, this.coordinateSystem); } get isEmpty() { return this.units.length === 0; } + + constructor(private parent: Structure | undefined, private coordinateSystem: SymmetryOperator | undefined) { + + } } - export function Builder() { return new StructureBuilder(); } + export function Builder(parent: Structure | undefined, coordinateSystem: SymmetryOperator | undefined) { + return new StructureBuilder(parent, coordinateSystem); + } export function hashCode(s: Structure) { return s.hashCode; diff --git a/src/mol-model/structure/structure/symmetry.ts b/src/mol-model/structure/structure/symmetry.ts index 4f4cfe6f6..eee13f1b6 100644 --- a/src/mol-model/structure/structure/symmetry.ts +++ b/src/mol-model/structure/structure/symmetry.ts @@ -24,7 +24,7 @@ namespace StructureSymmetry { const assembly = ModelSymmetry.findAssembly(models[0], asmName); if (!assembly) throw new Error(`Assembly '${asmName}' is not defined.`); - const assembler = Structure.Builder(); + const assembler = Structure.Builder(void 0, SymmetryOperator.create(assembly.id, Mat4.identity(), { id: assembly.id, operList: [] })); const queryCtx = new QueryContext(structure); @@ -137,7 +137,7 @@ function getOperatorsCached333(symmetry: ModelSymmetry) { } function assembleOperators(structure: Structure, operators: ReadonlyArray<SymmetryOperator>) { - const assembler = Structure.Builder(); + const assembler = Structure.Builder(void 0, void 0); const { units } = structure; for (const oper of operators) { for (const unit of units) { @@ -179,7 +179,7 @@ async function findMatesRadius(ctx: RuntimeContext, structure: Structure, radius const operators = getOperatorsCached333(symmetry); const lookup = structure.lookup3d; - const assembler = Structure.Builder(); + const assembler = Structure.Builder(void 0, void 0); const { units } = structure; const center = Vec3.zero(); diff --git a/src/mol-model/structure/structure/util/subset-builder.ts b/src/mol-model/structure/structure/util/subset-builder.ts index 77c228902..dbdf0cf77 100644 --- a/src/mol-model/structure/structure/util/subset-builder.ts +++ b/src/mol-model/structure/structure/util/subset-builder.ts @@ -90,7 +90,7 @@ export class StructureSubsetBuilder { newUnits[newUnits.length] = child; } - return Structure.create(newUnits); + return Structure.create(newUnits, this.parent); } getStructure() { diff --git a/src/mol-model/structure/structure/util/unique-subset-builder.ts b/src/mol-model/structure/structure/util/unique-subset-builder.ts index bc18e6519..8b808e246 100644 --- a/src/mol-model/structure/structure/util/unique-subset-builder.ts +++ b/src/mol-model/structure/structure/util/unique-subset-builder.ts @@ -85,7 +85,7 @@ export class StructureUniqueSubsetBuilder { newUnits[newUnits.length] = child; } - return Structure.create(newUnits); + return Structure.create(newUnits, this.parent, this.parent.coordinateSystem); } get isEmpty() { -- GitLab