From 74c8e512a785fc6666197ebe2d07a666b15d736c Mon Sep 17 00:00:00 2001 From: Alexander Rose <alex.rose@rcsb.org> Date: Wed, 11 Dec 2019 15:22:08 -0800 Subject: [PATCH] add Structure.atomicResidueCount & SerialMapping.getSerialIndex --- .../structure/structure/structure.ts | 50 ++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/src/mol-model/structure/structure/structure.ts b/src/mol-model/structure/structure/structure.ts index 702a73db1..c24710a96 100644 --- a/src/mol-model/structure/structure/structure.ts +++ b/src/mol-model/structure/structure/structure.ts @@ -5,7 +5,7 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { IntMap, SortedArray, Iterator, Segmentation, Interval } from '../../../mol-data/int' +import { IntMap, SortedArray, Iterator, Segmentation, Interval, OrderedSet } from '../../../mol-data/int' import { UniqueArray } from '../../../mol-data/generic' import { SymmetryOperator } from '../../../mol-math/geometry/symmetry-operator' import { Model, ElementIndex } from '../model' @@ -59,6 +59,7 @@ class Structure { elementCount: number, bondCount: number, uniqueElementCount: number, + atomicResidueCount: number, polymerResidueCount: number, polymerUnitCount: number, coordinateSystem: SymmetryOperator, @@ -71,6 +72,7 @@ class Structure { elementCount: -1, bondCount: -1, uniqueElementCount: -1, + atomicResidueCount: -1, polymerResidueCount: -1, polymerUnitCount: -1, coordinateSystem: SymmetryOperator.Default, @@ -140,6 +142,13 @@ class Structure { return this._props.uniqueElementCount; } + get atomicResidueCount() { + if (this._props.atomicResidueCount === -1) { + this._props.atomicResidueCount = getAtomicResidueCount(this) + } + return this._props.atomicResidueCount; + } + /** Coarse structure, defined as Containing less than twice as many elements as polymer residues */ get isCoarse() { const ec = this.elementCount @@ -253,7 +262,8 @@ class Structure { } get entityIndices() { - return this._props.entityIndices || (this._props.entityIndices = getEntityIndices(this)); + return this._props.entityIndices + || (this._props.entityIndices = getEntityIndices(this)); } get uniqueAtomicResidueIndices() { @@ -470,16 +480,38 @@ function getPolymerUnitCount(structure: Structure): number { return polymerUnitCount } +function getAtomicResidueCount(structure: Structure): number { + const { units } = structure + let atomicResidueCount = 0 + for (let i = 0, _i = units.length; i < _i; i++) { + const unit = units[i] + if (!Unit.isAtomic(unit)) continue + const { elements, residueIndex } = unit + let idx = -1 + let prevIdx = -1 + for (let j = 0, jl = elements.length; j < jl; ++j) { + idx = residueIndex[elements[j]] + if (idx !== prevIdx) { + atomicResidueCount += 1 + prevIdx = idx + } + } + } + return atomicResidueCount +} + interface SerialMapping { - /** Cumulative count of elements for each unit */ + /** Cumulative count of preceding elements for each unit */ cumulativeUnitElementCount: ArrayLike<number> /** Unit index for each serial element in the structure */ unitIndices: ArrayLike<number> /** Element index for each serial element in the structure */ elementIndices: ArrayLike<ElementIndex> + /** Get serial index of element in the structure */ + getSerialIndex: (unit: Unit, element: ElementIndex) => Structure.SerialIndex } function getSerialMapping(structure: Structure): SerialMapping { - const { units, elementCount } = structure + const { units, elementCount, unitIndexMap } = structure const cumulativeUnitElementCount = new Uint32Array(units.length) const unitIndices = new Uint32Array(elementCount) const elementIndices = new Uint32Array(elementCount) as unknown as ElementIndex[] @@ -493,7 +525,13 @@ function getSerialMapping(structure: Structure): SerialMapping { } m += elements.length } - return { cumulativeUnitElementCount, unitIndices, elementIndices } + return { + cumulativeUnitElementCount, + unitIndices, + elementIndices, + + getSerialIndex: (unit, element) => cumulativeUnitElementCount[unitIndexMap.get(unit.id)] + OrderedSet.indexOf(unit.elements, element) as Structure.SerialIndex + } } namespace Structure { @@ -776,7 +814,7 @@ namespace Structure { return hashString(s.units.map(u => Unit.conformationId(u)).join('|')) } - // TODO: there should be a version that property supports partitioned units + // TODO: there should be a version that properly supports partitioned units export function areUnitAndIndicesEqual(a: Structure, b: Structure) { if (a === b) return true; -- GitLab