volume.ts 3.2 KB

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