Skip to content
Snippets Groups Projects
Commit 6d0c2f83 authored by Alexander Rose's avatar Alexander Rose
Browse files

wip, carb mark/getLoci

parent 2418ddcf
No related branches found
No related tags found
No related merge requests found
......@@ -105,6 +105,10 @@ function getLinkLoci(pickingId: PickingId, structure: Structure, id: number) {
Link.Location(
carbA.unit, indexA as StructureElement.UnitIndex,
carbB.unit, indexB as StructureElement.UnitIndex
),
Link.Location(
carbB.unit, indexB as StructureElement.UnitIndex,
carbA.unit, indexA as StructureElement.UnitIndex
)
])
}
......
......@@ -25,6 +25,7 @@ import { OrderedSet, Interval } from 'mol-data/int';
import { EmptyLoci, Loci } from 'mol-model/loci';
import { VisualContext } from 'mol-repr/representation';
import { Theme } from 'mol-theme/theme';
import { getResidueLoci } from './util/common';
const t = Mat4.identity()
const sVec = Vec3.zero()
......@@ -184,30 +185,36 @@ function CarbohydrateElementIterator(structure: Structure): LocationIterator {
return LocationIterator(groupCount, instanceCount, getLocation, true, isSecondary)
}
/** Return a Loci for the elements of the whole residue of a carbohydrate. */
function getCarbohydrateLoci(pickingId: PickingId, structure: Structure, id: number) {
const { objectId, groupId } = pickingId
if (id === objectId) {
const carb = structure.carbohydrates.elements[Math.floor(groupId / 2)]
const { unit } = carb
const index = OrderedSet.indexOf(unit.elements, carb.anomericCarbon)
if (index !== -1) {
const indices = OrderedSet.ofSingleton(index as StructureElement.UnitIndex)
return StructureElement.Loci(structure, [{ unit, indices }])
}
return getResidueLoci(structure, carb.unit, carb.anomericCarbon)
}
return EmptyLoci
}
/** Mark a carbohydrate (usually a monosaccharide) when all its residue's elements are in a loci. */
function markCarbohydrate(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) {
const { getElementIndex } = structure.carbohydrates
const { getElementIndex, getAnomericCarbon } = structure.carbohydrates
let changed = false
if (StructureElement.isLoci(loci)) {
for (const e of loci.elements) {
OrderedSet.forEach(e.indices, index => {
const idx = getElementIndex(e.unit, e.unit.elements[index])
if (idx !== undefined) {
if (apply(Interval.ofBounds(idx * 2, idx * 2 + 2))) changed = true
OrderedSet.forEach(e.indices, v => {
const { model, elements } = e.unit
const { index, offsets } = model.atomicHierarchy.residueAtomSegments
const rI = index[elements[v]]
const unitIndexMin = OrderedSet.findPredecessorIndex(elements, offsets[rI])
const unitIndexMax = OrderedSet.findPredecessorIndex(elements, offsets[rI + 1] - 1)
const unitIndexInterval = Interval.ofRange(unitIndexMin, unitIndexMax)
if(!OrderedSet.isSubset(e.indices, unitIndexInterval)) return
const eI = getAnomericCarbon(e.unit, rI)
if (eI !== undefined) {
const idx = getElementIndex(e.unit, eI)
if (idx !== undefined) {
if (apply(Interval.ofBounds(idx * 2, idx * 2 + 2))) changed = true
}
}
})
}
......
......@@ -114,25 +114,21 @@ function getTerminalLinkLoci(pickingId: PickingId, structure: Structure, id: num
const carb = elements[l.carbohydrateIndex]
const carbIndex = OrderedSet.indexOf(carb.unit.elements, carb.anomericCarbon)
if (l.fromCarbohydrate) {
return Link.Loci(structure, [
Link.Location(
carb.unit, carbIndex as StructureElement.UnitIndex,
l.elementUnit, l.elementIndex
)
])
} else {
return Link.Loci(structure, [
Link.Location(
l.elementUnit, l.elementIndex,
carb.unit, carbIndex as StructureElement.UnitIndex
)
])
}
return Link.Loci(structure, [
Link.Location(
carb.unit, carbIndex as StructureElement.UnitIndex,
l.elementUnit, l.elementIndex
),
Link.Location(
l.elementUnit, l.elementIndex,
carb.unit, carbIndex as StructureElement.UnitIndex
)
])
}
return EmptyLoci
}
// TODO mark link when both (or one) of the link elements are in a StructureElement.Loci
function markTerminalLink(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) {
const { getTerminalLinkIndex } = structure.carbohydrates
......
......@@ -4,7 +4,7 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Unit, Structure } from 'mol-model/structure';
import { Unit, Structure, ElementIndex, StructureElement } from 'mol-model/structure';
import { createMeshRenderObject, createPointsRenderObject, createLinesRenderObject, createDirectVolumeRenderObject } from 'mol-gl/render-object';
import { Mat4 } from 'mol-math/linear-algebra';
import { TransformData, createTransform, createIdentityTransform } from 'mol-geo/geometry/transform-data';
......@@ -18,6 +18,27 @@ import { VisualContext } from 'mol-repr/representation';
import { Theme } from 'mol-theme/theme';
import { ParamDefinition as PD } from 'mol-util/param-definition';
import { StructureMeshParams, StructurePointsParams, StructureLinesParams, StructureDirectVolumeParams } from 'mol-repr/structure/representation';
import { OrderedSet, SortedArray } from 'mol-data/int';
import { EmptyLoci, Loci } from 'mol-model/loci';
/** Return a Loci for the elements of a whole residue the elementIndex belongs to. */
export function getResidueLoci(structure: Structure, unit: Unit, elementIndex: ElementIndex): Loci {
const { elements, model } = unit
if (OrderedSet.indexOf(elements, elementIndex) !== -1) {
const { index, offsets } = model.atomicHierarchy.residueAtomSegments
const rI = index[elementIndex]
const _indices: number[] = []
for (let i = offsets[rI], il = offsets[rI + 1]; i < il; ++i) {
const unitIndex = OrderedSet.indexOf(elements, i)
if (unitIndex !== -1) _indices.push(unitIndex)
}
const indices = OrderedSet.ofSortedArray<StructureElement.UnitIndex>(SortedArray.ofSortedArray(_indices))
return StructureElement.Loci(structure, [{ unit, indices }])
}
return EmptyLoci
}
//
export function createUnitsTransform({ units }: Unit.SymmetryGroup, transformData?: TransformData) {
const unitCount = units.length
......
......@@ -6,12 +6,13 @@
import { Unit, ElementIndex, StructureElement, Link } from 'mol-model/structure';
import SortedRanges from 'mol-data/int/sorted-ranges';
import { OrderedSet, Interval, SortedArray } from 'mol-data/int';
import { OrderedSet, Interval } from 'mol-data/int';
import { EmptyLoci, Loci } from 'mol-model/loci';
import { LocationIterator } from 'mol-geo/util/location-iterator';
import { PickingId } from 'mol-geo/geometry/picking';
import { StructureGroup } from 'mol-repr/structure/units-visual';
import { getElementIndexForAtomRole } from 'mol-model/structure/util';
import { getResidueLoci } from './common';
export * from './polymer/backbone-iterator'
export * from './polymer/gap-iterator'
......@@ -66,28 +67,18 @@ export namespace PolymerGapLocationIterator {
}
}
/** Return a Loci for the elements of a whole residue. */
/** Return a Loci for the elements of the whole residue of a polymer element. */
export function getPolymerElementLoci(pickingId: PickingId, structureGroup: StructureGroup, id: number) {
const { objectId, instanceId, groupId } = pickingId
if (id === objectId) {
const { structure, group } = structureGroup
const unit = group.units[instanceId]
const { elements, polymerElements, model } = unit
if (OrderedSet.indexOf(elements, polymerElements[groupId]) !== -1) {
const { index, offsets } = model.atomicHierarchy.residueAtomSegments
const rI = index[polymerElements[groupId]]
const _indices: number[] = []
for (let i = offsets[rI], il = offsets[rI + 1]; i < il; ++i) {
const unitIndex = OrderedSet.indexOf(elements, i)
if (unitIndex !== -1) _indices.push(unitIndex)
}
const indices = OrderedSet.ofSortedArray<StructureElement.UnitIndex>(SortedArray.ofSortedArray(_indices))
return StructureElement.Loci(structure, [{ unit, indices }])
}
return getResidueLoci(structure, unit, unit.polymerElements[groupId])
}
return EmptyLoci
}
/** Mark a polymer element (e.g. part of a cartoon trace) when all its residue's elements are in a loci. */
export function markPolymerElement(loci: Loci, structureGroup: StructureGroup, apply: (interval: Interval) => boolean) {
let changed = false
if (!StructureElement.isLoci(loci)) return false
......@@ -102,9 +93,9 @@ export function markPolymerElement(loci: Loci, structureGroup: StructureGroup, a
// TODO optimized implementation for intervals
OrderedSet.forEach(e.indices, v => {
const rI = index[elements[v]]
const unitIndexBeg = OrderedSet.indexOf(elements, offsets[rI])
const unitIndexEnd = OrderedSet.indexOf(elements, offsets[rI + 1])
const unitIndexInterval = Interval.ofBounds(unitIndexBeg, unitIndexEnd)
const unitIndexMin = OrderedSet.findPredecessorIndex(elements, offsets[rI])
const unitIndexMax = OrderedSet.findPredecessorIndex(elements, offsets[rI + 1] - 1)
const unitIndexInterval = Interval.ofRange(unitIndexMin, unitIndexMax)
if(!OrderedSet.isSubset(e.indices, unitIndexInterval)) return
const eI = getElementIndexForAtomRole(model, rI, 'trace')
const idx = OrderedSet.indexOf(e.unit.polymerElements, eI)
......@@ -117,6 +108,7 @@ export function markPolymerElement(loci: Loci, structureGroup: StructureGroup, a
return changed
}
/** Return a Loci for both directions of the polymer gap element. */
export function getPolymerGapElementLoci(pickingId: PickingId, structureGroup: StructureGroup, id: number) {
const { objectId, instanceId, groupId } = pickingId
if (id === objectId) {
......@@ -125,7 +117,10 @@ export function getPolymerGapElementLoci(pickingId: PickingId, structureGroup: S
const unitIndexA = OrderedSet.indexOf(unit.elements, unit.gapElements[groupId]) as StructureElement.UnitIndex
const unitIndexB = OrderedSet.indexOf(unit.elements, unit.gapElements[groupId % 2 ? groupId - 1 : groupId + 1]) as StructureElement.UnitIndex
if (unitIndexA !== -1 && unitIndexB !== -1) {
return Link.Loci(structure, [ Link.Location(unit, unitIndexA, unit, unitIndexB) ])
return Link.Loci(structure, [
Link.Location(unit, unitIndexA, unit, unitIndexB),
Link.Location(unit, unitIndexB, unit, unitIndexA)
])
}
}
return EmptyLoci
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment