Skip to content
Snippets Groups Projects
Select Git revision
  • ed2ca8ae66eec51c1cb61130183cf806c3e19aa5
  • master default protected
  • base-pairs-ladder
  • rednatco-v2
  • rednatco
  • test
  • ntc-tube-uniform-color
  • ntc-tube-missing-atoms
  • restore-vertex-array-per-program
  • watlas2
  • dnatco_new
  • cleanup-old-nodejs
  • webmmb
  • fix_auth_seq_id
  • update_deps
  • ext_dev
  • ntc_balls
  • nci-2
  • plugin
  • bugfix-0.4.5
  • nci
  • v0.5.0-dev.1
  • v0.4.5
  • v0.4.4
  • v0.4.3
  • v0.4.2
  • v0.4.1
  • v0.4.0
  • v0.3.12
  • v0.3.11
  • v0.3.10
  • v0.3.9
  • v0.3.8
  • v0.3.7
  • v0.3.6
  • v0.3.5
  • v0.3.4
  • v0.3.3
  • v0.3.2
  • v0.3.1
  • v0.3.0
41 results

polymer.ts

Blame
  • 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)
        }
    }