viewer.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /**
  2. * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Joan Segura <joan.segura@rcsb.org>
  5. */
  6. import { StructureRef } from 'molstar/lib/mol-plugin-state/manager/structure/hierarchy-state';
  7. import { Structure } from 'molstar/lib/mol-model/structure/structure';
  8. import { PluginContext } from 'molstar/lib/mol-plugin/context';
  9. import { MolScriptBuilder as MS } from 'molstar/lib/mol-script/language/builder';
  10. import { StructureRepresentationRegistry } from 'molstar/lib/mol-repr/structure/registry';
  11. import { StructureSelectionQuery } from 'molstar/lib/mol-plugin-state/helpers/structure-selection-query';
  12. import {
  13. rangeToTest, SelectBase,
  14. SelectRange,
  15. SelectTarget,
  16. Target,
  17. targetToLoci,
  18. toRange
  19. } from './selection';
  20. export function setFocusFromRange(plugin: PluginContext, target: SelectRange) {
  21. const data = getStructureWithModelId(plugin.managers.structure.hierarchy.current.structures, target);
  22. if (!data) return;
  23. const loci = targetToLoci(target, data);
  24. if (!loci) return;
  25. plugin.managers.structure.focus.setFromLoci(loci);
  26. }
  27. function getStructureWithModelId(structures: StructureRef[], target: { modelId: string }): Structure | undefined {
  28. const structureRef = getStructureRefWithModelId(structures, target);
  29. if (structureRef) return structureRef.cell?.obj?.data;
  30. }
  31. export function getStructureRefWithModelId(structures: StructureRef[], target: { modelId: string }): StructureRef | undefined {
  32. for (const structure of structures) {
  33. if (!structure.cell?.obj?.data?.units) continue;
  34. const unit = structure.cell.obj.data.units[0];
  35. if (unit.model.id === target.modelId) return structure;
  36. }
  37. }
  38. export function select(plugin: PluginContext, targets: SelectTarget | SelectTarget[], mode: 'select' | 'hover', modifier: 'add' | 'set') {
  39. (Array.isArray(targets) ? targets : [targets]).forEach((target, n)=>{
  40. const data = getStructureWithModelId(plugin.managers.structure.hierarchy.current.structures, target);
  41. if (!data) return;
  42. const loci = targetToLoci(target, data);
  43. if (!loci) return;
  44. if (mode === 'hover') {
  45. plugin.managers.interactivity.lociHighlights.highlight({ loci });
  46. } else if (mode === 'select') {
  47. plugin.managers.structure.selection.fromLoci(n > 0 ? 'add' : modifier, loci);
  48. }
  49. });
  50. }
  51. export function clearSelection(plugin: PluginContext, mode: 'select' | 'hover', target?: { modelId: string; } & Target) {
  52. if (mode === 'hover') {
  53. plugin.managers.interactivity.lociHighlights.clearHighlights();
  54. return;
  55. }
  56. if (!target) {
  57. plugin.managers.interactivity.lociSelects.deselectAll();
  58. return;
  59. }
  60. const data = getStructureWithModelId(plugin.managers.structure.hierarchy.current.structures, target);
  61. if (!data) return;
  62. const loci = targetToLoci(target, data);
  63. plugin.managers.interactivity.lociSelects.deselect({ loci });
  64. }
  65. export async function createComponent(plugin: PluginContext, componentLabel: string, targets: SelectBase | SelectTarget | SelectTarget[], representationType: StructureRepresentationRegistry.BuiltIn) {
  66. for (const target of (Array.isArray(targets) ? targets : [targets])) {
  67. const structureRef = getStructureRefWithModelId(plugin.managers.structure.hierarchy.current.structures, target);
  68. if (!structureRef) throw Error('createComponent error: model not found');
  69. const residues = toResidues(target);
  70. const sel = StructureSelectionQuery('innerQuery_' + Math.random().toString(36).substr(2),
  71. MS.struct.generator.atomGroups(rangeToTest(target.labelAsymId, residues)));
  72. await plugin.managers.structure.component.add({
  73. selection: sel,
  74. options: { checkExisting: false, label: componentLabel },
  75. representation: representationType,
  76. }, [structureRef]);
  77. }
  78. }
  79. function toResidues(target: SelectBase | SelectTarget): number[] {
  80. if ('labelSeqRange' in target) {
  81. return toRange(target.labelSeqRange.beg, target.labelSeqRange.end);
  82. }
  83. if ('labelSeqId' in target) {
  84. return [target.labelSeqId];
  85. }
  86. return [];
  87. }
  88. export function removeComponent(plugin: PluginContext, componentLabel: string) {
  89. plugin.managers.structure.hierarchy.currentComponentGroups.forEach(c => {
  90. for (const comp of c) {
  91. if (comp.cell.obj?.label === componentLabel) {
  92. plugin.managers.structure.hierarchy.remove(c);
  93. break;
  94. }
  95. }
  96. });
  97. }