flexible-structure.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import { PluginStateTransform, PluginStateObject as SO } from 'molstar/lib/mol-plugin-state/objects';
  2. import { RootStructureDefinition } from 'molstar/lib/mol-plugin-state/helpers/root-structure';
  3. import { PluginContext } from 'molstar/lib/mol-plugin/context';
  4. import { Task } from 'molstar/lib/mol-task';
  5. import { ParamDefinition as PD } from 'molstar/lib/mol-util/param-definition';
  6. import { PropsetProps, selectionTest, toRange } from '../preset';
  7. import { StructureQueryHelper } from 'molstar/lib/mol-plugin-state/helpers/structure-query';
  8. import { MolScriptBuilder as MS } from 'molstar/lib/mol-script/language/builder';
  9. import { StructureSelection, Structure } from 'molstar/lib/mol-model/structure';
  10. export { FlexibleStructureFromModel as FlexibleStructureFromModel };
  11. type FlexibleStructureFromModel = typeof FlexibleStructureFromModel
  12. const FlexibleStructureFromModel = PluginStateTransform.BuiltIn({
  13. name: 'flexible-structure-from-model',
  14. display: { name: 'Flexible Structure', description: 'Create a molecular structure from independently transformed substructures.' },
  15. from: SO.Molecule.Model,
  16. to: SO.Molecule.Structure,
  17. isDecorator: true,
  18. params(a) {
  19. return {
  20. selection: PD.Value<PropsetProps['selection']>([])
  21. };
  22. }
  23. })({
  24. apply({ a, params }, plugin: PluginContext) {
  25. return Task.create('Build Flexible Structure', async ctx => {
  26. const base = await RootStructureDefinition.create(plugin, ctx, a.data);
  27. const { selection } = params;
  28. if (!selection?.length) return base;
  29. const blocks: Structure[] = []
  30. for (const p of selection) {
  31. const residues: number[] = (p.beg && p.end) ? toRange(p.beg, p.end) : [];
  32. const test = selectionTest(p.asymId, residues);
  33. const expression = MS.struct.generator.atomGroups(test);
  34. const { selection: sele } = StructureQueryHelper.createAndRun(base.data, expression);
  35. const s = StructureSelection.unionStructure(sele);
  36. if (!p.matrix) {
  37. blocks.push(s);
  38. } else {
  39. const ts = Structure.transform(s, p.matrix);
  40. blocks.push(ts);
  41. }
  42. }
  43. const builder = Structure.Builder({ parent: base.data });
  44. for (const b of blocks) {
  45. for (const u of b.units) {
  46. builder.addUnit(u.kind, u.model, u.conformation.operator, u.elements, u.traits, u.invariantId);
  47. }
  48. }
  49. const blockStructure = builder.getStructure();
  50. return new SO.Molecule.Structure(blockStructure, { label: base.data.label })
  51. });
  52. },
  53. dispose({ b }) {
  54. b?.data.customPropertyDescriptors.dispose();
  55. }
  56. });