@rcsb/rcsb-saguaro-3d
Version:
RCSB Molstar/Saguaro Web App
198 lines • 10.6 kB
JavaScript
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