Browse Source

more adjustments to handle coarse elements

Alexander Rose 7 years ago
parent
commit
8f6a885cad

+ 1 - 1
src/apps/render-test/components/detail.tsx

@@ -38,7 +38,7 @@ export default class Detail extends Observer<{ state: State } & WithStyles, Deta
     render() {
         const { classes } = this.props;
 
-        const items = [0, 1, 2].map((value, idx) => {
+        const items = [0, 1, 2, 3].map((value, idx) => {
             return <MenuItem key={idx} value={value}>{value.toString()}</MenuItem>
         })
 

+ 4 - 0
src/mol-geo/primitive/icosahedron.ts

@@ -23,6 +23,10 @@ const indices = [
      4, 9, 5, 	2, 4, 11,	6, 2, 10,	8, 6, 7,	9, 8, 1
 ];
 
+export function icosahedronVertexCount(detail: number) {
+    return 10 * Math.pow(Math.pow(2, detail), 2) + 2
+}
+
 export const DefaultIcosahedronProps = {
     radius: 1,
     detail: 0

+ 10 - 6
src/mol-geo/representation/structure/point.ts

@@ -7,7 +7,7 @@
 import { ValueCell } from 'mol-util/value-cell'
 import { createPointRenderObject, RenderObject, PointRenderObject } from 'mol-gl/scene'
 import { OrderedSet } from 'mol-data/int'
-import { Unit, ElementGroup } from 'mol-model/structure';
+import { Unit, ElementGroup, Element } from 'mol-model/structure';
 import { Task } from 'mol-task'
 import { fillSerial } from 'mol-gl/renderable/util';
 
@@ -26,13 +26,17 @@ export type PointProps = Partial<typeof DefaultPointProps>
 export function createPointVertices(unit: Unit, elementGroup: ElementGroup) {
     const elementCount = OrderedSet.size(elementGroup.elements)
     const vertices = new Float32Array(elementCount * 3)
-    const { x, y, z } = unit.model.atomSiteConformation
+
+    const { x, y, z } = unit
+    const l = Element.Location()
+    l.unit = unit
+
     for (let i = 0; i < elementCount; i++) {
-        const e = OrderedSet.getAt(elementGroup.elements, i)
+        l.element = ElementGroup.getAt(elementGroup, i)
         const i3 = i * 3
-        vertices[i3] = x[e]
-        vertices[i3 + 1] = y[e]
-        vertices[i3 + 2] = z[e]
+        vertices[i3] = x(l.element)
+        vertices[i3 + 1] = y(l.element)
+        vertices[i3 + 2] = z(l.element)
     }
     return vertices
 }

+ 24 - 53
src/mol-geo/representation/structure/spacefill.ts

@@ -10,15 +10,15 @@ import { RenderObject, createMeshRenderObject, MeshRenderObject } from 'mol-gl/s
 // import { createColorTexture } from 'mol-gl/util';
 import { Vec3, Mat4 } from 'mol-math/linear-algebra'
 import { OrderedSet } from 'mol-data/int'
-import { Unit, ElementGroup } from 'mol-model/structure';
+import { Unit, ElementGroup, Element, Queries } from 'mol-model/structure';
 import { RepresentationProps, UnitsRepresentation } from './index';
 import { Task } from 'mol-task'
 import { MeshBuilder } from '../../shape/mesh-builder';
-import { VdwRadius } from 'mol-model/structure/model/properties/atomic';
 import { createTransforms, createColors } from './utils';
 import { ColorTheme } from '../../theme';
 import VertexMap from '../../shape/vertex-map';
 import CoarseGrained from 'mol-model/structure/model/properties/coarse-grained';
+import { icosahedronVertexCount } from '../../primitive/icosahedron';
 
 export const DefaultSpacefillProps = {
     detail: 0,
@@ -26,72 +26,43 @@ export const DefaultSpacefillProps = {
 }
 export type SpacefillProps = Partial<typeof DefaultSpacefillProps>
 
-function buildAtomSpheres(meshBuilder: MeshBuilder, unit: Unit, elementGroup: ElementGroup, detail: number) {
-    return Task.create('Atom spheres', async ctx => {
-        if (!Unit.isAtomic(unit)) return
-
-        const v = Vec3.zero()
-        const m = Mat4.identity()
-
-        const { x, y, z } = unit.model.atomSiteConformation
-        const { type_symbol } = unit.model.hierarchy.atoms
+function createSpacefillMesh(unit: Unit, elementGroup: ElementGroup, detail: number) {
+    return Task.create('Sphere mesh', async ctx => {
         const elementCount = OrderedSet.size(elementGroup.elements)
-        for (let i = 0; i < elementCount; i++) {
-            const e = OrderedSet.getAt(elementGroup.elements, i)
-            v[0] = x[e]
-            v[1] = y[e]
-            v[2] = z[e]
-            Mat4.setTranslation(m, v)
+        const vertexCount = elementCount * icosahedronVertexCount(detail)
+        const meshBuilder = MeshBuilder.create(vertexCount)
 
-            meshBuilder.setId(i)
-            meshBuilder.addIcosahedron(m, { radius: VdwRadius(type_symbol.value(e)), detail })
-
-            if (i % 10000 === 0 && ctx.shouldUpdate) {
-                await ctx.update({ message: 'Atom spheres', current: i, max: elementCount });
-            }
+        let radius: Element.Property<number>
+        if (Unit.isAtomic(unit)) {
+            radius = Queries.props.atom.vdw_radius
+        } else if (Unit.isCoarse(unit) && unit.elementType === CoarseGrained.ElementType.Sphere) {
+            radius = Queries.props.coarse_grained.sphere_radius
+        } else {
+            console.warn('Unsupported unit type')
+            return meshBuilder.getMesh()
         }
-    })
-}
-
-function buildCoarseSpheres(meshBuilder: MeshBuilder, unit: Unit, elementGroup: ElementGroup, detail: number) {
-    return Task.create('Coarse spheres', async ctx => {
-        if (!Unit.isCoarse(unit) || unit.elementType !== CoarseGrained.ElementType.Sphere) return
 
         const v = Vec3.zero()
         const m = Mat4.identity()
 
-        const { x, y, z, radius } = unit.model.coarseGrained.spheres
-        const elementCount = OrderedSet.size(elementGroup.elements)
-        console.log('building coarse spheres', elementCount)
+        const { x, y, z } = unit
+        const l = Element.Location()
+        l.unit = unit
+
         for (let i = 0; i < elementCount; i++) {
-            const e = OrderedSet.getAt(elementGroup.elements, i)
-            v[0] = x[e]
-            v[1] = y[e]
-            v[2] = z[e]
+            l.element = ElementGroup.getAt(elementGroup, i)
+            v[0] = x(l.element)
+            v[1] = y(l.element)
+            v[2] = z(l.element)
             Mat4.setTranslation(m, v)
 
             meshBuilder.setId(i)
-            meshBuilder.addIcosahedron(m, { radius: radius.value(e), detail })
+            meshBuilder.addIcosahedron(m, { radius: radius(l), detail })
 
             if (i % 10000 === 0 && ctx.shouldUpdate) {
-                await ctx.update({ message: 'Coarse spheres', current: i, max: elementCount });
+                await ctx.update({ message: 'Sphere mesh', current: i, max: elementCount });
             }
         }
-    })
-}
-
-function createSpacefillMesh(unit: Unit, elementGroup: ElementGroup, detail: number) {
-    return Task.create('Spacefill', async ctx => {
-        const meshBuilder = MeshBuilder.create()
-
-        if (Unit.isAtomic(unit)) {
-            await ctx.runChild(buildAtomSpheres(meshBuilder, unit, elementGroup, detail))
-        }
-
-        if (Unit.isCoarse(unit) && unit.elementType === CoarseGrained.ElementType.Sphere) {
-            console.log('building coarse spheres')
-            await ctx.runChild(buildCoarseSpheres(meshBuilder, unit, elementGroup, detail))
-        }
 
         return meshBuilder.getMesh()
     })

+ 2 - 2
src/mol-geo/representation/structure/utils.ts

@@ -9,7 +9,7 @@ import { Mat4 } from 'mol-math/linear-algebra'
 
 import { createUniformColor } from '../../util/color-data';
 import { createUniformSize } from '../../util/size-data';
-import { vdwSizeData } from '../../theme/structure/size/vdw';
+import { elementSizeData } from '../../theme/structure/size/element';
 import VertexMap from '../../shape/vertex-map';
 import { ColorTheme, SizeTheme } from '../../theme';
 import { elementIndexColorData, elementSymbolColorData, instanceIndexColorData, chainIdColorData } from '../../theme/structure/color';
@@ -43,6 +43,6 @@ export function createSizes(units: ReadonlyArray<Unit>, elementGroup: ElementGro
         case 'uniform':
             return createUniformSize(props)
         case 'vdw':
-            return vdwSizeData({ units, elementGroup, vertexMap })
+            return elementSizeData({ units, elementGroup, vertexMap })
     }
 }

+ 31 - 0
src/mol-geo/theme/structure/size/element.ts

@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { ElementGroup, Element, Unit, Queries } from 'mol-model/structure';
+import CoarseGrained from 'mol-model/structure/model/properties/coarse-grained';
+import { StructureSizeDataProps } from '.';
+import { createAttributeSize } from '../../../util/size-data';
+
+/** Create attribute data with the size of an element, i.e. vdw for atoms and radius for coarse spheres */
+export function elementSizeData(props: StructureSizeDataProps) {
+    const { units, elementGroup, vertexMap } = props
+    const unit = units[0]
+    let radius: Element.Property<number>
+    if (Unit.isAtomic(unit)) {
+        radius = Queries.props.atom.vdw_radius
+    } else if (Unit.isCoarse(unit) && unit.elementType === CoarseGrained.ElementType.Sphere) {
+        radius = Queries.props.coarse_grained.sphere_radius
+    }
+    const l = Element.Location()
+    l.unit = unit
+    return createAttributeSize({
+        sizeFn: (elementIdx: number) => {
+            l.element = ElementGroup.getAt(elementGroup, elementIdx)
+            return radius(l)
+        },
+        vertexMap
+    })
+}

+ 1 - 1
src/mol-geo/theme/structure/size/index.ts

@@ -13,4 +13,4 @@ export interface StructureSizeDataProps {
     vertexMap: VertexMap
 }
 
-export { vdwSizeData } from './vdw'
+export { elementSizeData } from './element'

+ 0 - 23
src/mol-geo/theme/structure/size/vdw.ts

@@ -1,23 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import { OrderedSet } from 'mol-data/int';
-import { VdwRadius } from 'mol-model/structure/model/properties/atomic';
-import { StructureSizeDataProps } from '.';
-import { createAttributeSize } from '../../../util/size-data';
-
-
-export function vdwSizeData(props: StructureSizeDataProps) {
-    const { units, elementGroup, vertexMap } = props
-    const { type_symbol } = units[0].model.hierarchy.atoms
-    return createAttributeSize({
-        sizeFn: (elementIdx: number) => {
-            const e = OrderedSet.getAt(elementGroup.elements, elementIdx)
-            return VdwRadius(type_symbol.value(e))
-        },
-        vertexMap
-    })
-}

+ 6 - 2
src/mol-model/structure/query/properties.ts

@@ -1,11 +1,12 @@
 /**
- * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
 import { Element, Unit } from '../structure'
 import CoarseGrained from '../model/properties/coarse-grained';
+import { VdwRadius } from '../model/properties/atomic';
 
 const constant = {
     true: Element.property(l => true),
@@ -38,7 +39,10 @@ const atom = {
     label_atom_id: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.atoms.label_atom_id.value(l.element)),
     auth_atom_id: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.atoms.auth_atom_id.value(l.element)),
     label_alt_id: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.atoms.label_alt_id.value(l.element)),
-    pdbx_formal_charge: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.atoms.pdbx_formal_charge.value(l.element))
+    pdbx_formal_charge: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.atoms.pdbx_formal_charge.value(l.element)),
+
+    // Derived
+    vdw_radius: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : VdwRadius(l.unit.hierarchy.atoms.type_symbol.value(l.element))),
 }
 
 const residue = {