Skip to content
Snippets Groups Projects
Commit 5dc0a5e5 authored by David Sehnal's avatar David Sehnal
Browse files

Updated carb representation (indicate whether it has a ring; geometry is a single property)

parent 494728e2
No related branches found
No related tags found
No related merge requests found
......@@ -47,50 +47,53 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru
const linkParams = { radiusTop: 0.4, radiusBottom: 0.4 }
for (let i = 0, il = carbohydrates.elements.length; i < il; ++i) {
const c = carbohydrates.elements[i]
const c = carbohydrates.elements[i];
if (!c.hasRing) continue;
const cGeo = c.geometry!
const shapeType = getSaccharideShape(c.component.type)
switch (shapeType) {
case SaccharideShapes.FilledSphere:
builder.addIcosahedron(c.center, radius, 2)
builder.addIcosahedron(cGeo.center, radius, 2)
break;
case SaccharideShapes.FilledCube:
centerAlign(c.center, c.normal, c.direction)
centerAlign(cGeo.center, cGeo.normal, cGeo.direction)
builder.addBox(t, { width: side, height: side, depth: side })
break;
case SaccharideShapes.CrossedCube:
// TODO split
centerAlign(c.center, c.normal, c.direction)
centerAlign(cGeo.center, cGeo.normal, cGeo.direction)
builder.addBox(t, { width: side, height: side, depth: side })
break;
case SaccharideShapes.FilledCone:
Vec3.scaleAndAdd(p1, c.center, c.direction, radius)
Vec3.scaleAndSub(p2, c.center, c.direction, radius)
Vec3.scaleAndAdd(p1, cGeo.center, cGeo.direction, radius)
Vec3.scaleAndSub(p2, cGeo.center, cGeo.direction, radius)
builder.addCylinder(p1, p2, 1, coneParams)
break
case SaccharideShapes.DevidedCone:
// TODO split
Vec3.scaleAndAdd(p1, c.center, c.direction, radius)
Vec3.scaleAndSub(p2, c.center, c.direction, radius)
Vec3.scaleAndAdd(p1, cGeo.center, cGeo.direction, radius)
Vec3.scaleAndSub(p2, cGeo.center, cGeo.direction, radius)
builder.addCylinder(p1, p2, 1, coneParams)
break
case SaccharideShapes.FlatBox:
centerAlign(c.center, c.normal, c.direction)
centerAlign(cGeo.center, cGeo.normal, cGeo.direction)
builder.addBox(t, { width: side, height: side / 2, depth: side })
break
case SaccharideShapes.FilledStar:
centerAlign(c.center, c.normal, c.direction)
centerAlign(cGeo.center, cGeo.normal, cGeo.direction)
builder.addStar(t, { outerRadius: side, innerRadius: side / 2, thickness: side / 2, pointCount: 5 })
break
case SaccharideShapes.FilledDiamond:
case SaccharideShapes.DividedDiamond:
case SaccharideShapes.FlatDiamond:
case SaccharideShapes.Pentagon:
centerAlign(c.center, c.normal, c.direction)
centerAlign(cGeo.center, cGeo.normal, cGeo.direction)
builder.addBox(t, { width: side, height: side, depth: 0.5 })
break
case SaccharideShapes.FlatHexagon:
default:
centerAlign(c.center, c.normal, c.direction)
centerAlign(cGeo.center, cGeo.normal, cGeo.direction)
builder.addBox(t, { width: side, height: side, depth: 0.1 })
break
}
......@@ -98,14 +101,14 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru
for (let i = 0, il = carbohydrates.links.length; i < il; ++i) {
const l = carbohydrates.links[i]
const centerA = carbohydrates.elements[l.carbohydrateIndexA].center
const centerB = carbohydrates.elements[l.carbohydrateIndexB].center
const centerA = carbohydrates.elements[l.carbohydrateIndexA].geometry!.center
const centerB = carbohydrates.elements[l.carbohydrateIndexB].geometry!.center
builder.addCylinder(centerA, centerB, 0.5, linkParams)
}
for (let i = 0, il = carbohydrates.terminalLinks.length; i < il; ++i) {
const tl = carbohydrates.terminalLinks[i]
const center = carbohydrates.elements[tl.carbohydrateIndex].center
const center = carbohydrates.elements[tl.carbohydrateIndex].geometry!.center
tl.elementUnit.conformation.position(tl.elementUnit.elements[tl.elementIndex], p)
if (tl.fromCarbohydrate) {
builder.addCylinder(center, p, 0.5, linkParams)
......
......@@ -90,22 +90,22 @@ export function computeCarbohydrates(structure: Structure): Carbohydrates {
const terminalLinks: CarbohydrateTerminalLink[] = []
const elements: CarbohydrateElement[] = []
const elementsMap = new Map<string, number>()
const elementsWithRingMap = new Map<string, number>()
function elementKey(residueIndex: number, unitId: number) {
return `${residueIndex}|${unitId}`
}
function fixLinkDirection(iA: number, iB: number) {
Vec3.sub(elements[iA].direction, elements[iB].center, elements[iA].center)
Vec3.normalize(elements[iA].direction, elements[iA].direction)
Vec3.sub(elements[iA].geometry!.direction, elements[iB].geometry!.center, elements[iA].geometry!.center)
Vec3.normalize(elements[iA].geometry!.direction, elements[iA].geometry!.direction)
}
const tmpV = Vec3.zero()
function fixTerminalLinkDirection(iA: number, indexB: number, unitB: Unit.Atomic) {
const pos = unitB.conformation.position
Vec3.sub(elements[iA].direction, pos(unitB.elements[indexB], tmpV), elements[iA].center)
Vec3.normalize(elements[iA].direction, elements[iA].direction)
const pos = unitB.conformation.position, geo = elements[iA].geometry!;
Vec3.sub(geo.direction, pos(unitB.elements[indexB], tmpV), geo.center)
Vec3.normalize(geo.direction, geo.direction)
}
// get carbohydrate elements and carbohydrate links induced by intra-residue bonds
......@@ -140,7 +140,10 @@ export function computeCarbohydrates(structure: Structure): Carbohydrates {
const sugarRings = sugarResidueMap.get(residueIndex);
if (!sugarRings || !sugarRings.length) {
console.warn(`No ring found for carbohydrate on residue with index ${residueIndex}, unit ${unit.id}. Residue skipped.`);
elements.push({
hasRing: false,
unit, residueIndex, component: saccharideComp
})
continue;
}
......@@ -158,8 +161,12 @@ export function computeCarbohydrates(structure: Structure): Carbohydrates {
const elementIndex = elements.length
ringElements.push(elementIndex)
elementsMap.set(elementKey(residueIndex, unit.id), elementIndex)
elements.push({ center, normal, direction, unit, residueIndex, component: saccharideComp })
elementsWithRingMap.set(elementKey(residueIndex, unit.id), elementIndex)
elements.push({
geometry: { center, normal, direction, },
hasRing: true,
unit, residueIndex, component: saccharideComp
})
}
// add carbohydrate links induced by intra-residue bonds
......@@ -195,8 +202,8 @@ export function computeCarbohydrates(structure: Structure): Carbohydrates {
pairBonds.getBonds(indexA).forEach(bondInfo => {
const { unitA, unitB } = pairBonds
const indexB = bondInfo.indexB
const elementIndexA = elementsMap.get(elementKey(getResidueIndex(indexA, unitA), unitA.id))
const elementIndexB = elementsMap.get(elementKey(getResidueIndex(indexB, unitB), unitB.id))
const elementIndexA = elementsWithRingMap.get(elementKey(getResidueIndex(indexA, unitA), unitA.id))
const elementIndexB = elementsWithRingMap.get(elementKey(getResidueIndex(indexB, unitB), unitB.id))
if (elementIndexA !== undefined && elementIndexB !== undefined) {
if (getAtomId(unitA, indexA).startsWith('C1')) {
......
......@@ -23,11 +23,11 @@ export interface CarbohydrateTerminalLink {
}
export interface CarbohydrateElement {
readonly center: Vec3,
readonly normal: Vec3,
readonly direction: Vec3,
readonly unit: Unit.Atomic
readonly residueIndex: ResidueIndex
// geometry is only defined if at least one ring is present.
readonly geometry?: { readonly center: Vec3, readonly normal: Vec3, readonly direction: Vec3 },
readonly hasRing: boolean,
readonly unit: Unit.Atomic,
readonly residueIndex: ResidueIndex,
readonly component: SaccharideComponent
}
......
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