hierarchy-preset.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /**
  2. * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  6. */
  7. import { PresetProvider } from '../preset-provider';
  8. import { PluginStateObject } from '../../objects';
  9. import { ParamDefinition as PD } from '../../../mol-util/param-definition';
  10. import { StateObjectRef, StateTransformer } from '../../../mol-state';
  11. import { StateTransforms } from '../../transforms';
  12. import { RootStructureDefinition } from '../../helpers/root-structure';
  13. import { PresetStructureRepresentations } from './representation-preset';
  14. import { PluginContext } from '../../../mol-plugin/context';
  15. import { Vec3 } from '../../../mol-math/linear-algebra';
  16. import { Model } from '../../../mol-model/structure';
  17. import { getStructureQuality } from '../../../mol-repr/util';
  18. export interface TrajectoryHierarchyPresetProvider<P = any, S = {}> extends PresetProvider<PluginStateObject.Molecule.Trajectory, P, S> { }
  19. export function TrajectoryHierarchyPresetProvider<P, S>(preset: TrajectoryHierarchyPresetProvider<P, S>) { return preset; }
  20. export namespace TrajectoryHierarchyPresetProvider {
  21. export type Params<P extends TrajectoryHierarchyPresetProvider> = P extends TrajectoryHierarchyPresetProvider<infer T> ? T : never;
  22. export type State<P extends TrajectoryHierarchyPresetProvider> = P extends TrajectoryHierarchyPresetProvider<infer _, infer S> ? S : never;
  23. export const CommonParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
  24. modelProperties: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.CustomModelProperties, void 0, plugin))),
  25. structureProperties: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.CustomStructureProperties, void 0, plugin))),
  26. representationPreset: PD.Optional(PD.Text<keyof PresetStructureRepresentations>('auto' as const)),
  27. });
  28. }
  29. const CommonParams = TrajectoryHierarchyPresetProvider.CommonParams;
  30. const DefaultParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
  31. model: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.ModelFromTrajectory, a, plugin))),
  32. showUnitcell: PD.Optional(PD.Boolean(false)),
  33. structure: PD.Optional(RootStructureDefinition.getParams(void 0, 'assembly').type),
  34. ...CommonParams(a, plugin)
  35. });
  36. const defaultPreset = TrajectoryHierarchyPresetProvider({
  37. id: 'preset-trajectory-default',
  38. display: {
  39. name: 'Default (Assembly)', group: 'Preset',
  40. description: 'Shows the first assembly or, if that is unavailable, the first model.'
  41. },
  42. isApplicable: o => {
  43. return true;
  44. },
  45. params: DefaultParams,
  46. async apply(trajectory, params, plugin) {
  47. const builder = plugin.builders.structure;
  48. const model = await builder.createModel(trajectory, params.model);
  49. const modelProperties = await builder.insertModelProperties(model, params.modelProperties);
  50. const structure = await builder.createStructure(modelProperties || model, params.structure);
  51. const structureProperties = await builder.insertStructureProperties(structure, params.structureProperties);
  52. const unitcell = params.showUnitcell === void 0 || !!params.showUnitcell ? await builder.tryCreateUnitcell(modelProperties, undefined, { isHidden: true }) : void 0;
  53. const representation = await plugin.builders.structure.representation.applyPreset(structureProperties, params.representationPreset || 'auto');
  54. return {
  55. model,
  56. modelProperties,
  57. unitcell,
  58. structure,
  59. structureProperties,
  60. representation
  61. };
  62. }
  63. });
  64. const allModels = TrajectoryHierarchyPresetProvider({
  65. id: 'preset-trajectory-all-models',
  66. display: {
  67. name: 'All Models', group: 'Preset',
  68. description: 'Shows all models; colored by model-index.'
  69. },
  70. isApplicable: o => {
  71. return o.data.length > 1;
  72. },
  73. params: CommonParams,
  74. async apply(trajectory, params, plugin) {
  75. const tr = StateObjectRef.resolveAndCheck(plugin.state.data, trajectory)?.obj?.data;
  76. if (!tr) return { };
  77. const builder = plugin.builders.structure;
  78. const models = [], structures = [];
  79. for (let i = 0; i < tr.length; i++) {
  80. const model = await builder.createModel(trajectory, { modelIndex: i });
  81. const modelProperties = await builder.insertModelProperties(model, params.modelProperties, { isCollapsed: true });
  82. const structure = await builder.createStructure(modelProperties || model, { name: 'model', params: {} });
  83. const structureProperties = await builder.insertStructureProperties(structure, params.structureProperties);
  84. models.push(model);
  85. structures.push(structure);
  86. const quality = structure.obj ? getStructureQuality(structure.obj.data, { elementCountFactor: tr.length }) : 'medium';
  87. await builder.representation.applyPreset(structureProperties, params.representationPreset || 'auto', { globalThemeName: 'model-index', quality });
  88. }
  89. return { models, structures };
  90. }
  91. });
  92. const CrystalSymmetryParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
  93. model: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.ModelFromTrajectory, a, plugin))),
  94. ...CommonParams(a, plugin)
  95. });
  96. async function applyCrystalSymmetry(props: { ijkMin: Vec3, ijkMax: Vec3, theme?: string }, trajectory: StateObjectRef<PluginStateObject.Molecule.Trajectory>, params: PD.ValuesFor<ReturnType<typeof CrystalSymmetryParams>>, plugin: PluginContext) {
  97. const builder = plugin.builders.structure;
  98. const model = await builder.createModel(trajectory, params.model);
  99. const modelProperties = await builder.insertModelProperties(model, params.modelProperties);
  100. const structure = await builder.createStructure(modelProperties || model, {
  101. name: 'symmetry',
  102. params: props
  103. });
  104. const structureProperties = await builder.insertStructureProperties(structure, params.structureProperties);
  105. const unitcell = await builder.tryCreateUnitcell(modelProperties, undefined, { isHidden: false });
  106. const representation = await plugin.builders.structure.representation.applyPreset(structureProperties, params.representationPreset || 'auto', { globalThemeName: props.theme });
  107. return {
  108. model,
  109. modelProperties,
  110. unitcell,
  111. structure,
  112. structureProperties,
  113. representation
  114. };
  115. }
  116. const unitcell = TrajectoryHierarchyPresetProvider({
  117. id: 'preset-trajectory-unitcell',
  118. display: {
  119. name: 'Unit Cell', group: 'Preset',
  120. description: 'Shows the fully populated unit cell.'
  121. },
  122. isApplicable: o => {
  123. return Model.hasCrystalSymmetry(o.data[0]);
  124. },
  125. params: CrystalSymmetryParams,
  126. async apply(trajectory, params, plugin) {
  127. return await applyCrystalSymmetry({ ijkMin: Vec3.create(0, 0, 0), ijkMax: Vec3.create(0, 0, 0) }, trajectory, params, plugin);
  128. }
  129. });
  130. const supercell = TrajectoryHierarchyPresetProvider({
  131. id: 'preset-trajectory-supercell',
  132. display: {
  133. name: 'Super Cell', group: 'Preset',
  134. description: 'Shows the super cell, i.e. the central unit cell and all adjacent unit cells.'
  135. },
  136. isApplicable: o => {
  137. return Model.hasCrystalSymmetry(o.data[0]);
  138. },
  139. params: CrystalSymmetryParams,
  140. async apply(trajectory, params, plugin) {
  141. return await applyCrystalSymmetry({ ijkMin: Vec3.create(-1, -1, -1), ijkMax: Vec3.create(1, 1, 1), theme: 'operator-hkl' }, trajectory, params, plugin);
  142. }
  143. });
  144. export const PresetTrajectoryHierarchy = {
  145. 'default': defaultPreset,
  146. 'all-models': allModels,
  147. unitcell,
  148. supercell,
  149. };
  150. export type PresetTrajectoryHierarchy = typeof PresetTrajectoryHierarchy;