app.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import Viewer from 'mol-canvas3d/viewer';
  7. import { getCifFromUrl, getModelsFromMmcif, getCifFromFile, getCcp4FromUrl, getVolumeFromCcp4, getCcp4FromFile, getVolumeFromVolcif } from './util';
  8. import { StructureView } from './structure-view';
  9. import { BehaviorSubject } from 'rxjs';
  10. import { CifBlock } from 'mol-io/reader/cif';
  11. import { VolumeView } from './volume-view';
  12. import { Ccp4File } from 'mol-io/reader/ccp4/schema';
  13. export class App {
  14. viewer: Viewer
  15. container: HTMLDivElement | null = null;
  16. canvas: HTMLCanvasElement | null = null;
  17. structureView: StructureView | null = null;
  18. volumeView: VolumeView | null = null;
  19. structureLoaded: BehaviorSubject<StructureView | null> = new BehaviorSubject<StructureView | null>(null)
  20. volumeLoaded: BehaviorSubject<VolumeView | null> = new BehaviorSubject<VolumeView | null>(null)
  21. initViewer(_canvas: HTMLCanvasElement, _container: HTMLDivElement) {
  22. this.canvas = _canvas
  23. this.container = _container
  24. try {
  25. this.viewer = Viewer.create(this.canvas, this.container)
  26. this.viewer.animate()
  27. return true
  28. } catch (e) {
  29. console.error(e)
  30. return false
  31. }
  32. }
  33. setStatus(msg: string) {
  34. }
  35. private taskCount = 0
  36. taskCountChanged = new BehaviorSubject({ count: 0, info: '' })
  37. private changeTaskCount(delta: number, info = '') {
  38. this.taskCount += delta
  39. this.taskCountChanged.next({ count: this.taskCount, info })
  40. }
  41. async runTask<T>(promise: Promise<T>, info: string) {
  42. this.changeTaskCount(1, info)
  43. let result: T
  44. try {
  45. result = await promise
  46. } finally {
  47. this.changeTaskCount(-1)
  48. }
  49. return result
  50. }
  51. //
  52. async loadMmcif(cif: CifBlock, assemblyId?: string) {
  53. const models = await this.runTask(getModelsFromMmcif(cif), 'Build models')
  54. this.structureView = await this.runTask(StructureView(this, this.viewer, models, { assemblyId }), 'Init structure view')
  55. this.structureLoaded.next(this.structureView)
  56. }
  57. async loadPdbIdOrMmcifUrl(idOrUrl: string, options?: { assemblyId?: string, binary?: boolean }) {
  58. if (this.structureView) this.structureView.destroy();
  59. const url = idOrUrl.length <= 4 ? `https://files.rcsb.org/download/${idOrUrl}.cif` : idOrUrl;
  60. const cif = await this.runTask(getCifFromUrl(url, options ? !!options.binary : false), 'Load mmCIF from URL')
  61. this.loadMmcif(cif.blocks[0], options ? options.assemblyId : void 0)
  62. }
  63. async loadMmcifFile(file: File) {
  64. if (this.structureView) this.structureView.destroy();
  65. const binary = /\.bcif$/.test(file.name);
  66. const cif = await this.runTask(getCifFromFile(file, binary), 'Load mmCIF from file')
  67. this.loadMmcif(cif.blocks[0])
  68. }
  69. //
  70. async loadCcp4(ccp4: Ccp4File) {
  71. const volume = await this.runTask(getVolumeFromCcp4(ccp4), 'Get Volume')
  72. this.volumeView = await this.runTask(VolumeView(this, this.viewer, volume), 'Init volume view')
  73. this.volumeLoaded.next(this.volumeView)
  74. }
  75. async loadCcp4File(file: File) {
  76. if (this.volumeView) this.volumeView.destroy();
  77. const ccp4 = await this.runTask(getCcp4FromFile(file), 'Load CCP4 from file')
  78. this.loadCcp4(ccp4)
  79. }
  80. async loadCcp4Url(url: string) {
  81. if (this.volumeView) this.volumeView.destroy();
  82. const ccp4 = await this.runTask(getCcp4FromUrl(url), 'Load CCP4 from URL')
  83. this.loadCcp4(ccp4)
  84. }
  85. //
  86. async loadVolcif(cif: CifBlock) {
  87. const volume = await this.runTask(getVolumeFromVolcif(cif), 'Get Volume')
  88. this.volumeView = await this.runTask(VolumeView(this, this.viewer, volume), 'Init volume view')
  89. this.volumeLoaded.next(this.volumeView)
  90. }
  91. async loadVolcifFile(file: File) {
  92. if (this.volumeView) this.volumeView.destroy();
  93. const binary = /\.bcif$/.test(file.name);
  94. const cif = await this.runTask(getCifFromFile(file, binary), 'Load volCif from file')
  95. this.loadVolcif(cif.blocks[1])
  96. }
  97. async loadVolcifUrl(url: string, binary?: boolean) {
  98. if (this.volumeView) this.volumeView.destroy();
  99. const cif = await this.runTask(getCifFromUrl(url, binary), 'Load volCif from URL')
  100. this.loadVolcif(cif.blocks[1])
  101. }
  102. }