Browse Source

wip, canvas example app

Alexander Rose 6 years ago
parent
commit
54148c8e79
2 changed files with 126 additions and 44 deletions
  1. 1 1
      src/apps/canvas/index.html
  2. 125 43
      src/apps/canvas/index.ts

+ 1 - 1
src/apps/canvas/index.html

@@ -6,7 +6,7 @@
         <title>Mol* Canvas</title>
     </head>
     <body>
-        <div id="container" style="width:800px; height: 600px;">
+        <div id="container" style="width:1024px; height: 768px;">
             <canvas id="canvas"></canvas>
         </div>
         <span id="info"></span>

+ 125 - 43
src/apps/canvas/index.ts

@@ -16,14 +16,17 @@ import { BallAndStickRepresentation } from 'mol-geo/representation/structure/rep
 import { EveryLoci } from 'mol-model/loci';
 import { MarkerAction } from 'mol-geo/util/marker-data';
 import { labelFirst } from 'mol-view/label';
-import { Queries as Q, StructureProperties as SP, StructureSelection, StructureQuery } from 'mol-model/structure';
+// import { Queries as Q, StructureProperties as SP, StructureSelection, StructureQuery } from 'mol-model/structure';
 import { MeshBuilder } from 'mol-geo/mesh/mesh-builder';
 import { ShapeRepresentation } from 'mol-geo/representation/shape';
-import { Vec3, Mat4 } from 'mol-math/linear-algebra';
+import { /*Vec3, Mat4,*/ Tensor } from 'mol-math/linear-algebra';
 import { Shape } from 'mol-model/shape';
 import { Color } from 'mol-util/color';
 import { addSphere } from 'mol-geo/mesh/builder/sphere';
-import { Box } from 'mol-geo/primitive/box';
+// import { Box } from 'mol-geo/primitive/box';
+import { AssemblySymmetry } from 'mol-model-props/rcsb/symmetry';
+import { addCylinder } from 'mol-geo/mesh/builder/cylinder';
+import { Table } from 'mol-data/db';
 
 const container = document.getElementById('container')
 if (!container) throw new Error('Can not find element with id "container".')
@@ -84,11 +87,57 @@ async function getStructureFromModel(model: Model, assembly = '1') {
     }
 }
 
+function getAxesShape(featureId: number, assemblySymmetry: AssemblySymmetry) {
+    const f = assemblySymmetry.db.rcsb_assembly_symmetry_feature
+    const feature = Table.pickRow(f, i => f.id.value(i) === featureId)
+    if (!feature) return
+
+    const axes = assemblySymmetry.getAxes(featureId)
+    if (!axes._rowCount) return
+
+    const vectorSpace = AssemblySymmetry.Schema.rcsb_assembly_symmetry_axis.start.space;
+
+    const colors: Color[] = []
+    const labels: string[] = []
+
+    const radius = 0.4
+    const cylinderProps = { radiusTop: radius, radiusBottom: radius }
+    const meshBuilder = MeshBuilder.create(256, 128)
+
+    for (let i = 0, il = axes._rowCount; i < il; ++i) {
+        const start = Tensor.toVec3(vectorSpace, axes.start.value(i))
+        const end = Tensor.toVec3(vectorSpace, axes.end.value(i))
+        meshBuilder.setGroup(i)
+        addSphere(meshBuilder, start, radius, 2)
+        addSphere(meshBuilder, end, radius, 2)
+        addCylinder(meshBuilder, start, end, 1, cylinderProps)
+        colors.push(Color(0xCCEE11))
+        labels.push(`Axis ${i + 1} for ${feature.symmetry_value} ${feature.type.toLowerCase()} symmetry`)
+    }
+    const mesh = meshBuilder.getMesh()
+    const shape = Shape.create('Axes', mesh, colors, labels)
+    return shape
+}
+
+function getClusterColorTheme(featureId: number, assemblySymmetry: AssemblySymmetry) {
+    const f = assemblySymmetry.db.rcsb_assembly_symmetry_feature
+    const feature = Table.pickRow(f, i => f.id.value(i) === featureId)
+    if (!feature) return
+
+    const clusters = assemblySymmetry.getClusters(featureId)
+    if (!clusters._rowCount) return
+
+    for (let i = 0, il = clusters._rowCount; i < il; ++i) {
+        console.log(clusters.members.value(i), clusters.avg_rmsd.value(i), feature.stoichiometry_value, feature.stoichiometry_description)
+    }
+}
+
 async function init() {
-    const cif = await getCifFromUrl('https://files.rcsb.org/download/1crn.cif')
-    const model = await getModelFromMmcif(cif)
-    const structure = await getStructureFromModel(model)
+    const assembly = '1'
 
+    const cif = await getCifFromUrl('https://files.rcsb.org/download/4hhb.cif')
+    const model = await getModelFromMmcif(cif)
+    const structure = await getStructureFromModel(model, assembly)
     viewer.center(structure.boundary.sphere.center)
 
     // cartoon for whole structure
@@ -100,52 +149,85 @@ async function init() {
     }).run()
     viewer.add(cartoonRepr)
 
