hierarchy-preset.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /**
  2. * Copyright (c) 2020-2021 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, StructureRepresentationPresetProvider } 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. import { OperatorNameColorThemeProvider } from '../../../mol-theme/color/operator-name';
  19. import { PluginConfig } from '../../../mol-plugin/config';
  20. export interface TrajectoryHierarchyPresetProvider<P = any, S = {}> extends PresetProvider<PluginStateObject.Molecule.Trajectory, P, S> { }
  21. export function TrajectoryHierarchyPresetProvider<P, S>(preset: TrajectoryHierarchyPresetProvider<P, S>) { return preset; }
  22. export namespace TrajectoryHierarchyPresetProvider {
  23. export type Params<P extends TrajectoryHierarchyPresetProvider> = P extends TrajectoryHierarchyPresetProvider<infer T> ? T : never;
  24. export type State<P extends TrajectoryHierarchyPresetProvider> = P extends TrajectoryHierarchyPresetProvider<infer _, infer S> ? S : never;
  25. export const CommonParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
  26. modelProperties: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.CustomModelProperties, void 0, plugin))),
  27. structureProperties: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.CustomStructureProperties, void 0, plugin))),
  28. representationPreset: PD.Optional(PD.Text<keyof PresetStructureRepresentations>('auto' as const))
  29. });
  30. }
  31. const CommonParams = TrajectoryHierarchyPresetProvider.CommonParams;
  32. const DefaultParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
  33. model: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.ModelFromTrajectory, a, plugin))),
  34. showUnitcell: PD.Optional(PD.Boolean(false)),
  35. structure: PD.Optional(RootStructureDefinition.getParams(void 0, 'assembly').type),
  36. representationPresetParams: PD.Optional(PD.Group(StructureRepresentationPresetProvider.CommonParams)),
  37. ...CommonParams(a, plugin)
  38. });
  39. const defaultPreset = TrajectoryHierarchyPresetProvider({
  40. id: 'preset-trajectory-default',
  41. display: {
  42. name: 'Default (Assembly)', group: 'Preset',
  43. description: 'Shows the first assembly or, if that is unavailable, the first model.'
  44. },
  45. isApplicable: o => {
  46. return true;
  47. },
  48. params: DefaultParams,
  49. async apply(trajectory, params, plugin) {
  50. const builder = plugin.builders.structure;
  51. const model = await builder.createModel(trajectory, params.model);
  52. const modelProperties = await builder.insertModelProperties(model, params.modelProperties);
  53. const structure = await builder.createStructure(modelProperties || model, params.structure);
  54. const structureProperties = await builder.insertStructureProperties(structure, params.structureProperties);
  55. const unitcell = params.showUnitcell === void 0 || !!params.showUnitcell ? await builder.tryCreateUnitcell(modelProperties, undefined, { isHidden: true }) : void 0;
  56. const representationPreset = params.representationPreset || plugin.config.get(PluginConfig.Structure.DefaultRepresentationPreset) || PresetStructureRepresentations.auto.id;
  57. const representation = await plugin.builders.structure.representation.applyPreset(structureProperties, representationPreset, params.representationPresetParams);
  58. return {
  59. model,
  60. modelProperties,
  61. unitcell,
  62. structure,
  63. structureProperties,
  64. representation
  65. };
  66. }
  67. });
  68. const AllModelsParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
  69. useDefaultIfSingleModel: PD.Optional(PD.Boolean(false)),
  70. representationPresetParams: PD.Optional(PD.Group(StructureRepresentationPresetProvider.CommonParams)),
  71. ...CommonParams(a, plugin)
  72. });
  73. const allModels = TrajectoryHierarchyPresetProvider({
  74. id: 'preset-trajectory-all-models',
  75. display: {
  76. name: 'All Models', group: 'Preset',
  77. description: 'Shows all models; colored by trajectory-index.'
  78. },
  79. isApplicable: o => {
  80. return o.data.frameCount > 1;
  81. },
  82. params: AllModelsParams,
  83. async apply(trajectory, params, plugin) {
  84. const tr = StateObjectRef.resolveAndCheck(plugin.state.data, trajectory)?.obj?.data;
  85. if (!tr) return { };
  86. if (tr.frameCount === 1 && params.useDefaultIfSingleModel) {
  87. return defaultPreset.apply(trajectory, params as any, plugin);
  88. }
  89. const builder = plugin.builders.structure;
  90. const models = [], structures = [];
  91. for (let i = 0; i < tr.frameCount; i++) {
  92. const model = await builder.createModel(trajectory, { modelIndex: i });
  93. const modelProperties = await builder.insertModelProperties(model, params.modelProperties, { isCollapsed: true });
  94. const structure = await builder.createStructure(modelProperties || model, { name: 'model', params: {} });
  95. const structureProperties = await builder.insertStructureProperties(structure, params.structureProperties);
  96. models.push(model);
  97. structures.push(structure);
  98. const quality = structure.obj ? getStructureQuality(structure.obj.data, { elementCountFactor: tr.frameCount }) : 'medium';
  99. const representationPreset = params.representationPreset || plugin.config.get(PluginConfig.Structure.DefaultRepresentationPreset) || PresetStructureRepresentations.auto.id;
  100. await builder.representation.applyPreset(structureProperties, representationPreset, { theme: { globalName: 'trajectory-index' }, quality });
  101. }
  102. return { models, structures };
  103. }
  104. });
  105. const CrystalSymmetryParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
  106. model: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.ModelFromTrajectory, a, plugin))),
  107. ...CommonParams(a, plugin)
  108. });
  109. async function applyCrystalSymmetry(props: { ijkMin: Vec3, ijkMax: Vec3, theme?: string }, trajectory: StateObjectRef<PluginStateObject.Molecule.Trajectory>, params: PD.ValuesFor<ReturnType<typeof CrystalSymmetryParams>>, plugin: PluginContext) {
  110. const builder = plugin.builders.structure;
  111. const model = await builder.createModel(trajectory, params.model);
  112. const modelProperties = await builder.insertModelProperties(model, params.modelProperties);
  113. const structure = await builder.createStructure(modelProperties || model, {
  114. name: 'symmetry',
  115. params: props
  116. });
  117. const structureProperties = await builder.insertStructureProperties(structure, params.structureProperties);
  118. const unitcell = await builder.tryCreateUnitcell(modelProperties, undefined, { isHidden: false });
  119. const representationPreset = params.representationPreset || plugin.config.get(PluginConfig.Structure.DefaultRepresentationPreset) || PresetStructureRepresentations.auto.id;
  120. const representation = await plugin.builders.structure.representation.applyPreset(structureProperties, representationPreset, { theme: { globalName: props.theme } });
  121. return {
  122. model,
  123. modelProperties,
  124. unitcell,
  125. structure,
  126. structureProperties,
  127. representation
  128. };
  129. }
  130. const unitcell = TrajectoryHierarchyPresetProvider({
  131. id: 'preset-trajectory-unitcell',
  132. display: {
  133. name: 'Unit Cell', group: 'Preset',
  134. description: 'Shows the fully populated unit cell.'
  135. },
  136. isApplicable: o => {
  137. return Model.hasCrystalSymmetry(o.data.representative);
  138. },
  139. params: CrystalSymmetryParams,
  140. async apply(trajectory, params, plugin) {
  141. return await applyCrystalSymmetry({ ijkMin: Vec3.create(0, 0, 0), ijkMax: Vec3.create(0, 0, 0) }, trajectory, params, plugin);
  142. }
  143. });
  144. const supercell = TrajectoryHierarchyPresetProvider({
  145. id: 'preset-trajectory-supercell',
  146. display: {
  147. name: 'Super Cell', group: 'Preset',
  148. description: 'Shows the super cell, i.e. the central unit cell and all adjacent unit cells.'
  149. },
  150. isApplicable: o => {
  151. return Model.hasCrystalSymmetry(o.data.representative);
  152. },
  153. params: CrystalSymmetryParams,
  154. async apply(trajectory, params, plugin) {
  155. return await applyCrystalSymmetry({ ijkMin: Vec3.create(-1, -1, -1), ijkMax: Vec3.create(1, 1, 1), theme: 'operator-hkl' }, trajectory, params, plugin);
  156. }
  157. });
  158. const CrystalContactsParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
  159. model: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.ModelFromTrajectory, a, plugin))),
  160. ...CommonParams(a, plugin)
  161. });
  162. const crystalContacts = TrajectoryHierarchyPresetProvider({
  163. id: 'preset-trajectory-crystal-contacts',
  164. display: {
  165. name: 'Crystal Contacts', group: 'Preset',
  166. description: 'Showsasymetric unit and chains from neighbours within 5 \u212B, i.e., symmetry mates.'
  167. },
  168. isApplicable: o => {
  169. return Model.hasCrystalSymmetry(o.data.representative);
  170. },
  171. params: CrystalContactsParams,
  172. async apply(trajectory, params, plugin) {
  173. const builder = plugin.builders.structure;
  174. const model = await builder.createModel(trajectory, params.model);
  175. const modelProperties = await builder.insertModelProperties(model, params.modelProperties);
  176. const structure = await builder.createStructure(modelProperties || model, {
  177. name: 'symmetry-mates',
  178. params: { radius: 5 }
  179. });
  180. const structureProperties = await builder.insertStructureProperties(structure, params.structureProperties);
  181. const unitcell = await builder.tryCreateUnitcell(modelProperties, undefined, { isHidden: true });
  182. const representationPreset = params.representationPreset || plugin.config.get(PluginConfig.Structure.DefaultRepresentationPreset) || PresetStructureRepresentations.auto.id;
  183. const representation = await plugin.builders.structure.representation.applyPreset(structureProperties, representationPreset, { theme: { globalName: 'operator-name', carbonColor: 'operator-name', focus: { name: 'element-symbol', params: { carbonColor: { name: 'operator-name', params: OperatorNameColorThemeProvider.defaultValues } } } } });
  184. return {
  185. model,
  186. modelProperties,
  187. unitcell,
  188. structure,
  189. structureProperties,
  190. representation
  191. };
  192. }
  193. });
  194. export const PresetTrajectoryHierarchy = {
  195. 'default': defaultPreset,
  196. 'all-models': allModels,
  197. unitcell,
  198. supercell,
  199. crystalContacts,
  200. };
  201. export type PresetTrajectoryHierarchy = typeof PresetTrajectoryHierarchy;