volume.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. */
  6. import * as fs from 'fs'
  7. import * as argparse from 'argparse'
  8. import * as util from 'util'
  9. import { VolumeData, VolumeIsoValue } from 'mol-model/volume'
  10. import { downloadCif } from './helpers'
  11. import CIF from 'mol-io/reader/cif'
  12. import { DensityServer_Data_Database } from 'mol-io/reader/cif/schema/density-server';
  13. import { Table } from 'mol-data/db';
  14. import { StringBuilder } from 'mol-util';
  15. import { Task } from 'mol-task';
  16. import { createVolumeIsosurfaceMesh } from 'mol-repr/volume/isosurface';
  17. import { createEmptyTheme } from 'mol-theme/theme';
  18. import { volumeFromDensityServerData } from 'mol-model-formats/volume/density-server';
  19. require('util.promisify').shim();
  20. const writeFileAsync = util.promisify(fs.writeFile);
  21. type Volume = { source: DensityServer_Data_Database, volume: VolumeData }
  22. async function getVolume(url: string): Promise<Volume> {
  23. const cif = await downloadCif(url, true);
  24. const data = CIF.schema.densityServer(cif.blocks[1]);
  25. return { source: data, volume: await volumeFromDensityServerData(data).run() };
  26. }
  27. function print(data: Volume) {
  28. const { volume_data_3d_info } = data.source;
  29. const row = Table.getRow(volume_data_3d_info, 0);
  30. console.log(row);
  31. console.log(data.volume.cell);
  32. console.log(data.volume.dataStats);
  33. console.log(data.volume.fractionalBox);
  34. }
  35. async function doMesh(data: Volume, filename: string) {
  36. const mesh = await Task.create('', runtime => createVolumeIsosurfaceMesh({ runtime }, data.volume, createEmptyTheme(), { isoValue: VolumeIsoValue.absolute(1.5) } )).run();
  37. console.log({ vc: mesh.vertexCount, tc: mesh.triangleCount });
  38. // Export the mesh in OBJ format.
  39. const { vertexCount, triangleCount } = mesh;
  40. const vs = mesh.vertexBuffer.ref.value;
  41. const ts = mesh.indexBuffer.ref.value;
  42. const obj = StringBuilder.create();
  43. for (let i = 0; i < vertexCount; i++) {
  44. StringBuilder.write(obj, 'v ');
  45. StringBuilder.writeFloat(obj, vs[3 * i + 0], 100);
  46. StringBuilder.whitespace1(obj);
  47. StringBuilder.writeFloat(obj, vs[3 * i + 1], 100);
  48. StringBuilder.whitespace1(obj);
  49. StringBuilder.writeFloat(obj, vs[3 * i + 2], 100);
  50. StringBuilder.newline(obj);
  51. }
  52. for (let i = 0; i < triangleCount; i++) {
  53. StringBuilder.write(obj, 'f ');
  54. StringBuilder.writeIntegerAndSpace(obj, ts[3 * i + 0] + 1);
  55. StringBuilder.writeIntegerAndSpace(obj, ts[3 * i + 1] + 1);
  56. StringBuilder.writeInteger(obj, ts[3 * i + 2] + 1);
  57. StringBuilder.newline(obj);
  58. }
  59. await writeFileAsync(filename, StringBuilder.getString(obj));
  60. }
  61. async function run(url: string, meshFilename: string) {
  62. const volume = await getVolume(url);
  63. print(volume);
  64. await doMesh(volume, meshFilename);
  65. }
  66. const parser = new argparse.ArgumentParser({
  67. addHelp: true,
  68. description: 'Info about VolumeData from mol-model module'
  69. });
  70. parser.addArgument([ '--emdb', '-e' ], {
  71. help: 'EMDB id, for example 8116',
  72. });
  73. parser.addArgument([ '--mesh' ], {
  74. help: 'Mesh filename',
  75. required: true
  76. });
  77. interface Args {
  78. emdb?: string,
  79. mesh: string
  80. }
  81. const args: Args = parser.parseArgs();
  82. run(`https://ds.litemol.org/em/emd-${args.emdb}/cell?detail=4`, args.mesh);