-    // create new structure via query
-    const q1 = Q.generators.atoms({
-        residueTest: qtx => SP.residue.label_seq_id(qtx.element) < 7
-    });
-    const newStructure = StructureSelection.unionStructure(await StructureQuery.run(q1, structure));
-
-    // ball+stick for new structure
+    // ball+stick for whole structure
     const ballStickRepr = BallAndStickRepresentation()
-    await ballStickRepr.create(newStructure, {
+    await ballStickRepr.create(structure, {
         colorTheme: { name: 'element-symbol' },
         sizeTheme: { name: 'uniform', value: 0.1 },
         useFog: false // TODO fog not working properly
     }).run()
     viewer.add(ballStickRepr)
 
-    // create a mesh
-    const meshBuilder = MeshBuilder.create(256, 128)
-    const colors: Color[] = []
-    const labels: string[] = []
-    // red sphere
-    meshBuilder.setGroup(0)
-    colors[0] = Color(0xFF2233)
-    labels[0] = 'red sphere'
-    addSphere(meshBuilder, Vec3.create(0, 0, 0), 4, 2)
-    // green cube
-    meshBuilder.setGroup(1)
-    colors[1] = Color(0x2233FF)
-    labels[1] = 'blue cube'
-    const t = Mat4.identity()
-    Mat4.fromTranslation(t, Vec3.create(10, 0, 0))
-    Mat4.scale(t, t, Vec3.create(3, 3, 3))
-    meshBuilder.add(t, Box())
-    const mesh = meshBuilder.getMesh()
+    // // create new structure via query
+    // const q1 = Q.generators.atoms({
+    //     residueTest: qtx => SP.residue.label_seq_id(qtx.element) < 7
+    // });
+    // const newStructure = StructureSelection.unionStructure(await StructureQuery.run(q1, structure));
+
+    // // ball+stick for new structure
+    // const newBallStickRepr = BallAndStickRepresentation()
+    // await newBallStickRepr.create(newStructure, {
+    //     colorTheme: { name: 'element-symbol' },
+    //     sizeTheme: { name: 'uniform', value: 0.1 },
+    //     useFog: false // TODO fog not working properly
+    // }).run()
+    // viewer.add(newBallStickRepr)
+
+    // // create a mesh
+    // const meshBuilder = MeshBuilder.create(256, 128)
+    // const colors: Color[] = []
+    // const labels: string[] = []
+    // // red sphere
+    // meshBuilder.setGroup(0)
+    // colors[0] = Color(0xFF2233)
+    // labels[0] = 'red sphere'
+    // addSphere(meshBuilder, Vec3.create(0, 0, 0), 4, 2)
+    // // green cube
+    // meshBuilder.setGroup(1)
+    // colors[1] = Color(0x2233FF)
+    // labels[1] = 'blue cube'
+    // const t = Mat4.identity()
+    // Mat4.fromTranslation(t, Vec3.create(10, 0, 0))
+    // Mat4.scale(t, t, Vec3.create(3, 3, 3))
+    // meshBuilder.add(t, Box())
+    // const mesh = meshBuilder.getMesh()
     // const mesh = getObjFromUrl('mesh.obj')
 
-    // create shape from mesh
-    const shape = Shape.create('myShape', mesh, colors, labels)
-
-    // add representation from shape
-    const customRepr = ShapeRepresentation()
-    await customRepr.create(shape, {
-        colorTheme: { name: 'shape-group' },
-        // colorTheme: { name: 'uniform', value: Color(0xFFCC22) },
-        useFog: false // TODO fog not working properly
-    }).run()
-    viewer.add(customRepr)
+    // // create shape from mesh
+    // const shape = Shape.create('myShape', mesh, colors, labels)
+
+    // // add representation from shape
+    // const customRepr = ShapeRepresentation()
+    // await customRepr.create(shape, {
+    //     colorTheme: { name: 'shape-group' },
+    //     // colorTheme: { name: 'uniform', value: Color(0xFFCC22) },
+    //     useFog: false // TODO fog not working properly
+    // }).run()
+    // viewer.add(customRepr)
+
+
+    await AssemblySymmetry.attachFromCifOrAPI(model)
+    const assemblySymmetry = AssemblySymmetry.get(model)
+    console.log(assemblySymmetry)
+    if (assemblySymmetry) {
+        const features = assemblySymmetry.getFeatures(assembly)
+        if (features._rowCount) {
+            const axesShape = getAxesShape(features.id.value(1), assemblySymmetry)
+            console.log(axesShape)
+            if (axesShape) {
+                const customRepr = ShapeRepresentation()
+                await customRepr.create(axesShape, {
+                    colorTheme: { name: 'shape-group' },
+                    // colorTheme: { name: 'uniform', value: Color(0xFFCC22) },
+                    useFog: false // TODO fog not working properly
+                }).run()
+                viewer.add(customRepr)
+            }
+
+            getClusterColorTheme(features.id.value(0), assemblySymmetry)
+            getClusterColorTheme(features.id.value(1), assemblySymmetry)
+        }
+    }
 
     // ensure the added representations get rendered, i.e. without mouse input
     viewer.requestDraw()