index.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /**
  2. * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import * as argparse from 'argparse'
  7. import createContext = require('gl')
  8. import fs = require('fs')
  9. import { PNG } from 'pngjs'
  10. import { Canvas3D, Canvas3DParams } from '../../mol-canvas3d/canvas3d';
  11. import InputObserver from '../../mol-util/input/input-observer';
  12. import { ColorTheme } from '../../mol-theme/color';
  13. import { SizeTheme } from '../../mol-theme/size';
  14. import { CartoonRepresentationProvider } from '../../mol-repr/structure/representation/cartoon';
  15. import { CIF, CifFrame } from '../../mol-io/reader/cif'
  16. import { trajectoryFromMmCIF } from '../../mol-model-formats/structure/mmcif';
  17. import { Model, Structure } from '../../mol-model/structure';
  18. import { ajaxGet } from '../../mol-util/data-source';
  19. import { ColorNames } from '../../mol-util/color/tables';
  20. const width = 2048
  21. const height = 1536
  22. const gl = createContext(width, height, {
  23. alpha: false,
  24. antialias: true,
  25. depth: true,
  26. preserveDrawingBuffer: true
  27. })
  28. const input = InputObserver.create()
  29. const canvas3d = Canvas3D.create(gl, input, {
  30. multiSample: {
  31. mode: 'on',
  32. sampleLevel: 3
  33. },
  34. renderer: {
  35. ...Canvas3DParams.renderer.defaultValue,
  36. lightIntensity: 0,
  37. ambientIntensity: 1,
  38. backgroundColor: ColorNames.white
  39. },
  40. postprocessing: {
  41. ...Canvas3DParams.postprocessing.defaultValue,
  42. occlusionEnable: true,
  43. outlineEnable: true
  44. }
  45. })
  46. canvas3d.animate()
  47. const reprCtx = {
  48. wegbl: canvas3d.webgl,
  49. colorThemeRegistry: ColorTheme.createRegistry(),
  50. sizeThemeRegistry: SizeTheme.createRegistry()
  51. }
  52. function getCartoonRepr() {
  53. return CartoonRepresentationProvider.factory(reprCtx, CartoonRepresentationProvider.getParams)
  54. }
  55. async function parseCif(data: string|Uint8Array) {
  56. const comp = CIF.parse(data);
  57. const parsed = await comp.run();
  58. if (parsed.isError) throw parsed;
  59. return parsed.result;
  60. }
  61. async function downloadCif(url: string, isBinary: boolean) {
  62. const data = await ajaxGet({ url, type: isBinary ? 'binary' : 'string' }).run();
  63. return parseCif(data);
  64. }
  65. async function downloadFromPdb(pdb: string) {
  66. const parsed = await downloadCif(`https://files.rcsb.org/download/${pdb}.cif`, false);
  67. // const parsed = await downloadCif(`https://webchem.ncbr.muni.cz/ModelServer/static/bcif/${pdb}`, true);
  68. return parsed.blocks[0];
  69. }
  70. async function getModels(frame: CifFrame) {
  71. return await trajectoryFromMmCIF(frame).run();
  72. }
  73. async function getStructure(model: Model) {
  74. return Structure.ofModel(model);
  75. }
  76. async function run(id: string, out: string) {
  77. try {
  78. const cif = await downloadFromPdb(id)
  79. const models = await getModels(cif)
  80. const structure = await getStructure(models[0])
  81. const cartoonRepr = getCartoonRepr()
  82. cartoonRepr.setTheme({
  83. color: reprCtx.colorThemeRegistry.create('sequence-id', { structure }),
  84. size: reprCtx.sizeThemeRegistry.create('uniform', { structure })
  85. })
  86. await cartoonRepr.createOrUpdate({ ...CartoonRepresentationProvider.defaultValues, quality: 'auto' }, structure).run()
  87. canvas3d.add(cartoonRepr)
  88. canvas3d.resetCamera()
  89. } catch (e) {
  90. console.log(e)
  91. process.exit(1)
  92. }
  93. setTimeout(() => {
  94. const pixelData = canvas3d.getPixelData('color')
  95. const png = new PNG({ width, height })
  96. png.data = Buffer.from(pixelData.array)
  97. png.pack().pipe(fs.createWriteStream(out)).on('finish', () => {
  98. process.exit()
  99. })
  100. }, 2000)
  101. }
  102. //
  103. const parser = new argparse.ArgumentParser({
  104. addHelp: true,
  105. description: 'render image as PNG (work in progress)'
  106. });
  107. parser.addArgument([ '--id', '-i' ], {
  108. required: true,
  109. help: 'PDB ID'
  110. });
  111. parser.addArgument([ '--out', '-o' ], {
  112. required: true,
  113. help: 'image output path'
  114. });
  115. interface Args {
  116. id: string
  117. out: string
  118. }
  119. const args: Args = parser.parseArgs();
  120. run(args.id, args.out)