index.ts 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /**
  2. * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. */
  6. import { EmptyLoci } from '../../mol-model/loci';
  7. import { StructureSelection } from '../../mol-model/structure';
  8. import { createPlugin, DefaultPluginSpec } from '../../mol-plugin';
  9. import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in';
  10. import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
  11. import { PluginStateObject } from '../../mol-plugin-state/objects';
  12. import { PluginCommands } from '../../mol-plugin/commands';
  13. import { PluginContext } from '../../mol-plugin/context';
  14. import { Script } from '../../mol-script/script';
  15. import { Color } from '../../mol-util/color';
  16. import { StripedResidues } from './coloring';
  17. import { CustomToastMessage } from './controls';
  18. import './index.html';
  19. import { buildStaticSuperposition, dynamicSuperpositionTest, StaticSuperpositionTestData } from './superposition';
  20. import { PDBeStructureQualityReport } from '../../extensions/pdbe';
  21. require('mol-plugin-ui/skin/light.scss');
  22. type LoadParams = { url: string, format?: BuiltInTrajectoryFormat, isBinary?: boolean, assemblyId?: string }
  23. class BasicWrapper {
  24. plugin: PluginContext;
  25. init(target: string | HTMLElement) {
  26. this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
  27. ...DefaultPluginSpec,
  28. layout: {
  29. initial: {
  30. isExpanded: false,
  31. showControls: false
  32. },
  33. controls: {
  34. // left: 'none'
  35. }
  36. },
  37. components: {
  38. remoteState: 'none'
  39. }
  40. });
  41. this.plugin.representation.structure.themes.colorThemeRegistry.add(StripedResidues.colorThemeProvider!);
  42. this.plugin.managers.lociLabels.addProvider(StripedResidues.labelProvider!);
  43. this.plugin.customModelProperties.register(StripedResidues.propertyProvider, true);
  44. }
  45. async load({ url, format = 'mmcif', isBinary = false, assemblyId = '' }: LoadParams) {
  46. await this.plugin.clear();
  47. const data = await this.plugin.builders.data.download({ url, isBinary }, { state: { isGhost: true } });
  48. const trajectory = await this.plugin.builders.structure.parseTrajectory(data, format);
  49. await this.plugin.builders.structure.hierarchy.applyPreset(trajectory, 'default', {
  50. structure: assemblyId ? { name: 'assembly', params: { id: assemblyId } } : { name: 'deposited', params: { } },
  51. showUnitcell: false,
  52. representationPreset: 'auto'
  53. });
  54. }
  55. setBackground(color: number) {
  56. PluginCommands.Canvas3D.SetSettings(this.plugin, { settings: props => { props.renderer.backgroundColor = Color(color); } });
  57. }
  58. toggleSpin() {
  59. if (!this.plugin.canvas3d) return;
  60. PluginCommands.Canvas3D.SetSettings(this.plugin, {
  61. settings: props => {
  62. props.trackball.spin = !props.trackball.spin;
  63. }
  64. });
  65. if (!this.plugin.canvas3d.props.trackball.spin) PluginCommands.Camera.Reset(this.plugin, {});
  66. }
  67. animate = {
  68. modelIndex: {
  69. maxFPS: 8,
  70. onceForward: () => { this.plugin.state.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'forward' } } }); },
  71. onceBackward: () => { this.plugin.state.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'backward' } } }); },
  72. palindrome: () => { this.plugin.state.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'palindrome', params: {} } }); },
  73. loop: () => { this.plugin.state.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'loop', params: {} } }); },
  74. stop: () => this.plugin.state.animation.stop()
  75. }
  76. }
  77. coloring = {
  78. applyStripes: async () => {
  79. this.plugin.dataTransaction(async () => {
  80. for (const s of this.plugin.managers.structure.hierarchy.current.structures) {
  81. await this.plugin.managers.structure.component.updateRepresentationsTheme(s.components, { color: StripedResidues.propertyProvider.descriptor.name as any });
  82. }
  83. });
  84. },
  85. applyDefault: async () => {
  86. this.plugin.dataTransaction(async () => {
  87. for (const s of this.plugin.managers.structure.hierarchy.current.structures) {
  88. await this.plugin.managers.structure.component.updateRepresentationsTheme(s.components, { color: 'default' });
  89. }
  90. });
  91. }
  92. }
  93. interactivity = {
  94. highlightOn: () => {
  95. const seq_id = 7;
  96. const data = (this.plugin.state.data.select('asm')[0].obj as PluginStateObject.Molecule.Structure).data;
  97. const sel = Script.getStructureSelection(Q => Q.struct.generator.atomGroups({
  98. 'residue-test': Q.core.rel.eq([Q.struct.atomProperty.macromolecular.label_seq_id(), seq_id]),
  99. 'group-by': Q.struct.atomProperty.macromolecular.residueKey()
  100. }), data);
  101. const loci = StructureSelection.toLociWithSourceUnits(sel);
  102. this.plugin.managers.interactivity.lociHighlights.highlightOnly({ loci });
  103. },
  104. clearHighlight: () => {
  105. this.plugin.managers.interactivity.lociHighlights.highlightOnly({ loci: EmptyLoci });
  106. }
  107. }
  108. tests = {
  109. staticSuperposition: async () => {
  110. await this.plugin.clear();
  111. return buildStaticSuperposition(this.plugin, StaticSuperpositionTestData);
  112. },
  113. dynamicSuperposition: async () => {
  114. await this.plugin.clear();
  115. return dynamicSuperpositionTest(this.plugin, ['1tqn', '2hhb', '4hhb'], 'HEM');
  116. },
  117. toggleValidationTooltip: () => {
  118. return this.plugin.state.updateBehavior(PDBeStructureQualityReport, params => { params.showTooltip = !params.showTooltip; });
  119. },
  120. showToasts: () => {
  121. PluginCommands.Toast.Show(this.plugin, {
  122. title: 'Toast 1',
  123. message: 'This is an example text, timeout 3s',
  124. key: 'toast-1',
  125. timeoutMs: 3000
  126. });
  127. PluginCommands.Toast.Show(this.plugin, {
  128. title: 'Toast 2',
  129. message: CustomToastMessage,
  130. key: 'toast-2'
  131. });
  132. },
  133. hideToasts: () => {
  134. PluginCommands.Toast.Hide(this.plugin, { key: 'toast-1' });
  135. PluginCommands.Toast.Hide(this.plugin, { key: 'toast-2' });
  136. }
  137. }
  138. }
  139. (window as any).BasicMolStarWrapper = new BasicWrapper();