|
@@ -5,11 +5,12 @@
|
|
|
*/
|
|
|
|
|
|
import { Unit, StructureElement, Model, ElementIndex, ResidueIndex } from 'mol-model/structure';
|
|
|
-import { Segmentation, OrderedSet, Interval } from 'mol-data/int';
|
|
|
+import { Segmentation, OrderedSet, Interval, 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';
|
|
|
import SortedRanges from 'mol-data/int/sorted-ranges';
|
|
|
+import { CoarseSphereConformation, CoarseGaussianConformation } from 'mol-model/structure/model/properties/coarse';
|
|
|
|
|
|
export function getPolymerRanges(unit: Unit): SortedRanges<ElementIndex> {
|
|
|
switch (unit.kind) {
|
|
@@ -71,25 +72,25 @@ function getResidueTypeAtomId(moleculeType: MoleculeType, atomType: 'trace' | 'd
|
|
|
return ''
|
|
|
}
|
|
|
|
|
|
-function getMoleculeType(model: Model, residueIndex: number) {
|
|
|
+function getMoleculeType(model: Model, residueIndex: ResidueIndex) {
|
|
|
const compId = model.atomicHierarchy.residues.label_comp_id.value(residueIndex)
|
|
|
const chemCompMap = model.properties.chemicalComponentMap
|
|
|
const cc = chemCompMap.get(compId)
|
|
|
return cc ? cc.moleculeType : MoleculeType.unknown
|
|
|
}
|
|
|
|
|
|
-function getElementIndexForAtomId(unit: Unit.Atomic, residueSegment: Segmentation.Segment, atomId: string) {
|
|
|
- const elements = unit.elements
|
|
|
- const { label_atom_id } = unit.model.atomicHierarchy.atoms
|
|
|
- for (let j = residueSegment.start, _j = residueSegment.end; j < _j; j++) {
|
|
|
- if (label_atom_id.value(elements[j]) === atomId) return j as ElementIndex
|
|
|
+function getElementIndexForAtomId(model: Model, rI: ResidueIndex, atomId: string): ElementIndex {
|
|
|
+ const { offsets } = model.atomicHierarchy.residueAtomSegments
|
|
|
+ const { label_atom_id } = model.atomicHierarchy.atoms
|
|
|
+ for (let j = offsets[rI], _j = offsets[rI + 1]; j < _j; j++) {
|
|
|
+ if (label_atom_id.value(j) === atomId) return j as ElementIndex
|
|
|
}
|
|
|
- return residueSegment.end - 1 as ElementIndex
|
|
|
+ return offsets[rI] as ElementIndex
|
|
|
}
|
|
|
|
|
|
-function getResidueTypeAtomIdElementIndex(unit: Unit.Atomic, residueSegment: Segmentation.Segment, type: 'trace' | 'direction') {
|
|
|
- const atomId = getResidueTypeAtomId(getMoleculeType(unit.model, residueSegment.index), type)
|
|
|
- return getElementIndexForAtomId(unit, residueSegment, atomId)
|
|
|
+function getElementIndexForResidueTypeAtomId(model: Model, rI: ResidueIndex, atomType: 'trace' | 'direction') {
|
|
|
+ const atomId = getResidueTypeAtomId(getMoleculeType(model, rI), atomType)
|
|
|
+ return getElementIndexForAtomId(model, rI, atomId)
|
|
|
}
|
|
|
|
|
|
// function residueLabel(model: Model, rI: number) {
|
|
@@ -124,21 +125,32 @@ function createPolymerBackbonePair (unit: Unit) {
|
|
|
|
|
|
const enum AtomicPolymerBackboneIteratorState { nextPolymer, firstResidue, nextResidue }
|
|
|
|
|
|
-export class AtomicPolymerBackboneIterator<T extends number = number> implements Iterator<PolymerBackbonePair> {
|
|
|
+export class AtomicPolymerBackboneIterator implements Iterator<PolymerBackbonePair> {
|
|
|
private value: PolymerBackbonePair
|
|
|
- private polymerIt: SortedRanges.Iterator<ElementIndex>
|
|
|
+ private polymerIt: SortedRanges.Iterator<ElementIndex, ResidueIndex>
|
|
|
private residueIt: Segmentation.SegmentIterator<ResidueIndex>
|
|
|
private state: AtomicPolymerBackboneIteratorState = AtomicPolymerBackboneIteratorState.nextPolymer
|
|
|
hasNext: boolean = false;
|
|
|
|
|
|
+ getElementIndex(residueIndex: ResidueIndex, atomType: 'trace' | 'direction') {
|
|
|
+ const index = getElementIndexForResidueTypeAtomId(this.unit.model, residueIndex, atomType)
|
|
|
+ // // TODO handle case when it returns -1
|
|
|
+ // return SortedArray.indexOf(this.unit.elements, index) as ElementIndex
|
|
|
+
|
|
|
+ const elementIndex = SortedArray.indexOf(this.unit.elements, index) as ElementIndex
|
|
|
+ if (elementIndex === -1) {
|
|
|
+ console.log('-1', residueIndex, atomType, index)
|
|
|
+ }
|
|
|
+ return elementIndex === -1 ? 0 as ElementIndex : elementIndex
|
|
|
+ }
|
|
|
+
|
|
|
move() {
|
|
|
if (this.state === AtomicPolymerBackboneIteratorState.nextPolymer) {
|
|
|
while (this.polymerIt.hasNext) {
|
|
|
const residueSegment = this.polymerIt.move()
|
|
|
this.residueIt.setSegment(residueSegment);
|
|
|
if (this.residueIt.hasNext) {
|
|
|
- this.value.centerB.element = getResidueTypeAtomIdElementIndex(this.unit, residueSegment, 'trace')
|
|
|
- // setTraceElement(this.value.centerB, this.residueIt.move())
|
|
|
+ this.value.centerB.element = this.getElementIndex(this.residueIt.move().index, 'trace')
|
|
|
this.state = AtomicPolymerBackboneIteratorState.nextResidue
|
|
|
break
|
|
|
}
|
|
@@ -147,8 +159,7 @@ export class AtomicPolymerBackboneIterator<T extends number = number> implements
|
|
|
|
|
|
if (this.state === AtomicPolymerBackboneIteratorState.nextResidue) {
|
|
|
this.value.centerA.element = this.value.centerB.element
|
|
|
- this.value.centerB.element = getResidueTypeAtomIdElementIndex(this.unit, this.residueIt.move(), 'trace')
|
|
|
- // setTraceElement(this.value.centerB, this.residueIt.move())
|
|
|
+ this.value.centerB.element = this.getElementIndex(this.residueIt.move().index, 'trace')
|
|
|
if (!this.residueIt.hasNext) {
|
|
|
// TODO need to advance to a polymer that has two or more residues (can't assume it has)
|
|
|
this.state = AtomicPolymerBackboneIteratorState.nextPolymer
|
|
@@ -169,10 +180,10 @@ export class AtomicPolymerBackboneIterator<T extends number = number> implements
|
|
|
|
|
|
const enum CoarsePolymerBackboneIteratorState { nextPolymer, nextElement }
|
|
|
|
|
|
-export class CoarsePolymerBackboneIterator<T extends number = number> implements Iterator<PolymerBackbonePair> {
|
|
|
+export class CoarsePolymerBackboneIterator implements Iterator<PolymerBackbonePair> {
|
|
|
private value: PolymerBackbonePair
|
|
|
- private polymerIt: SortedRanges.Iterator<ElementIndex>
|
|
|
- private polymerSegment: Segmentation.Segment<ElementIndex>
|
|
|
+ private polymerIt: SortedRanges.Iterator<ElementIndex, ResidueIndex>
|
|
|
+ private polymerSegment: Segmentation.Segment<ResidueIndex>
|
|
|
private state: CoarsePolymerBackboneIteratorState = CoarsePolymerBackboneIteratorState.nextPolymer
|
|
|
private elementIndex: number
|
|
|
hasNext: boolean = false;
|
|
@@ -182,9 +193,8 @@ export class CoarsePolymerBackboneIterator<T extends number = number> implements
|
|
|
if (this.polymerIt.hasNext) {
|
|
|
this.polymerSegment = this.polymerIt.move();
|
|
|
this.elementIndex = this.polymerSegment.start
|
|
|
- // this.elementIndex += 1
|
|
|
if (this.elementIndex + 1 < this.polymerSegment.end) {
|
|
|
- this.value.centerB.element = this.value.centerB.unit.elements[this.elementIndex]
|
|
|
+ this.value.centerB.element = this.unit.elements[this.elementIndex]
|
|
|
this.state = CoarsePolymerBackboneIteratorState.nextElement
|
|
|
} else {
|
|
|
this.state = CoarsePolymerBackboneIteratorState.nextPolymer
|
|
@@ -195,7 +205,7 @@ export class CoarsePolymerBackboneIterator<T extends number = number> implements
|
|
|
if (this.state === CoarsePolymerBackboneIteratorState.nextElement) {
|
|
|
this.elementIndex += 1
|
|
|
this.value.centerA.element = this.value.centerB.element
|
|
|
- this.value.centerB.element = this.value.centerB.unit.elements[this.elementIndex]
|
|
|
+ this.value.centerB.element = this.unit.elements[this.elementIndex]
|
|
|
if (this.elementIndex + 1 >= this.polymerSegment.end) {
|
|
|
this.state = CoarsePolymerBackboneIteratorState.nextPolymer
|
|
|
}
|
|
@@ -205,16 +215,13 @@ export class CoarsePolymerBackboneIterator<T extends number = number> implements
|
|
|
return this.value;
|
|
|
}
|
|
|
|
|
|
- constructor(unit: Unit.Spheres | Unit.Gaussians) {
|
|
|
+ constructor(private unit: Unit.Spheres | Unit.Gaussians) {
|
|
|
this.polymerIt = SortedRanges.transientSegments(getPolymerRanges(unit), unit.elements);
|
|
|
this.value = createPolymerBackbonePair(unit)
|
|
|
this.hasNext = this.polymerIt.hasNext
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
* Iterates over individual residues/coarse elements in polymers of a unit while
|
|
|
* providing information about the neighbourhood in the underlying model for drawing splines
|
|
@@ -242,32 +249,21 @@ function createPolymerTraceElement (unit: Unit): PolymerTraceElement {
|
|
|
first: false, last: false,
|
|
|
secStrucType: SecondaryStructureType.create(SecondaryStructureType.Flag.NA),
|
|
|
t0: Vec3.zero(), t1: Vec3.zero(), t2: Vec3.zero(), t3: Vec3.zero(), t4: Vec3.zero(),
|
|
|
- d12: Vec3.zero(), d23: Vec3.zero(),
|
|
|
+ d12: Vec3.create(1, 0, 0), d23: Vec3.create(1, 0, 0),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const enum AtomicPolymerTraceIteratorState { nextPolymer, nextResidue }
|
|
|
|
|
|
-function setSegment (outSegment: Segmentation.Segment<number>, index: number, segments: Segmentation<number>, min: number, max: number): Segmentation.Segment<number> {
|
|
|
- // index = Math.min(Math.max(0, index), segments.segments.length - 2)
|
|
|
- const _index = Math.min(Math.max(min, index), max)
|
|
|
- if (isNaN(_index)) console.log(_index, index, min, max)
|
|
|
- outSegment.index = _index
|
|
|
- outSegment.start = segments.offsets[_index]
|
|
|
- outSegment.end = segments.offsets[_index + 1]
|
|
|
- // console.log(index, {...outSegment}, {...boundingSegment}, segments.segments[boundingSegment.index])
|
|
|
- return outSegment
|
|
|
-}
|
|
|
-
|
|
|
-export class AtomicPolymerTraceIterator<T extends number = number> implements Iterator<PolymerTraceElement> {
|
|
|
+export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement> {
|
|
|
private value: PolymerTraceElement
|
|
|
- private polymerIt: SortedRanges.Iterator<ElementIndex>
|
|
|
+ private polymerIt: SortedRanges.Iterator<ElementIndex, ResidueIndex>
|
|
|
private residueIt: Segmentation.SegmentIterator<ResidueIndex>
|
|
|
- private residueAtomSegmentMin: number
|
|
|
- private residueAtomSegmentMax: number
|
|
|
+ private polymerSegment: Segmentation.Segment<ResidueIndex>
|
|
|
+ private residueSegmentMin: ResidueIndex
|
|
|
+ private residueSegmentMax: ResidueIndex
|
|
|
private state: AtomicPolymerTraceIteratorState = AtomicPolymerTraceIteratorState.nextPolymer
|
|
|
private residueAtomSegments: Segmentation<ElementIndex, ResidueIndex>
|
|
|
- private tmpSegment: Segmentation.Segment<ResidueIndex>
|
|
|
|
|
|
hasNext: boolean = false;
|
|
|
|
|
@@ -277,12 +273,25 @@ export class AtomicPolymerTraceIterator<T extends number = number> implements It
|
|
|
target[2] = this.unit.model.atomicConformation.z[index]
|
|
|
}
|
|
|
|
|
|
- updateResidueSegmentRange(polymerSegment: Segmentation.Segment<ElementIndex>) {
|
|
|
- const { polymerRanges, residueAtomSegments } = this.unit.model.atomicHierarchy
|
|
|
- const sMin = polymerRanges[polymerSegment.index * 2]
|
|
|
- const sMax = polymerRanges[polymerSegment.index * 2 + 1]
|
|
|
- this.residueAtomSegmentMin = residueAtomSegments.index[sMin]
|
|
|
- this.residueAtomSegmentMax = residueAtomSegments.index[sMax]
|
|
|
+ updateResidueSegmentRange(polymerSegment: Segmentation.Segment<ResidueIndex>) {
|
|
|
+ const { index } = this.unit.model.atomicHierarchy.residueAtomSegments
|
|
|
+ this.residueSegmentMin = index[this.unit.elements[polymerSegment.start]]
|
|
|
+ this.residueSegmentMax = index[this.unit.elements[polymerSegment.end - 1]]
|
|
|
+ }
|
|
|
+
|
|
|
+ getAtomIndex(residueIndex: number, atomType: 'trace' | 'direction') {
|
|
|
+ const index = Math.min(Math.max(this.residueSegmentMin, residueIndex), this.residueSegmentMax)
|
|
|
+ return getElementIndexForResidueTypeAtomId(this.unit.model, index as ResidueIndex, atomType)
|
|
|
+ }
|
|
|
+
|
|
|
+ getElementIndex(residueIndex: number, atomType: 'trace' | 'direction') {
|
|
|
+ const index = this.getAtomIndex(residueIndex, atomType)
|
|
|
+ // TODO handle case when it returns -1
|
|
|
+ const elementIndex = SortedArray.indexOf(this.unit.elements, index) as ElementIndex
|
|
|
+ if (elementIndex === -1) {
|
|
|
+ console.log('-1', residueIndex, atomType, index)
|
|
|
+ }
|
|
|
+ return elementIndex === -1 ? 0 as ElementIndex : elementIndex
|
|
|
}
|
|
|
|
|
|
move() {
|
|
@@ -290,10 +299,9 @@ export class AtomicPolymerTraceIterator<T extends number = number> implements It
|
|
|
|
|
|
if (this.state === AtomicPolymerTraceIteratorState.nextPolymer) {
|
|
|
while (polymerIt.hasNext) {
|
|
|
- const polymerSegment = polymerIt.move();
|
|
|
- // console.log('polymerSegment', {...polymerSegment})
|
|
|
- residueIt.setSegment(polymerSegment);
|
|
|
- this.updateResidueSegmentRange(polymerSegment)
|
|
|
+ this.polymerSegment = polymerIt.move();
|
|
|
+ residueIt.setSegment(this.polymerSegment);
|
|
|
+ this.updateResidueSegmentRange(this.polymerSegment)
|
|
|
if (residueIt.hasNext) {
|
|
|
this.state = AtomicPolymerTraceIteratorState.nextResidue
|
|
|
break
|
|
@@ -302,32 +310,22 @@ export class AtomicPolymerTraceIterator<T extends number = number> implements It
|
|
|
}
|
|
|
|
|
|
if (this.state === AtomicPolymerTraceIteratorState.nextResidue) {
|
|
|
- const { tmpSegment, residueAtomSegments, residueAtomSegmentMin, residueAtomSegmentMax } = this
|
|
|
- const residueSegment = residueIt.move();
|
|
|
- const resSegIdx = residueSegment.index
|
|
|
- // console.log(residueLabel(this.unit.model, resSegIdx), resSegIdx, this.unit.model.properties.secondaryStructure.type[resSegIdx])
|
|
|
- value.center.element = getResidueTypeAtomIdElementIndex(this.unit, residueSegment, 'trace')
|
|
|
+ const { index: residueIndex } = residueIt.move();
|
|
|
+ value.center.element = this.getElementIndex(residueIndex, 'trace')
|
|
|
|
|
|
- setSegment(tmpSegment, resSegIdx - 2, residueAtomSegments, residueAtomSegmentMin, residueAtomSegmentMax)
|
|
|
- this.pos(value.t0, getResidueTypeAtomIdElementIndex(this.unit, tmpSegment, 'trace'))
|
|
|
+ this.pos(value.t0, this.getAtomIndex(residueIndex - 2, 'trace'))
|
|
|
+ this.pos(value.t1, this.getAtomIndex(residueIndex - 1, 'trace'))
|
|
|
+ this.pos(value.t2, this.getAtomIndex(residueIndex, 'trace'))
|
|
|
+ this.pos(value.t3, this.getAtomIndex(residueIndex + 1, 'trace'))
|
|
|
+ this.pos(value.t4, this.getAtomIndex(residueIndex + 2, 'trace'))
|
|
|
|
|
|
- setSegment(tmpSegment, resSegIdx - 1, residueAtomSegments, residueAtomSegmentMin, residueAtomSegmentMax)
|
|
|
- this.pos(value.t1, getResidueTypeAtomIdElementIndex(this.unit, tmpSegment, 'trace'))
|
|
|
- this.pos(value.d12, getResidueTypeAtomIdElementIndex(this.unit, tmpSegment, 'direction'))
|
|
|
+ this.pos(value.d12, this.getAtomIndex(residueIndex - 1, 'direction'))
|
|
|
+ this.pos(value.d23, this.getAtomIndex(residueIndex, 'direction'))
|
|
|
|
|
|
- setSegment(tmpSegment, resSegIdx, residueAtomSegments, residueAtomSegmentMin, residueAtomSegmentMax)
|
|
|
- value.secStrucType = this.unit.model.properties.secondaryStructure.type[resSegIdx]
|
|
|
- this.pos(value.t2, getResidueTypeAtomIdElementIndex(this.unit, tmpSegment, 'trace'))
|
|
|
- this.pos(value.d23, getResidueTypeAtomIdElementIndex(this.unit, tmpSegment, 'direction'))
|
|
|
+ this.value.secStrucType = this.unit.model.properties.secondaryStructure.type[residueIndex]
|
|
|
|
|
|
- setSegment(tmpSegment, resSegIdx + 1, residueAtomSegments, residueAtomSegmentMin, residueAtomSegmentMax)
|
|
|
- this.pos(value.t3, getResidueTypeAtomIdElementIndex(this.unit, tmpSegment, 'trace'))
|
|
|
-
|
|
|
- setSegment(tmpSegment, resSegIdx + 2, residueAtomSegments, residueAtomSegmentMin, residueAtomSegmentMax)
|
|
|
- this.pos(value.t4, getResidueTypeAtomIdElementIndex(this.unit, tmpSegment, 'trace'))
|
|
|
-
|
|
|
- value.first = resSegIdx === residueAtomSegmentMin
|
|
|
- value.last = resSegIdx === residueAtomSegmentMax
|
|
|
+ value.first = residueIndex === this.polymerSegment.start
|
|
|
+ value.last = residueIndex === this.polymerSegment.end - 1
|
|
|
|
|
|
if (!residueIt.hasNext) {
|
|
|
this.state = AtomicPolymerTraceIteratorState.nextPolymer
|
|
@@ -344,22 +342,71 @@ export class AtomicPolymerTraceIterator<T extends number = number> implements It
|
|
|
this.polymerIt = SortedRanges.transientSegments(getPolymerRanges(unit), unit.elements)
|
|
|
this.residueIt = Segmentation.transientSegments(this.residueAtomSegments, unit.elements);
|
|
|
this.value = createPolymerTraceElement(unit)
|
|
|
- this.tmpSegment = { index: 0 as ResidueIndex, start: 0 as ElementIndex, end: 0 as ElementIndex }
|
|
|
this.hasNext = this.residueIt.hasNext && this.polymerIt.hasNext
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-export class CoarsePolymerTraceIterator<T extends number = number> implements Iterator<PolymerTraceElement> {
|
|
|
- private value: PolymerTraceElement
|
|
|
+const enum CoarsePolymerTraceIteratorState { nextPolymer, nextElement }
|
|
|
|
|
|
+export class CoarsePolymerTraceIterator implements Iterator<PolymerTraceElement> {
|
|
|
+ private value: PolymerTraceElement
|
|
|
+ private polymerIt: SortedRanges.Iterator<ElementIndex, ResidueIndex>
|
|
|
+ private polymerSegment: Segmentation.Segment<ResidueIndex>
|
|
|
+ private state: CoarsePolymerTraceIteratorState = CoarsePolymerTraceIteratorState.nextPolymer
|
|
|
+ private conformation: CoarseSphereConformation | CoarseGaussianConformation
|
|
|
+ private elementIndex: number
|
|
|
hasNext: boolean = false;
|
|
|
|
|
|
+ private pos(target: Vec3, elementIndex: number) {
|
|
|
+ elementIndex = Math.min(Math.max(this.polymerSegment.start, elementIndex), this.polymerSegment.end - 1)
|
|
|
+ const index = this.unit.elements[elementIndex]
|
|
|
+ target[0] = this.conformation.x[index]
|
|
|
+ target[1] = this.conformation.y[index]
|
|
|
+ target[2] = this.conformation.z[index]
|
|
|
+ }
|
|
|
+
|
|
|
move() {
|
|
|
+ if (this.state === CoarsePolymerTraceIteratorState.nextPolymer) {
|
|
|
+ while (this.polymerIt.hasNext) {
|
|
|
+ this.polymerSegment = this.polymerIt.move();
|
|
|
+ this.elementIndex = this.polymerSegment.start
|
|
|
+
|
|
|
+ if (this.elementIndex + 1 < this.polymerSegment.end) {
|
|
|
+ this.state = CoarsePolymerTraceIteratorState.nextElement
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.state === CoarsePolymerTraceIteratorState.nextElement) {
|
|
|
+ this.elementIndex += 1
|
|
|
+ this.value.center.element = this.value.center.unit.elements[this.elementIndex]
|
|
|
+
|
|
|
+ this.pos(this.value.t0, this.elementIndex - 2)
|
|
|
+ this.pos(this.value.t1, this.elementIndex - 1)
|
|
|
+ this.pos(this.value.t2, this.elementIndex)
|
|
|
+ this.pos(this.value.t3, this.elementIndex + 1)
|
|
|
+ this.pos(this.value.t4, this.elementIndex + 2)
|
|
|
+
|
|
|
+ this.value.first = this.elementIndex === this.polymerSegment.start
|
|
|
+ this.value.last = this.elementIndex === this.polymerSegment.end - 1
|
|
|
+
|
|
|
+ if (this.elementIndex + 1 >= this.polymerSegment.end) {
|
|
|
+ this.state = CoarsePolymerTraceIteratorState.nextPolymer
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.hasNext = this.elementIndex + 1 < this.polymerSegment.end || this.polymerIt.hasNext
|
|
|
return this.value;
|
|
|
}
|
|
|
|
|
|
- constructor(unit: Unit.Spheres | Unit.Gaussians) {
|
|
|
+ constructor(private unit: Unit.Spheres | Unit.Gaussians) {
|
|
|
+ this.polymerIt = SortedRanges.transientSegments(getPolymerRanges(unit), unit.elements);
|
|
|
this.value = createPolymerTraceElement(unit)
|
|
|
- this.hasNext = false
|
|
|
+ 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
|
|
|
+ }
|
|
|
+ this.hasNext = this.polymerIt.hasNext
|
|
|
}
|
|
|
}
|