UNPKG

@rcsb/rcsb-saguaro-3d

Version:
198 lines 10.6 kB
import { StructureElement, StructureProperties as SP, StructureSelection, Unit } from "molstar/lib/mol-model/structure"; import { OrderedSet } from "molstar/lib/mol-data/int"; import { MolScriptBuilder as MS } from "molstar/lib/mol-script/language/builder"; import { Script } from "molstar/lib/mol-script/script"; export class MolstarCallbackManager { constructor(config) { this.viewer = config.viewer; this.stateManager = config.stateManager; this.loadingFlag = config.loadingFlag; this.modelMapManager = config.modelMapManager; this.innerSelectionFlag = config.innerSelectionFlag; this.innerReprChangeFlag = config.innerReprChangeFlag; } subscribeRepresentationChange() { this.reprChangeSubs = this.viewer.plugin.state.data.events.cell.stateUpdated.subscribe((s) => { var _a, _b, _c; if (this.innerReprChangeFlag.get()) return; if ((_b = (_a = s.cell.obj) === null || _a === void 0 ? void 0 : _a.tags) === null || _b === void 0 ? void 0 : _b.find(t => t.indexOf('structure-component-') === 0)) this.stateManager.next({ type: "representation-change", view: "3d-view", data: { label: (_c = s.cell.obj) === null || _c === void 0 ? void 0 : _c.label, isHidden: !!s.cell.state.isHidden } }); }); return this.reprChangeSubs; } subscribeHover() { this.hoverSubs = this.viewer.plugin.behaviors.interaction.hover.subscribe((r) => { var _a, _b; const sequenceData = new Array(); const loci = r.current.loci; if (StructureElement.Loci.is(loci)) { const loc = StructureElement.Location.create(loci.structure); for (const e of loci.elements) { const modelId = (_b = (_a = e.unit) === null || _a === void 0 ? void 0 : _a.model) === null || _b === void 0 ? void 0 : _b.id; const seqIds = new Set(); loc.unit = e.unit; for (let i = 0, il = OrderedSet.size(e.indices); i < il; ++i) { loc.element = e.unit.elements[OrderedSet.getAt(e.indices, i)]; if (Unit.isAtomic(loc.unit)) seqIds.add(SP.residue.label_seq_id(loc)); else for (let n = SP.coarse.seq_id_begin(loc); n <= SP.coarse.seq_id_end(loc); n++) { seqIds.add(n); } } sequenceData.push({ modelId: this.modelMapManager.getModelId(modelId), labelAsymId: SP.chain.label_asym_id(loc), operatorName: SP.unit.operator_name(loc), seqIds }); } } this.stateManager.selectionState.setSelectionFromResidueSelection(sequenceData, 'hover', 'structure'); this.stateManager.next({ type: "hover-change", view: "3d-view" }); }); return this.hoverSubs; } subscribeSelection() { this.addSubs = this.viewer.plugin.managers.structure.selection.events.loci.add.subscribe((currentLoci) => { if (this.innerSelectionFlag.get()) return; const loc = createLocation(currentLoci); const currentModelId = this.modelMapManager.getModelId(currentLoci.structure.model.id); if (SP.entity.type(loc) === 'non-polymer') { const resAuthId = SP.residue.auth_seq_id(loc); const chainLabelId = SP.chain.label_asym_id(loc); const surrCore = MS.struct.generator.atomGroups({ 'residue-test': MS.core.rel.eq([MS.ammp('auth_seq_id'), resAuthId]), 'chain-test': MS.core.rel.eq([MS.ammp('label_asym_id'), chainLabelId]), 'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'non-polymer']), }); const surrExp = MS.struct.modifier.includeSurroundings({ 0: surrCore, radius: 5, "as-whole-residues": true }); const polymerExp = MS.struct.generator.atomGroups({ 'residue-test': MS.core.rel.eq([MS.ammp('entityType'), 'non-polymer']) }); const sel = Script.getStructureSelection(Q => Q.struct.modifier.exceptBy({ 0: surrExp, by: polymerExp }), currentLoci.structure); this.innerSelectionFlag.set(true); const surroundingsLoci = StructureSelection.toLociWithSourceUnits(sel); this.viewer.plugin.managers.structure.selection.fromLoci('add', StructureSelection.toLociWithSourceUnits(sel)); const surroundingsLoc = StructureElement.Location.create(surroundingsLoci.structure); let currentSelLength = 0; for (const e of surroundingsLoci.elements) { StructureElement.Location.set(surroundingsLoc, surroundingsLoci.structure, e.unit, e.unit.elements[0]); if (SP.entity.type(surroundingsLoc) === 'polymer' && ((typeof e.indices !== "object" && currentSelLength == 0) || e.indices.length >= currentSelLength)) { currentSelLength = typeof e.indices !== "object" ? 0 : e.indices.length; this.stateManager.selectionState.setLastSelection({ modelId: currentModelId, labelAsymId: SP.chain.label_asym_id(surroundingsLoc), source: "structure", regions: [] }); } } this.innerSelectionFlag.set(false); } else if (SP.entity.type(loc) === 'polymer') { const labelAsymId = SP.chain.label_asym_id(loc); const operatorName = SP.unit.operator_name(loc); this.stateManager.selectionState.setLastSelection({ modelId: currentModelId, labelAsymId: labelAsymId, operatorName: operatorName, source: "structure", regions: [] }); } else { this.stateManager.selectionState.setLastSelection(null); } this.updateStateManager(); }); this.removeSubs = this.viewer.plugin.managers.structure.selection.events.loci.remove.subscribe(() => { if (this.innerSelectionFlag.get()) return; this.updateStateManager(); }); this.viewer.plugin.managers.structure.selection.events.loci.clear.subscribe(() => { if (this.innerSelectionFlag.get()) return; this.updateStateManager(); }); return this.addSubs; } pluginCall(f) { this.viewer.pluginCall(f); } subscribeModelChange() { this.modelChangeSubs = this.viewer.plugin.state.behaviors.events.object.updated.subscribe(o => { if (this.loadingFlag.get()) return; this.modelChange(); }); return this.modelChangeSubs; } modelChange() { this.stateManager.assemblyModelSate.setMap(this.modelMapManager.getChains()); this.stateManager.next({ type: "model-change", view: "3d-view" }); } unsubscribe() { var _a, _b, _c, _d, _e; (_a = this.addSubs) === null || _a === void 0 ? void 0 : _a.unsubscribe(); (_b = this.removeSubs) === null || _b === void 0 ? void 0 : _b.unsubscribe(); (_c = this.clearSubs) === null || _c === void 0 ? void 0 : _c.unsubscribe(); (_d = this.modelChangeSubs) === null || _d === void 0 ? void 0 : _d.unsubscribe(); (_e = this.hoverSubs) === null || _e === void 0 ? void 0 : _e.unsubscribe(); } updateStateManager() { var _a; const sequenceData = new Array(); for (const structure of this.viewer.plugin.managers.structure.hierarchy.current.structures) { const data = (_a = structure.cell.obj) === null || _a === void 0 ? void 0 : _a.data; if (data == null) return; const loci = this.viewer.plugin.managers.structure.selection.getLoci(data); if (StructureElement.Loci.is(loci)) { const loc = StructureElement.Location.create(loci.structure); for (const e of loci.elements) { StructureElement.Location.set(loc, loci.structure, e.unit, e.unit.elements[0]); if (SP.entity.type(loc) === 'polymer') { const seqIds = new Set(); for (let i = 0, il = OrderedSet.size(e.indices); i < il; ++i) { loc.element = e.unit.elements[OrderedSet.getAt(e.indices, i)]; if (Unit.isAtomic(loc.unit)) seqIds.add(SP.residue.label_seq_id(loc)); else for (let n = SP.coarse.seq_id_begin(loc); n <= SP.coarse.seq_id_end(loc); n++) { seqIds.add(n); } } if (seqIds.size > 0) sequenceData.push({ modelId: this.modelMapManager.getModelId(data.model.id), labelAsymId: SP.chain.label_asym_id(loc), operatorName: SP.unit.operator_name(loc), seqIds }); } } } } this.stateManager.selectionState.setSelectionFromResidueSelection(sequenceData, 'select', 'structure'); if (sequenceData.length == 0) this.stateManager.selectionState.setLastSelection(null); this.stateManager.next({ type: "selection-change", view: "3d-view" }); } } function createLocation(loci) { const loc = StructureElement.Location.create(loci.structure); StructureElement.Location.set(loc, loci.structure, loci.elements[0].unit, loci.elements[0].unit.elements[OrderedSet.getAt(loci.elements[0].indices, 0)]); return loc; } //# sourceMappingURL=MolstarCallbackManager.js.map