gap-iterator.ts 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { Unit, StructureElement, ElementIndex, ResidueIndex } from 'mol-model/structure';
  7. import { AtomRole } from 'mol-model/structure/model/types';
  8. import Iterator from 'mol-data/iterator';
  9. import SortedRanges from 'mol-data/int/sorted-ranges';
  10. import { getElementIndexForAtomRole } from 'mol-model/structure/util';
  11. import { getGapRanges } from '../polymer';
  12. /** Iterates over gaps, i.e. the stem residues/coarse elements adjacent to gaps */
  13. export function PolymerGapIterator(unit: Unit): Iterator<PolymerGapPair> {
  14. switch (unit.kind) {
  15. case Unit.Kind.Atomic: return new AtomicPolymerGapIterator(unit)
  16. case Unit.Kind.Spheres:
  17. case Unit.Kind.Gaussians:
  18. return new CoarsePolymerGapIterator(unit)
  19. }
  20. }
  21. interface PolymerGapPair {
  22. centerA: StructureElement
  23. centerB: StructureElement
  24. }
  25. function createPolymerGapPair (unit: Unit) {
  26. return {
  27. centerA: StructureElement.create(unit),
  28. centerB: StructureElement.create(unit),
  29. }
  30. }
  31. export class AtomicPolymerGapIterator implements Iterator<PolymerGapPair> {
  32. private value: PolymerGapPair
  33. private gapIt: SortedRanges.Iterator<ElementIndex, ResidueIndex>
  34. hasNext: boolean = false;
  35. private getElementIndex(residueIndex: ResidueIndex, atomRole: AtomRole) {
  36. const elementIndex = getElementIndexForAtomRole(this.unit.model, residueIndex, atomRole)
  37. return elementIndex === -1 ? this.unit.model.atomicHierarchy.residueAtomSegments.offsets[residueIndex] : elementIndex
  38. }
  39. move() {
  40. const { elements, residueIndex } = this.unit
  41. const gapSegment = this.gapIt.move();
  42. this.value.centerA.element = this.getElementIndex(residueIndex[elements[gapSegment.start]], 'trace')
  43. this.value.centerB.element = this.getElementIndex(residueIndex[elements[gapSegment.end - 1]], 'trace')
  44. this.hasNext = this.gapIt.hasNext
  45. return this.value;
  46. }
  47. constructor(private unit: Unit.Atomic) {
  48. this.gapIt = SortedRanges.transientSegments(getGapRanges(unit), unit.elements);
  49. this.value = createPolymerGapPair(unit)
  50. this.hasNext = this.gapIt.hasNext
  51. }
  52. }
  53. export class CoarsePolymerGapIterator implements Iterator<PolymerGapPair> {
  54. private value: PolymerGapPair
  55. private gapIt: SortedRanges.Iterator<ElementIndex, ElementIndex>
  56. hasNext: boolean = false;
  57. move() {
  58. const gapSegment = this.gapIt.move();
  59. this.value.centerA.element = this.unit.elements[gapSegment.start]
  60. this.value.centerB.element = this.unit.elements[gapSegment.end - 1]
  61. this.hasNext = this.gapIt.hasNext
  62. return this.value;
  63. }
  64. constructor(private unit: Unit.Spheres | Unit.Gaussians) {
  65. this.gapIt = SortedRanges.transientSegments(getGapRanges(unit), unit.elements);
  66. this.value = createPolymerGapPair(unit)
  67. this.hasNext = this.gapIt.hasNext
  68. }
  69. }