|
@@ -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()
|