Select Git revision
warden-server-2.0.0-beta.tar.gz.sig
polymer.ts 6.09 KiB
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Unit, ElementIndex, StructureElement } from 'mol-model/structure';
import { Segmentation, OrderedSet, Interval } from 'mol-data/int';
import SortedRanges from 'mol-data/int/sorted-ranges';
import { LocationIterator } from '../../../../util/location-iterator';
import { getElementIndexForAtomRole } from 'mol-model/structure/util';
import { PolymerGapIterator } from './polymer/gap-iterator';
export * from './polymer/backbone-iterator'
export * from './polymer/gap-iterator'
export * from './polymer/trace-iterator'
export * from './polymer/curve-segment'
export function getPolymerRanges(unit: Unit): SortedRanges<ElementIndex> {
switch (unit.kind) {
case Unit.Kind.Atomic: return unit.model.atomicHierarchy.polymerRanges
case Unit.Kind.Spheres: return unit.model.coarseHierarchy.spheres.polymerRanges
case Unit.Kind.Gaussians: return unit.model.coarseHierarchy.gaussians.polymerRanges
}
}
export function getGapRanges(unit: Unit): SortedRanges<ElementIndex> {
switch (unit.kind) {
case Unit.Kind.Atomic: return unit.model.atomicHierarchy.gapRanges
case Unit.Kind.Spheres: return unit.model.coarseHierarchy.spheres.gapRanges
case Unit.Kind.Gaussians: return unit.model.coarseHierarchy.gaussians.gapRanges
}
}
// polymer element
export function getPolymerElementCount(unit: Unit) {
let count = 0
const { elements } = unit
const polymerIt = SortedRanges.transientSegments(getPolymerRanges(unit), elements)
switch (unit.kind) {
case Unit.Kind.Atomic:
const residueIt = Segmentation.transientSegments(unit.model.atomicHierarchy.residueAtomSegments, elements)
while (polymerIt.hasNext) {
const polymerSegment = polymerIt.move()
residueIt.setSegment(polymerSegment)
while (residueIt.hasNext) {
const residueSegment = residueIt.move()
const { start, end } = residueSegment
if (OrderedSet.areIntersecting(Interval.ofBounds(elements[start], elements[end - 1]), elements)) ++count
}
}
break
case Unit.Kind.Spheres:
case Unit.Kind.Gaussians:
while (polymerIt.hasNext) {
const { start, end } = polymerIt.move()
count += OrderedSet.intersectionSize(Interval.ofBounds(elements[start], elements[end - 1]), elements)
}
break
}
return count
}
export function getPolymerElementIndices(unit: Unit) {
const indices: ElementIndex[] = []
const { elements, model } = unit
const { residueAtomSegments } = unit.model.atomicHierarchy
const polymerIt = SortedRanges.transientSegments(getPolymerRanges(unit), elements)
switch (unit.kind) {
case Unit.Kind.Atomic:
const residueIt = Segmentation.transientSegments(residueAtomSegments, elements)
while (polymerIt.hasNext) {
const polymerSegment = polymerIt.move()
residueIt.setSegment(polymerSegment)
while (residueIt.hasNext) {
const residueSegment = residueIt.move()
const { start, end, index } = residueSegment
if (OrderedSet.areIntersecting(Interval.ofBounds(elements[start], elements[end - 1]), elements)) {
const elementIndex = getElementIndexForAtomRole(model, index, 'trace')
indices.push(elementIndex === -1 ? residueAtomSegments.offsets[index] : elementIndex)
}
}
}
break
case Unit.Kind.Spheres:
case Unit.Kind.Gaussians:
while (polymerIt.hasNext) {
const { start, end } = polymerIt.move()
for (let i = start; i < end; ++i) { indices.push(elements[i]) }
}
break
}
return indices
}
export namespace PolymerLocationIterator {
export function fromGroup(group: Unit.SymmetryGroup): LocationIterator {
const polymerElementIndices = getPolymerElementIndices(group.units[0])
const groupCount = polymerElementIndices.length
const instanceCount = group.units.length
const location = StructureElement.create()
const getLocation = (groupIndex: number, instanceIndex: number) => {
const unit = group.units[instanceIndex]
location.unit = unit
location.element = polymerElementIndices[groupIndex]
return location
}
return LocationIterator(groupCount, instanceCount, getLocation)
}
}
// polymer gap
export function getPolymerGapCount(unit: Unit) {
let count = 0
const { elements } = unit
const gapIt = SortedRanges.transientSegments(getGapRanges(unit), elements)
while (gapIt.hasNext) {
const { start, end } = gapIt.move()
if (OrderedSet.areIntersecting(Interval.ofBounds(elements[start], elements[end - 1]), elements)) ++count
}
return count
}
export function getPolymerGapElementIndices(unit: Unit) {
const indices: ElementIndex[] = []
const polymerGapIt = PolymerGapIterator(unit)
while (polymerGapIt.hasNext) {
const { centerA, centerB } = polymerGapIt.move()
indices.push(centerA.element, centerB.element)
}
return indices
}
export namespace PolymerGapLocationIterator {
export function fromGroup(group: Unit.SymmetryGroup): LocationIterator {
const polymerGapElementIndices = getPolymerGapElementIndices(group.units[0])
const groupCount = polymerGapElementIndices.length
const instanceCount = group.units.length
const location = StructureElement.create()
const getLocation = (groupIndex: number, instanceIndex: number) => {
const unit = group.units[instanceIndex]
location.unit = unit
location.element = polymerGapElementIndices[groupIndex]
return location
}
return LocationIterator(groupCount, instanceCount, getLocation)
}
}