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

better handling of missing atoms in trace, block, backbone visuals

parent d58f27ea
No related branches found
No related tags found
No related merge requests found
......@@ -82,18 +82,21 @@ async function createNucleotideBlockMesh(ctx: RuntimeContext, unit: Unit, props:
idx6 = getElementIndexForAtomRole(model, residueIndex, 'trace')
}
if (idx1 !== -1 && idx2 !== -1 && idx3 !== -1 && idx4 !== -1 && idx5 !== -1 && idx6 !== -1) {
pos(idx1, p1); pos(idx2, p2); pos(idx3, p3); pos(idx4, p4); pos(idx5, p5); pos(idx6, p6)
Vec3.normalize(v12, Vec3.sub(v12, p2, p1))
Vec3.normalize(v34, Vec3.sub(v34, p4, p3))
Vec3.normalize(vC, Vec3.cross(vC, v12, v34))
Mat4.targetTo(t, p1, p2, vC)
Vec3.scaleAndAdd(center, p1, v12, height / 2 - 0.2)
Mat4.scale(t, t, Vec3.set(sVec, width, depth, height))
Mat4.setTranslation(t, center)
if (idx5 !== -1 && idx6 !== -1) {
pos(idx5, p5); pos(idx6, p6)
builder.setGroup(SortedArray.findPredecessorIndex(elements, idx6))
builder.add(t, box)
addCylinder(builder, p5, p6, 1, { radiusTop: 0.2, radiusBottom: 0.2 })
if (idx1 !== -1 && idx2 !== -1 && idx3 !== -1 && idx4 !== -1) {
pos(idx1, p1); pos(idx2, p2); pos(idx3, p3); pos(idx4, p4);
Vec3.normalize(v12, Vec3.sub(v12, p2, p1))
Vec3.normalize(v34, Vec3.sub(v34, p4, p3))
Vec3.normalize(vC, Vec3.cross(vC, v12, v34))
Mat4.targetTo(t, p1, p2, vC)
Vec3.scaleAndAdd(center, p1, v12, height / 2 - 0.2)
Mat4.scale(t, t, Vec3.set(sVec, width, depth, height))
Mat4.setTranslation(t, center)
builder.add(t, box)
}
}
}
......
......@@ -10,6 +10,7 @@ import Iterator from 'mol-data/iterator';
import SortedRanges from 'mol-data/int/sorted-ranges';
import { getElementIndexForAtomRole } from 'mol-model/structure/util';
import { getPolymerRanges } from '../polymer';
import { AtomRole } from 'mol-model/structure/model/types';
/** Iterates over consecutive pairs of residues/coarse elements in polymers */
export function PolymerBackboneIterator(unit: Unit): Iterator<PolymerBackbonePair> {
......@@ -43,13 +44,19 @@ export class AtomicPolymerBackboneIterator implements Iterator<PolymerBackbonePa
private residueSegment: Segmentation.Segment<ResidueIndex>
hasNext: boolean = false;
private getElementIndex(residueIndex: ResidueIndex, atomRole: AtomRole) {
const { atomicHierarchy } = this.unit.model
const elementIndex = getElementIndexForAtomRole(this.unit.model, residueIndex, atomRole)
return elementIndex === -1 ? atomicHierarchy.residueAtomSegments.offsets[residueIndex] : elementIndex
}
move() {
if (this.state === AtomicPolymerBackboneIteratorState.nextPolymer) {
while (this.polymerIt.hasNext) {
this.residueIt.setSegment(this.polymerIt.move());
if (this.residueIt.hasNext) {
this.residueSegment = this.residueIt.move()
this.value.centerB.element = getElementIndexForAtomRole(this.unit.model, this.residueSegment.index, 'trace')
this.value.centerB.element = this.getElementIndex(this.residueSegment.index, 'trace')
this.state = AtomicPolymerBackboneIteratorState.nextResidue
break
}
......@@ -59,7 +66,7 @@ export class AtomicPolymerBackboneIterator implements Iterator<PolymerBackbonePa
if (this.state === AtomicPolymerBackboneIteratorState.nextResidue) {
this.residueSegment = this.residueIt.move()
this.value.centerA.element = this.value.centerB.element
this.value.centerB.element = getElementIndexForAtomRole(this.unit.model, this.residueSegment.index, 'trace')
this.value.centerB.element = this.getElementIndex(this.residueSegment.index, 'trace')
if (!this.residueIt.hasNext) {
if (this.unit.model.atomicHierarchy.cyclicPolymerMap.has(this.residueSegment.index)) {
this.state = AtomicPolymerBackboneIteratorState.cycle
......@@ -71,7 +78,7 @@ export class AtomicPolymerBackboneIterator implements Iterator<PolymerBackbonePa
} else if (this.state === AtomicPolymerBackboneIteratorState.cycle) {
const { cyclicPolymerMap } = this.unit.model.atomicHierarchy
this.value.centerA.element = this.value.centerB.element
this.value.centerB.element = getElementIndexForAtomRole(this.unit.model, cyclicPolymerMap.get(this.residueSegment.index)!, 'trace')
this.value.centerB.element = this.getElementIndex(cyclicPolymerMap.get(this.residueSegment.index)!, 'trace')
// TODO need to advance to a polymer that has two or more residues (can't assume it has)
this.state = AtomicPolymerBackboneIteratorState.nextPolymer
}
......
......@@ -89,24 +89,25 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
this.residueSegmentMax = index[this.unit.elements[polymerSegment.end - 1]]
}
private getAtomIndex(residueIndex: ResidueIndex, atomRole: AtomRole) {
const { cyclicPolymerMap } = this.unit.model.atomicHierarchy
private getElementIndex(residueIndex: ResidueIndex, atomRole: AtomRole) {
const { atomicHierarchy } = this.unit.model
if (residueIndex < this.residueSegmentMin) {
const cyclicIndex = cyclicPolymerMap.get(this.residueSegmentMin)
const cyclicIndex = atomicHierarchy.cyclicPolymerMap.get(this.residueSegmentMin)
if (cyclicIndex !== undefined) {
residueIndex = cyclicIndex - (this.residueSegmentMin - residueIndex - 1) as ResidueIndex
} else {
residueIndex = this.residueSegmentMin
}
} else if (residueIndex > this.residueSegmentMax) {
const cyclicIndex = cyclicPolymerMap.get(this.residueSegmentMax)
const cyclicIndex = atomicHierarchy.cyclicPolymerMap.get(this.residueSegmentMax)
if (cyclicIndex !== undefined) {
residueIndex = cyclicIndex + (residueIndex - this.residueSegmentMax - 1) as ResidueIndex
} else {
residueIndex = this.residueSegmentMax
}
}
return getElementIndexForAtomRole(this.unit.model, residueIndex, atomRole)
const elementIndex = getElementIndexForAtomRole(this.unit.model, residueIndex, atomRole)
return elementIndex === -1 ? atomicHierarchy.residueAtomSegments.offsets[residueIndex] : elementIndex
}
private setControlPoint(out: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, residueIndex: ResidueIndex) {
......@@ -135,19 +136,19 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
if (this.state === AtomicPolymerTraceIteratorState.nextResidue) {
const { index: residueIndex } = residueIt.move();
value.center.element = this.getAtomIndex(residueIndex, 'trace')
value.center.element = this.getElementIndex(residueIndex, 'trace')
this.pos(this.p0, this.getAtomIndex(residueIndex - 3 as ResidueIndex, 'trace'))
this.pos(this.p1, this.getAtomIndex(residueIndex - 2 as ResidueIndex, 'trace'))
this.pos(this.p2, this.getAtomIndex(residueIndex - 1 as ResidueIndex, 'trace'))
this.pos(this.p3, this.getAtomIndex(residueIndex, 'trace'))
this.pos(this.p4, this.getAtomIndex(residueIndex + 1 as ResidueIndex, 'trace'))
this.pos(this.p5, this.getAtomIndex(residueIndex + 2 as ResidueIndex, 'trace'))
this.pos(this.p6, this.getAtomIndex(residueIndex + 3 as ResidueIndex, 'trace'))
this.pos(this.p0, this.getElementIndex(residueIndex - 3 as ResidueIndex, 'trace'))
this.pos(this.p1, this.getElementIndex(residueIndex - 2 as ResidueIndex, 'trace'))
this.pos(this.p2, this.getElementIndex(residueIndex - 1 as ResidueIndex, 'trace'))
this.pos(this.p3, this.getElementIndex(residueIndex, 'trace'))
this.pos(this.p4, this.getElementIndex(residueIndex + 1 as ResidueIndex, 'trace'))
this.pos(this.p5, this.getElementIndex(residueIndex + 2 as ResidueIndex, 'trace'))
this.pos(this.p6, this.getElementIndex(residueIndex + 3 as ResidueIndex, 'trace'))
// this.pos(this.v01, this.getAtomIndex(residueIndex - 2 as ResidueIndex, 'direction'))
this.pos(this.v12, this.getAtomIndex(residueIndex - 1 as ResidueIndex, 'direction'))
this.pos(this.v23, this.getAtomIndex(residueIndex, 'direction'))
this.pos(this.v12, this.getElementIndex(residueIndex - 1 as ResidueIndex, 'direction'))
this.pos(this.v23, this.getElementIndex(residueIndex, 'direction'))
// this.pos(this.v34, this.getAtomIndex(residueIndex + 1 as ResidueIndex, 'direction'))
this.value.secStrucType = this.unit.model.properties.secondaryStructure.type[residueIndex]
......
......@@ -26,13 +26,13 @@ export function getAtomIdForAtomRole(moleculeType: MoleculeType, atomRole: AtomR
return ''
}
export function getElementIndexForAtomId(model: Model, rI: ResidueIndex, atomId: string): ElementIndex {
export function getElementIndexForAtomId(model: Model, rI: ResidueIndex, atomId: string): ElementIndex | -1 {
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 offsets[rI] as ElementIndex
return -1
}
export function getElementIndexForAtomRole(model: Model, rI: ResidueIndex, atomRole: AtomRole) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment