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

wip, server-side image-generator app

parent 1a846c78
No related branches found
No related tags found
No related merge requests found
...@@ -115,7 +115,18 @@ Run the image ...@@ -115,7 +115,18 @@ Run the image
To see all available commands, use ``node build/model-server/preprocess -h``. To see all available commands, use ``node build/model-server/preprocess -h``.
## Editor ## Development
### Intallation
If node complains about a missine acorn peer dependency, run the following commands
npm update acorn --depth 20
npm dedupe
If the `gl` package does not compile on node 12 (there are currently no pre-built binaries) revert back to node 10.
### Editor
To get syntax highlighting for the shader files add the following to Visual Code's settings files To get syntax highlighting for the shader files add the following to Visual Code's settings files
......
...@@ -79,13 +79,15 @@ ...@@ -79,13 +79,15 @@
"@types/benchmark": "^1.0.31", "@types/benchmark": "^1.0.31",
"@types/compression": "0.0.36", "@types/compression": "0.0.36",
"@types/express": "^4.16.1", "@types/express": "^4.16.1",
"@types/gl": "^4.1.0",
"@types/jest": "^24.0.12", "@types/jest": "^24.0.12",
"@types/node": "^12.0.1", "@types/node": "^12.0.1",
"@types/node-fetch": "^2.3.3", "@types/node-fetch": "^2.3.3",
"@types/pngjs": "^3.3.2",
"@types/react": "^16.8.17", "@types/react": "^16.8.17",
"@types/react-dom": "^16.8.4", "@types/react-dom": "^16.8.4",
"@types/webgl2": "0.0.4",
"@types/swagger-ui-dist": "3.0.0", "@types/swagger-ui-dist": "3.0.0",
"@types/webgl2": "0.0.4",
"benchmark": "^2.1.4", "benchmark": "^2.1.4",
"circular-dependency-plugin": "^5.0.2", "circular-dependency-plugin": "^5.0.2",
"concurrently": "^4.1.0", "concurrently": "^4.1.0",
...@@ -93,7 +95,7 @@ ...@@ -93,7 +95,7 @@
"css-loader": "^2.1.1", "css-loader": "^2.1.1",
"extra-watch-webpack-plugin": "^1.0.3", "extra-watch-webpack-plugin": "^1.0.3",
"file-loader": "^3.0.1", "file-loader": "^3.0.1",
"graphql-code-generator": "^0.18.1", "graphql-code-generator": "^0.18.2",
"graphql-codegen-time": "^0.18.1", "graphql-codegen-time": "^0.18.1",
"graphql-codegen-typescript-template": "^0.18.1", "graphql-codegen-typescript-template": "^0.18.1",
"jest": "^24.8.0", "jest": "^24.8.0",
...@@ -116,9 +118,11 @@ ...@@ -116,9 +118,11 @@
"argparse": "^1.0.10", "argparse": "^1.0.10",
"compression": "^1.7.4", "compression": "^1.7.4",
"express": "^4.16.4", "express": "^4.16.4",
"gl": "^4.2.2",
"graphql": "^14.3.0", "graphql": "^14.3.0",
"immutable": "^3.8.2", "immutable": "^3.8.2",
"node-fetch": "^2.5.0", "node-fetch": "^2.5.0",
"pngjs": "^3.4.0",
"react": "^16.8.6", "react": "^16.8.6",
"react-dom": "^16.8.6", "react-dom": "^16.8.6",
"rxjs": "^6.5.2", "rxjs": "^6.5.2",
......
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import * as argparse from 'argparse'
import createContext = require('gl')
import fs = require('fs')
import { PNG } from 'pngjs'
import { Canvas3D, Canvas3DParams } from 'mol-canvas3d/canvas3d';
import InputObserver from 'mol-util/input/input-observer';
import { ColorTheme } from 'mol-theme/color';
import { SizeTheme } from 'mol-theme/size';
import { CartoonRepresentationProvider } from 'mol-repr/structure/representation/cartoon';
import CIF, { CifFrame } from 'mol-io/reader/cif'
import { trajectoryFromMmCIF } from 'mol-model-formats/structure/mmcif';
import { Model, Structure } from 'mol-model/structure';
import { ajaxGet } from 'mol-util/data-source';
import { ColorNames } from 'mol-util/color/tables';
const width = 1024
const height = 768
const gl = createContext(width, height, {
alpha: false,
antialias: true,
depth: true,
preserveDrawingBuffer: true
})
const input = InputObserver.create()
const canvas3d = Canvas3D.create(gl, input, {
multiSample: 'on',
sampleLevel: 3,
renderer: {
...Canvas3DParams.renderer.defaultValue,
lightIntensity: 0,
ambientIntensity: 1,
backgroundColor: ColorNames.white
},
postprocessing: {
...Canvas3DParams.postprocessing.defaultValue,
occlusionEnable: true,
outlineEnable: true
}
})
canvas3d.animate()
const reprCtx = {
wegbl: canvas3d.webgl,
colorThemeRegistry: ColorTheme.createRegistry(),
sizeThemeRegistry: SizeTheme.createRegistry()
}
function getCartoonRepr() {
return CartoonRepresentationProvider.factory(reprCtx, CartoonRepresentationProvider.getParams)
}
async function parseCif(data: string|Uint8Array) {
const comp = CIF.parse(data);
const parsed = await comp.run();
if (parsed.isError) throw parsed;
return parsed.result;
}
async function downloadCif(url: string, isBinary: boolean) {
const data = await ajaxGet({ url, type: isBinary ? 'binary' : 'string' }).run();
return parseCif(data);
}
async function downloadFromPdb(pdb: string) {
const parsed = await downloadCif(`https://files.rcsb.org/download/${pdb}.cif`, false);
// const parsed = await downloadCif(`https://webchem.ncbr.muni.cz/ModelServer/static/bcif/${pdb}`, true);
return parsed.blocks[0];
}
async function getModels(frame: CifFrame) {
return await trajectoryFromMmCIF(frame).run();
}
async function getStructure(model: Model) {
return Structure.ofModel(model);
}
async function run(id: string, out: string) {
try {
const cif = await downloadFromPdb(id)
const models = await getModels(cif)
const structure = await getStructure(models[0])
const cartoonRepr = getCartoonRepr()
cartoonRepr.setTheme({
color: reprCtx.colorThemeRegistry.create('sequence-id', { structure }),
size: reprCtx.sizeThemeRegistry.create('uniform', { structure })
})
await cartoonRepr.createOrUpdate({ ...CartoonRepresentationProvider.defaultValues, quality: 'auto' }, structure).run()
canvas3d.add(cartoonRepr)
canvas3d.resetCamera()
} catch (e) {
console.log(e)
process.exit(1)
}
setTimeout(() => {
const pixelData = canvas3d.getPixelData('draw')
const png = new PNG({ width, height })
png.data = Buffer.from(pixelData.array)
png.pack().pipe(fs.createWriteStream(out)).on('finish', () => {
process.exit()
})
}, 2000)
}
//
const parser = new argparse.ArgumentParser({
addHelp: true,
description: 'render image as PNG (work in progress)'
});
parser.addArgument([ '--id', '-i' ], {
required: true,
help: 'PDB ID'
});
parser.addArgument([ '--out', '-o' ], {
required: true,
help: 'image output path'
});
interface Args {
id: string
out: string
}
const args: Args = parser.parseArgs();
run(args.id, args.out)
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment