|
@@ -5,7 +5,7 @@
|
|
|
*/
|
|
|
|
|
|
import { Unit, StructureElement, ElementIndex, ResidueIndex, Structure } from '../../../../../mol-model/structure';
|
|
|
-import { Segmentation } from '../../../../../mol-data/int';
|
|
|
+import { Segmentation, SortedArray } from '../../../../../mol-data/int';
|
|
|
import { MoleculeType, SecondaryStructureType } from '../../../../../mol-model/structure/model/types';
|
|
|
import Iterator from '../../../../../mol-data/iterator';
|
|
|
import { Vec3 } from '../../../../../mol-math/linear-algebra';
|
|
@@ -69,12 +69,14 @@ const tmpVecB = Vec3()
|
|
|
|
|
|
export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement> {
|
|
|
private value: PolymerTraceElement
|
|
|
- private polymerIt: SortedRanges.Iterator<ElementIndex, ResidueIndex>
|
|
|
+ private polymerIt: SortedRanges.Iterator<ElementIndex, number>
|
|
|
private residueIt: Segmentation.SegmentIterator<ResidueIndex>
|
|
|
- private polymerSegment: Segmentation.Segment<ResidueIndex>
|
|
|
+ private polymerSegment: Segmentation.Segment<number>
|
|
|
private cyclicPolymerMap: Map<ResidueIndex, ResidueIndex>
|
|
|
private secondaryStructureType: SecondaryStructure['type']
|
|
|
private secondaryStructureGetIndex: SecondaryStructure['getIndex']
|
|
|
+ private residueSegmentBeg: ResidueIndex
|
|
|
+ private residueSegmentEnd: ResidueIndex
|
|
|
private residueSegmentMin: ResidueIndex
|
|
|
private residueSegmentMax: ResidueIndex
|
|
|
private prevSecStrucType: SecondaryStructureType
|
|
@@ -84,6 +86,7 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
|
|
|
private currCoarseBackbone: boolean
|
|
|
private nextCoarseBackbone: boolean
|
|
|
private state: AtomicPolymerTraceIteratorState = AtomicPolymerTraceIteratorState.nextPolymer
|
|
|
+ private polymerRanges: SortedArray<ElementIndex>
|
|
|
private residueAtomSegments: Segmentation<ElementIndex, ResidueIndex>
|
|
|
private traceElementIndex: ArrayLike<ElementIndex>
|
|
|
private directionFromElementIndex: ArrayLike<ElementIndex | -1>
|
|
@@ -114,10 +117,12 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private updateResidueSegmentRange(polymerSegment: Segmentation.Segment<ResidueIndex>) {
|
|
|
+ private updateResidueSegmentRange(polymerSegment: Segmentation.Segment<number>) {
|
|
|
const { index } = this.residueAtomSegments
|
|
|
- this.residueSegmentMin = index[this.unit.elements[polymerSegment.start]]
|
|
|
- this.residueSegmentMax = index[this.unit.elements[polymerSegment.end - 1]]
|
|
|
+ this.residueSegmentBeg = index[this.unit.elements[polymerSegment.start]]
|
|
|
+ this.residueSegmentEnd = index[this.unit.elements[polymerSegment.end - 1]]
|
|
|
+ this.residueSegmentMin = index[this.polymerRanges[polymerSegment.index * 2]]
|
|
|
+ this.residueSegmentMax = index[this.polymerRanges[polymerSegment.index * 2 + 1] - 1]
|
|
|
}
|
|
|
|
|
|
private getResidueIndex(residueIndex: number) {
|
|
@@ -153,9 +158,13 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
|
|
|
}
|
|
|
|
|
|
private setFromToVector(out: Vec3, residueIndex: ResidueIndex) {
|
|
|
- this.pos(tmpVecA, this.directionFromElementIndex[residueIndex])
|
|
|
- this.pos(tmpVecB, this.directionToElementIndex[residueIndex])
|
|
|
- Vec3.sub(out, tmpVecB, tmpVecA)
|
|
|
+ if (this.value.isCoarseBackbone) {
|
|
|
+ Vec3.set(out, 1, 0, 0)
|
|
|
+ } else {
|
|
|
+ this.pos(tmpVecA, this.directionFromElementIndex[residueIndex])
|
|
|
+ this.pos(tmpVecB, this.directionToElementIndex[residueIndex])
|
|
|
+ Vec3.sub(out, tmpVecB, tmpVecA)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private setDirection(out: Vec3, v1: Vec3, v2: Vec3, v3: Vec3) {
|
|
@@ -177,9 +186,9 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
|
|
|
if (residueIt.hasNext) {
|
|
|
this.state = AtomicPolymerTraceIteratorState.nextResidue
|
|
|
this.currSecStrucType = SecStrucTypeNA
|
|
|
- this.nextSecStrucType = this.getSecStruc(this.residueSegmentMin)
|
|
|
+ this.nextSecStrucType = this.getSecStruc(this.residueSegmentBeg)
|
|
|
this.currCoarseBackbone = false
|
|
|
- this.nextCoarseBackbone = this.directionFromElementIndex[this.residueSegmentMin] === -1 || this.directionToElementIndex[this.residueSegmentMin] === -1
|
|
|
+ this.nextCoarseBackbone = this.directionFromElementIndex[this.residueSegmentBeg] === -1 || this.directionToElementIndex[this.residueSegmentBeg] === -1
|
|
|
break
|
|
|
}
|
|
|
}
|
|
@@ -201,9 +210,10 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
|
|
|
value.isCoarseBackbone = this.currCoarseBackbone
|
|
|
value.coarseBackboneFirst = this.prevCoarseBackbone !== this.currCoarseBackbone
|
|
|
value.coarseBackboneLast = this.currCoarseBackbone !== this.nextCoarseBackbone
|
|
|
- value.first = residueIndex === this.residueSegmentMin
|
|
|
- value.last = residueIndex === this.residueSegmentMax
|
|
|
+ value.first = residueIndex === this.residueSegmentBeg
|
|
|
+ value.last = residueIndex === this.residueSegmentEnd
|
|
|
value.moleculeType = this.moleculeType[residueIndex]
|
|
|
+ value.isCoarseBackbone = this.directionFromElementIndex[residueIndex] === -1 || this.directionToElementIndex[residueIndex] === -1
|
|
|
|
|
|
const residueIndexPrev3 = this.getResidueIndex(residueIndex - 3)
|
|
|
const residueIndexPrev2 = this.getResidueIndex(residueIndex - 2)
|
|
@@ -212,39 +222,22 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
|
|
|
const residueIndexNext2 = this.getResidueIndex(residueIndex + 2)
|
|
|
const residueIndexNext3 = this.getResidueIndex(residueIndex + 3)
|
|
|
|
|
|
- if (value.first) {
|
|
|
- value.centerPrev.element = this.traceElementIndex[residueIndexPrev1]
|
|
|
- value.center.element = this.traceElementIndex[residueIndex]
|
|
|
-
|
|
|
- this.pos(this.p0, this.traceElementIndex[residueIndexPrev3])
|
|
|
- this.pos(this.p1, this.traceElementIndex[residueIndexPrev2])
|
|
|
- this.pos(this.p2, this.traceElementIndex[residueIndexPrev1])
|
|
|
- this.pos(this.p3, this.traceElementIndex[residueIndex])
|
|
|
- this.pos(this.p4, this.traceElementIndex[residueIndexNext1])
|
|
|
- this.pos(this.p5, this.traceElementIndex[residueIndexNext2])
|
|
|
-
|
|
|
- this.setFromToVector(this.d01, residueIndexPrev1)
|
|
|
- this.setFromToVector(this.d12, residueIndex)
|
|
|
- this.setFromToVector(this.d23, residueIndexNext1)
|
|
|
- } else {
|
|
|
- value.centerPrev.element = value.center.element
|
|
|
- value.center.element = value.centerNext.element
|
|
|
-
|
|
|
- Vec3.copy(this.p0, this.p1)
|
|
|
- Vec3.copy(this.p1, this.p2)
|
|
|
- Vec3.copy(this.p2, this.p3)
|
|
|
- Vec3.copy(this.p3, this.p4)
|
|
|
- Vec3.copy(this.p4, this.p5)
|
|
|
- Vec3.copy(this.p5, this.p6)
|
|
|
-
|
|
|
- Vec3.copy(this.d01, this.d12)
|
|
|
- Vec3.copy(this.d12, this.d23)
|
|
|
- Vec3.copy(this.d23, this.d34)
|
|
|
- }
|
|
|
+ value.centerPrev.element = this.traceElementIndex[residueIndexPrev1]
|
|
|
+ value.center.element = this.traceElementIndex[residueIndex]
|
|
|
value.centerNext.element = this.traceElementIndex[residueIndexNext1]
|
|
|
+
|
|
|
+ this.pos(this.p0, this.traceElementIndex[residueIndexPrev3])
|
|
|
+ this.pos(this.p1, this.traceElementIndex[residueIndexPrev2])
|
|
|
+ this.pos(this.p2, this.traceElementIndex[residueIndexPrev1])
|
|
|
+ this.pos(this.p3, this.traceElementIndex[residueIndex])
|
|
|
+ this.pos(this.p4, this.traceElementIndex[residueIndexNext1])
|
|
|
+ this.pos(this.p5, this.traceElementIndex[residueIndexNext2])
|
|
|
this.pos(this.p6, this.traceElementIndex[residueIndexNext3])
|
|
|
+
|
|
|
+ this.setFromToVector(this.d01, residueIndexPrev1)
|
|
|
+ this.setFromToVector(this.d12, residueIndex)
|
|
|
+ this.setFromToVector(this.d23, residueIndexNext1)
|
|
|
this.setFromToVector(this.d34, residueIndexNext2)
|
|
|
- value.isCoarseBackbone = this.directionFromElementIndex[residueIndex] === -1 || this.directionToElementIndex[residueIndex] === -1
|
|
|
|
|
|
this.setControlPoint(value.p0, this.p0, this.p1, this.p2, residueIndexPrev2)
|
|
|
this.setControlPoint(value.p1, this.p1, this.p2, this.p3, residueIndexPrev1)
|
|
@@ -268,12 +261,13 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
|
|
|
constructor(private unit: Unit.Atomic, structure: Structure) {
|
|
|
this.atomicConformation = unit.model.atomicConformation
|
|
|
this.residueAtomSegments = unit.model.atomicHierarchy.residueAtomSegments
|
|
|
+ this.polymerRanges = unit.model.atomicHierarchy.polymerRanges
|
|
|
this.traceElementIndex = unit.model.atomicHierarchy.derived.residue.traceElementIndex as ArrayLike<ElementIndex> // can assume it won't be -1 for polymer residues
|
|
|
this.directionFromElementIndex = unit.model.atomicHierarchy.derived.residue.directionFromElementIndex
|
|
|
this.directionToElementIndex = unit.model.atomicHierarchy.derived.residue.directionToElementIndex
|
|
|
this.moleculeType = unit.model.atomicHierarchy.derived.residue.moleculeType
|
|
|
this.cyclicPolymerMap = unit.model.atomicHierarchy.cyclicPolymerMap
|
|
|
- this.polymerIt = SortedRanges.transientSegments(getPolymerRanges(unit), unit.elements)
|
|
|
+ this.polymerIt = SortedRanges.transientSegments(this.polymerRanges, unit.elements)
|
|
|
this.residueIt = Segmentation.transientSegments(this.residueAtomSegments, unit.elements);
|
|
|
this.value = createPolymerTraceElement(unit)
|
|
|
this.hasNext = this.residueIt.hasNext && this.polymerIt.hasNext
|
|
@@ -359,6 +353,8 @@ export class CoarsePolymerTraceIterator implements Iterator<PolymerTraceElement>
|
|
|
constructor(private unit: Unit.Spheres | Unit.Gaussians, structure: Structure) {
|
|
|
this.polymerIt = SortedRanges.transientSegments(getPolymerRanges(unit), unit.elements);
|
|
|
this.value = createPolymerTraceElement(unit)
|
|
|
+ Vec3.set(this.value.d12, 1, 0, 0)
|
|
|
+ Vec3.set(this.value.d23, 1, 0, 0)
|
|
|
switch (unit.kind) {
|
|
|
case Unit.Kind.Spheres: this.conformation = unit.model.coarseConformation.spheres; break
|
|
|
case Unit.Kind.Gaussians: this.conformation = unit.model.coarseConformation.gaussians; break
|