hierarchy-preset.ts 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. export interface TrajectoryHierarchyPresetProvider<P = any, S = {}> extends PresetProvider<PluginStateObject.Molecule.Trajectory, P, S> { }
  18. export function TrajectoryHierarchyPresetProvider<P, S>(preset: TrajectoryHierarchyPresetProvider<P, S>) { return preset; }
  19. export namespace TrajectoryHierarchyPresetProvider {
  20. export type Params<P extends TrajectoryHierarchyPresetProvider> = P extends TrajectoryHierarchyPresetProvider<infer T> ? T : never;
  21. export type State<P extends TrajectoryHierarchyPresetProvider> = P extends TrajectoryHierarchyPresetProvider<infer _, infer S> ? S : never;
  22. export const CommonParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
  23. modelProperties: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.CustomModelProperties, void 0, plugin))),
  24. structureProperties: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.CustomStructureProperties, void 0, plugin))),
  25. representationPreset: PD.Optional(PD.Text<keyof PresetStructureRepresentations>('auto' as const)),
  26. })
  27. }
  28. const CommonParams = TrajectoryHierarchyPresetProvider.CommonParams
  29. const FirstModelParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
  30. model: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.ModelFromTrajectory, a, plugin))),
  31. showUnitcell: PD.Optional(PD.Boolean(false)),
  32. structure: PD.Optional(RootStructureDefinition.getParams(void 0, 'assembly').type),
  33. ...CommonParams(a, plugin)
  34. });
  35. const firstModel = TrajectoryHierarchyPresetProvider({
  36. id: 'preset-trajectory-first-model',
  37. display: { name: 'First Model', group: 'Preset' },
  38. isApplicable: o => {
  39. return true
  40. },
  41. params: FirstModelParams,
  42. async apply(trajectory, params, plugin) {
  43. const builder = plugin.builders.structure;
  44. const model = await builder.createModel(trajectory, params.model);
  45. const modelProperties = await builder.insertModelProperties(model, params.modelProperties);
  46. const structure = await builder.createStructure(modelProperties || model, params.structure);
  47. const structureProperties = await builder.insertStructureProperties(structure, params.structureProperties);
  48. const unitcell = params.showUnitcell === void 0 || !!params.showUnitcell ? await builder.tryCreateUnitcell(modelProperties, undefined, { isHidden: true }) : void 0;
  49. const representation = await plugin.builders.structure.representation.applyPreset(structureProperties, params.representationPreset || 'auto');
  50. return {
  51. model,
  52. modelProperties,
  53. unitcell,
  54. structure,
  55. structureProperties,
  56. representation
  57. };
  58. }
  59. });
  60. const allModels = TrajectoryHierarchyPresetProvider({
  61. id: 'preset-trajectory-all-models',
  62. display: { name: 'All Models', group: 'Preset' },
  63. isApplicable: o => {
  64. return o.data.length > 1
  65. },
  66. params: CommonParams,
  67. async apply(trajectory, params, plugin) {
  68. const tr = StateObjectRef.resolveAndCheck(plugin.state.data, trajectory)?.obj?.data;
  69. if (!tr) return { };
  70. const builder = plugin.builders.structure;
  71. const models = [], structures = [];
  72. for (let i = 0; i < tr.length; i++) {
  73. const model = await builder.createModel(trajectory, { modelIndex: i }, { isCollapsed: true });
  74. const modelProperties = await builder.insertModelProperties(model, params.modelProperties);
  75. const structure = await builder.createStructure(modelProperties || model, { name: 'deposited', params: {} });
  76. const structureProperties = await builder.insertStructureProperties(structure, params.structureProperties);
  77. models.push(model);
  78. structures.push(structure);
  79. await builder.representation.applyPreset(structureProperties, params.representationPreset || 'auto', { globalThemeName: 'model-index', quality: 'medium' });
  80. }
  81. return { models, structures };
  82. }
  83. });
  84. const CrystalSymmetryParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
  85. model: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.ModelFromTrajectory, a, plugin))),
  86. ...CommonParams(a, plugin)
  87. });
  88. async function applyCrystalSymmetry(ijk: { ijkMin: Vec3, ijkMax: Vec3 }, trajectory: StateObjectRef<PluginStateObject.Molecule.Trajectory>, params: PD.ValuesFor<ReturnType<typeof CrystalSymmetryParams>>, plugin: PluginContext) {
  89. const builder = plugin.builders.structure;
  90. const model = await builder.createModel(trajectory, params.model);
  91. const modelProperties = await builder.insertModelProperties(model, params.modelProperties);
  92. const structure = await builder.createStructure(modelProperties || model, {
  93. name: 'symmetry',
  94. params: ijk
  95. });
  96. const structureProperties = await builder.insertStructureProperties(structure, params.structureProperties);
  97. const unitcell = await builder.tryCreateUnitcell(modelProperties, undefined, { isHidden: false });
  98. const representation = await plugin.builders.structure.representation.applyPreset(structureProperties, params.representationPreset || 'auto');
  99. return {
  100. model,
  101. modelProperties,
  102. unitcell,
  103. structure,
  104. structureProperties,
  105. representation
  106. };
  107. }
  108. const unitcell = TrajectoryHierarchyPresetProvider({
  109. id: 'preset-trajectory-unitcell',
  110. display: { name: 'Unitcell', group: 'Preset' },
  111. isApplicable: o => {
  112. return Model.hasCrystalSymmetry(o.data[0])
  113. },
  114. params: CrystalSymmetryParams,
  115. async apply(trajectory, params, plugin) {
  116. return await applyCrystalSymmetry({ ijkMin: Vec3.create(0, 0, 0), ijkMax: Vec3.create(0, 0, 0) }, trajectory, params, plugin);
  117. }
  118. });
  119. const supercell = TrajectoryHierarchyPresetProvider({
  120. id: 'preset-trajectory-supercell',
  121. display: { name: 'Supercell', group: 'Preset' },
  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(-1, -1, -1), ijkMax: Vec3.create(1, 1, 1) }, trajectory, params, plugin);
  128. }
  129. });
  130. export const PresetTrajectoryHierarchy = {
  131. 'first-model': firstModel,
  132. 'all-models': allModels,
  133. unitcell,
  134. supercell,
  135. };
  136. export type PresetTrajectoryHierarchy = typeof PresetTrajectoryHierarchy;