pdbe-molstar-3dbionotes
Version:
Molstar implementation for PDBe
795 lines • 46.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SegmentTree = void 0;
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
var operators_1 = require("rxjs/operators");
var commands_1 = require("Molstar/mol-plugin/commands");
var mol_state_1 = require("Molstar/mol-state");
var base_1 = require("Molstar/mol-plugin-ui/base");
var common_1 = require("Molstar/mol-plugin-ui/controls/common");
var param_definition_1 = require("Molstar/mol-util/param-definition");
var parameters_1 = require("Molstar/mol-plugin-ui/controls/parameters");
var mol_state_2 = require("Molstar/mol-state");
var superposition_1 = require("../superposition");
var update_transform_1 = require("Molstar/mol-plugin-ui/state/update-transform");
var icons_1 = require("Molstar/mol-plugin-ui/controls/icons");
var lists_1 = require("Molstar/mol-util/color/lists");
var color_1 = require("Molstar/mol-util/color");
var builder_1 = require("Molstar/mol-script/language/builder");
var rxjs_1 = require("rxjs");
var SegmentTree = /** @class */ (function (_super) {
tslib_1.__extends(SegmentTree, _super);
function SegmentTree() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.getSegmentParams = function () {
var customState = _this.customState;
if (!customState.superpositionState || !customState.superpositionState.segmentData)
return;
var segmentData = customState.superpositionState.segmentData;
var segmentArr = segmentData.map(function (segment, i) {
var segmentLabel = i + 1 + " ( " + segment.segment_start + " - " + segment.segment_end + " )";
return [segmentLabel, segmentLabel];
});
var segmentOptions = {
segment: param_definition_1.ParamDefinition.Select('', segmentArr, { label: 'Select Segment', description: 'Select segment to view its clusters below' })
};
var segmentIndex = customState.superpositionState.activeSegment - 1;
_this.setState({ segment: {
params: segmentOptions,
value: { segment: segmentArr[segmentIndex][0] }
} });
_this.setState({ isBusy: false });
};
_this.updateSegment = function (val) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var customState, updatedParams;
var _this = this;
return tslib_1.__generator(this, function (_a) {
if (!this.state.segment)
return [2 /*return*/];
customState = this.customState;
customState.events.isBusy.next(true);
// Hide pervious segement structures
this.hideStructures(customState.superpositionState.activeSegment - 1);
updatedParams = tslib_1.__assign({}, this.state.segment);
updatedParams.value = val;
this.setState({ segment: updatedParams });
setTimeout(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var updatedSegmentIndex;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
updatedSegmentIndex = parseInt(val.segment.split(' ')[0]);
customState.superpositionState.activeSegment = updatedSegmentIndex;
// Display current segment visible structures
return [4 /*yield*/, this.displayStructures(customState.superpositionState.activeSegment - 1)];
case 1:
// Display current segment visible structures
_a.sent();
customState.events.isBusy.next(false);
this.plugin.customState.events.segmentUpdate.next(true);
return [2 /*return*/];
}
});
}); }, 100);
return [2 /*return*/, false];
});
}); };
_this.hideStructures = function (segmentIndex) {
// clear selections
_this.plugin.managers.interactivity.lociSelects.deselectAll();
// clear Focus
_this.plugin.managers.structure.focus.clear();
// remove measurements
var measurements = _this.plugin.managers.structure.measurement.state;
var measureTypes = ['labels', 'distances', 'angles', 'dihedrals'];
var measurementCell = void 0;
measureTypes.forEach(function (type) {
if (measurementCell)
return;
if (measurements[type][0]) {
measurementCell = _this.plugin.state.data.cells.get(measurements[type][0].transform.parent);
}
});
if (measurementCell) {
commands_1.PluginCommands.State.RemoveObject(_this.plugin, { state: measurementCell.parent, ref: measurementCell.transform.parent, removeParentGhosts: true });
}
// hide structures
var customState = _this.customState;
customState.superpositionState.visibleRefs[segmentIndex] = [];
for (var _i = 0, _a = customState.superpositionState.loadedStructs[segmentIndex]; _i < _a.length; _i++) {
var struct = _a[_i];
var structRef = _this.customState.superpositionState.models[struct];
if (structRef) {
var structHierarchy = _this.plugin.managers.structure.hierarchy.current.refs.get(structRef);
if (structHierarchy && structHierarchy.components) {
for (var _b = 0, _c = structHierarchy.components; _b < _c.length; _b++) {
var c = _c[_b];
if (c && c.cell && !c.cell.state.isHidden) {
customState.superpositionState.visibleRefs[segmentIndex].push(c.cell.transform.ref);
commands_1.PluginCommands.State.ToggleVisibility(_this.plugin, { state: c.cell.parent, ref: c.cell.transform.ref });
}
}
}
}
}
};
_this.displayStructures = function (segmentIndex) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var customState, loadStrs_1, _i, _a, ref, cell;
var _this = this;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
customState = this.customState;
if (!(customState.superpositionState.visibleRefs[segmentIndex].length === 0)) return [3 /*break*/, 3];
loadStrs_1 = [];
customState.superpositionState.segmentData[segmentIndex].clusters.forEach(function (cluster) {
var entryList = [cluster[0]];
if (customState.initParams.superpositionParams && customState.initParams.superpositionParams.superposeAll) {
entryList = cluster;
}
entryList.forEach(function (str) {
var structStateId = str.pdb_id + "_" + str.struct_asym_id;
var structRef = customState.superpositionState.models[structStateId];
if (structRef) {
var cell = _this.plugin.state.data.cells.get(structRef);
var isHidden = cell.state.isHidden ? true : false;
if (isHidden) {
commands_1.PluginCommands.State.ToggleVisibility(_this.plugin, { state: cell.parent, ref: structRef });
// PluginCommands.State.ToggleVisibility(this.plugin, { state: cell.parent!, ref: cell.transform.parent });
}
}
else {
loadStrs_1.push(str);
}
});
});
commands_1.PluginCommands.Camera.Reset(this.plugin);
if (!(loadStrs_1.length > 0)) return [3 /*break*/, 2];
return [4 /*yield*/, superposition_1.renderSuperposition(this.plugin, segmentIndex, loadStrs_1)];
case 1:
_b.sent();
_b.label = 2;
case 2: return [3 /*break*/, 4];
case 3:
for (_i = 0, _a = customState.superpositionState.visibleRefs[segmentIndex]; _i < _a.length; _i++) {
ref = _a[_i];
cell = this.plugin.state.data.cells.get(ref);
if (cell && cell.state.isHidden) {
commands_1.PluginCommands.State.ToggleVisibility(this.plugin, { state: cell.parent, ref: ref });
}
}
commands_1.PluginCommands.Camera.Reset(this.plugin);
_b.label = 4;
case 4: return [2 /*return*/];
}
});
}); };
return _this;
}
SegmentTree.prototype.componentDidMount = function () {
var _this = this;
this.subscribe(this.plugin.customState.events.superpositionInit, function () {
var customState = _this.customState;
if (customState && !customState.superpositionError) {
_this.getSegmentParams();
}
_this.forceUpdate();
});
this.subscribe(this.plugin.customState.events.isBusy, function (e) {
_this.setState({ isBusy: e });
if (e) {
commands_1.PluginCommands.Toast.Show(_this.plugin, {
title: 'Process',
message: 'Loading / computing large dataset!',
key: 'is-busy-toast'
});
}
else {
commands_1.PluginCommands.Toast.Hide(_this.plugin, { key: 'is-busy-toast' });
}
});
this.subscribe(this.plugin.behaviors.layout.leftPanelTabName, function (e) {
if (e !== 'segments')
return;
_this.getSegmentParams();
_this.forceUpdate();
});
};
Object.defineProperty(SegmentTree.prototype, "customState", {
get: function () {
return this.plugin.customState;
},
enumerable: false,
configurable: true
});
SegmentTree.prototype.render = function () {
var sectionHeader = React.createElement(common_1.SectionHeader, { title: "Structure clusters" });
var customState = this.customState;
if (customState && customState.initParams && !customState.initParams.superposition) {
return React.createElement(React.Fragment, null,
sectionHeader,
React.createElement("div", null, "Functionality unavailable!"));
}
else {
if (customState && customState.initParams && customState.initParams.superposition) {
sectionHeader = React.createElement(common_1.SectionHeader, { title: "Structure clusters - " + customState.initParams.moleculeId });
if (customState.superpositionError) {
return React.createElement(React.Fragment, null,
sectionHeader,
React.createElement("div", { style: { textAlign: 'center' } }, customState.superpositionError));
}
else if (!customState.superpositionState || !customState.superpositionState.segmentData) {
return React.createElement(React.Fragment, null,
sectionHeader,
React.createElement("div", { style: { textAlign: 'center' } }, "Loading Segment Data!"));
}
}
}
if (this.state) {
var segmentIndex_1 = parseInt(this.state.segment.value.segment.split(' ')[0]) - 1;
var segmentData_1 = customState.superpositionState.segmentData;
var fullSegmentRange = "( " + segmentData_1[0].segment_start + " - " + segmentData_1[segmentData_1.length - 1].segment_end + " )";
sectionHeader = React.createElement(common_1.SectionHeader, { title: "Structure clusters " + customState.initParams.moleculeId, desc: fullSegmentRange });
return React.createElement(React.Fragment, null,
sectionHeader,
React.createElement(parameters_1.ParameterControls, { params: this.state.segment.params, values: this.state.segment.value, onChangeValues: this.updateSegment, isDisabled: this.state.isBusy }),
segmentData_1[segmentIndex_1].clusters.map(function (c, i) { return React.createElement(ClusterNode, { cluster: c, totalClusters: segmentData_1[segmentIndex_1].clusters.length, segmentIndex: segmentIndex_1, clusterIndex: i, key: "cluster-" + segmentIndex_1 + "-" + i }); }));
}
return React.createElement(React.Fragment, null);
};
return SegmentTree;
}(base_1.PurePluginUIComponent));
exports.SegmentTree = SegmentTree;
var ClusterNode = /** @class */ (function (_super) {
tslib_1.__extends(ClusterNode, _super);
function ClusterNode() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = {
isCollapsed: false,
showAll: false,
showNone: false,
showSearch: false,
isBusy: false,
cluster: _this.props.cluster,
searchText: ''
};
_this.inputStream = new rxjs_1.Subject();
_this.handleInputStream = function (inputStr) {
_this.setState({ searchText: inputStr });
var filteredRes = _this.props.cluster.filter(function (item) {
return item.pdb_id.toLowerCase().indexOf(inputStr.toLowerCase()) >= 0;
});
_this.setState({ cluster: filteredRes });
};
_this.toggleExpanded = function (e) {
e.preventDefault();
_this.setState({ isCollapsed: !_this.state.isCollapsed });
e.currentTarget.blur();
};
_this.selectAll = function (e) {
e.preventDefault();
_this.setState({ showAll: !_this.state.showAll, showNone: false });
e.currentTarget.blur();
};
_this.selectNone = function (e) {
e.preventDefault();
_this.setState({ showAll: false, showNone: !_this.state.showNone });
e.currentTarget.blur();
};
_this.applyAction = function (e) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var customState, currentState;
var _this = this;
return tslib_1.__generator(this, function (_a) {
e.preventDefault();
e.currentTarget.blur();
customState = this.customState;
customState.events.isBusy.next(true);
currentState = tslib_1.__assign({}, this.state);
this.setState({ showAll: false, showNone: false });
setTimeout(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var loadStrs, _a, _b, str, structStateId, structRef, cell, isHidden, e_1_1;
var e_1, _c;
return tslib_1.__generator(this, function (_d) {
switch (_d.label) {
case 0:
loadStrs = [];
_d.label = 1;
case 1:
_d.trys.push([1, 9, 10, 15]);
_a = tslib_1.__asyncValues(this.state.cluster);
_d.label = 2;
case 2: return [4 /*yield*/, _a.next()];
case 3:
if (!(_b = _d.sent(), !_b.done)) return [3 /*break*/, 8];
str = _b.value;
structStateId = str.pdb_id + "_" + str.struct_asym_id;
structRef = undefined;
if (customState && customState.superpositionState && customState.superpositionState.models[structStateId]) {
structRef = this.customState.superpositionState.models[structStateId];
}
if (!structRef) return [3 /*break*/, 6];
cell = this.plugin.state.data.cells.get(structRef);
if (!cell) return [3 /*break*/, 5];
isHidden = cell.state.isHidden ? true : false;
if (!((isHidden && currentState.showAll) || (!isHidden && currentState.showNone))) return [3 /*break*/, 5];
return [4 /*yield*/, commands_1.PluginCommands.State.ToggleVisibility(this.plugin, { state: cell.parent, ref: structRef })];
case 4:
_d.sent();
_d.label = 5;
case 5: return [3 /*break*/, 7];
case 6:
if (currentState.showAll)
loadStrs.push(str);
_d.label = 7;
case 7: return [3 /*break*/, 2];
case 8: return [3 /*break*/, 15];
case 9:
e_1_1 = _d.sent();
e_1 = { error: e_1_1 };
return [3 /*break*/, 15];
case 10:
_d.trys.push([10, , 13, 14]);
if (!(_b && !_b.done && (_c = _a.return))) return [3 /*break*/, 12];
return [4 /*yield*/, _c.call(_a)];
case 11:
_d.sent();
_d.label = 12;
case 12: return [3 /*break*/, 14];
case 13:
if (e_1) throw e_1.error;
return [7 /*endfinally*/];
case 14: return [7 /*endfinally*/];
case 15:
;
commands_1.PluginCommands.Camera.Reset(this.plugin);
if (!(loadStrs.length > 0)) return [3 /*break*/, 17];
return [4 /*yield*/, superposition_1.renderSuperposition(this.plugin, this.props.segmentIndex, loadStrs)];
case 16:
_d.sent();
_d.label = 17;
case 17:
customState.events.isBusy.next(false);
return [2 /*return*/];
}
});
}); });
return [2 /*return*/];
});
}); };
_this.cancelAction = function (e) {
e.preventDefault();
_this.setState({ showAll: false, showNone: false });
e.currentTarget.blur();
};
_this.clearSearch = function (e) {
e.preventDefault();
_this.setState({ searchText: '' });
_this.inputStream.next('');
e.currentTarget.blur();
};
return _this;
}
ClusterNode.prototype.componentDidMount = function () {
var _this = this;
this.subscribe(this.plugin.customState.events.isBusy, function (e) {
_this.setState({ isBusy: e, showAll: false, showNone: false });
});
this.subscribe(this.inputStream.pipe(operators_1.debounceTime(1000 / 24)), function (e) { return _this.handleInputStream(e); });
};
Object.defineProperty(ClusterNode.prototype, "customState", {
get: function () {
return this.plugin.customState;
},
enumerable: false,
configurable: true
});
ClusterNode.prototype.render = function () {
var _this = this;
var customState = this.customState;
if (!customState.superpositionState || !customState.superpositionState.segmentData)
return React.createElement(React.Fragment, null);
var expand = React.createElement(common_1.IconButton, { svg: this.state.isCollapsed ? icons_1.ArrowRightSvg : icons_1.ArrowDropDownSvg, flex: '20px', onClick: this.toggleExpanded, transparent: true, disabled: this.state.isBusy, className: 'msp-no-hover-outline' });
var title = "Segment " + customState.superpositionState.activeSegment + " Cluster " + (this.props.clusterIndex + 1);
var label = React.createElement(common_1.Button, { className: "msp-btn-tree-label", noOverflow: true, title: title, disabled: this.state.isBusy },
React.createElement("span", null,
"Cluster ",
this.props.clusterIndex + 1),
" ",
React.createElement("small", null,
this.state.cluster.length < this.props.cluster.length ? this.state.cluster.length + " / " : '',
this.props.cluster.length,
" chain",
this.props.cluster.length > 1 ? 's' : ''));
var selectionControls = React.createElement(React.Fragment, null,
React.createElement(common_1.Button, { icon: icons_1.CheckSvg, flex: true, onClick: this.selectAll, style: { flex: '0 0 50px', textAlign: 'center', fontSize: '80%', color: '#9cacc3', padding: 0 }, disabled: this.state.isBusy, title: "Show all chains" }, "All"),
React.createElement(common_1.Button, { icon: icons_1.CloseSvg, flex: true, onClick: this.selectNone, style: { flex: '0 0 50px', textAlign: 'center', fontSize: '80%', color: '#9cacc3', padding: 0 }, disabled: this.state.isBusy, title: "Hide all chains" }, "None"));
var mainRow = React.createElement("div", { className: "msp-flex-row msp-tree-row", style: { marginTop: '10px' } },
expand,
label,
this.props.cluster.length > 1 && selectionControls);
var searchControls = React.createElement("div", { className: 'msp-mapped-parameter-group', style: { fontSize: '90%' } },
React.createElement("div", { className: 'msp-control-row msp-transform-header-brand-gray', style: { height: '33px', marginLeft: '30px' } },
React.createElement("span", { className: 'msp-control-row-label' }, "Search PDB ID"),
React.createElement("div", { className: 'msp-control-row-ctrl' },
React.createElement("input", { type: 'text', placeholder: 'Enter PDB ID..', disabled: this.state.isBusy, onChange: function (e) { return _this.inputStream.next(e.target.value); }, value: this.state.searchText, maxLength: 4 }))),
React.createElement(common_1.IconButton, { svg: icons_1.CloseSvg, flex: true, onClick: this.clearSearch, style: { flex: '0 0 24px', padding: 0 }, disabled: this.state.isBusy || this.state.searchText === '', toggleState: this.state.searchText !== '', title: 'Clear search input' }));
return React.createElement(React.Fragment, null,
mainRow,
(this.state.showAll || this.state.showNone) && React.createElement("div", null,
React.createElement("div", { className: "msp-control-row msp-transform-header-brand-" + (this.state.showAll ? 'green' : 'red'), style: { display: 'flex', marginLeft: '20px', height: '35px' } },
React.createElement("span", { className: 'msp-control-row-label', style: { flex: '1 1 auto', textAlign: 'left', fontSize: '85%' } },
this.state.showAll ? 'Display' : 'Hide',
" ",
this.state.cluster.length < this.props.cluster.length ? this.state.cluster.length + " / " : 'all ',
this.props.cluster.length,
" chains"),
React.createElement(common_1.Button, { icon: icons_1.CheckSvg, flex: true, onClick: this.applyAction, style: { flex: '0 0 60px', textAlign: 'center', fontSize: '78%', color: '#9cacc3', padding: 0, margin: '0 1px' }, title: "Apply action" }, "Apply"),
React.createElement(common_1.Button, { icon: icons_1.CloseSvg, flex: true, onClick: this.cancelAction, style: { flex: '0 0 60px', textAlign: 'center', fontSize: '78%', color: '#9cacc3', padding: 0, margin: '0 1px' }, title: "Cancel action" }, "Cancel"))),
(!this.state.isCollapsed && this.props.cluster.length > 5) && searchControls,
!this.state.isCollapsed && React.createElement("div", { className: 'msp-tree-updates-wrapper', style: { maxHeight: (this.props.totalClusters > 1) ? '330px' : '87%', overflowY: 'auto' } }, this.state.cluster.map(function (s, i) { return React.createElement(StructureNode, { segmentIndex: _this.props.segmentIndex, structure: s, isRep: i === 0 ? true : false, key: "str-" + s.pdb_id + s.struct_asym_id + i }); })));
};
return ClusterNode;
}(base_1.PluginUIComponent));
var StructureNode = /** @class */ (function (_super) {
tslib_1.__extends(StructureNode, _super);
function StructureNode() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = {
showControls: false,
isBusy: false,
isProcessing: false,
isHidden: true,
};
_this.toggleVisible = function (e) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var structHierarchy, _i, _a, c, currentHiddenState;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
e.preventDefault();
e.currentTarget.blur();
this.setState({ isProcessing: true, showControls: false });
if (!this.ref) return [3 /*break*/, 1];
structHierarchy = this.plugin.managers.structure.hierarchy.current.refs.get(this.ref);
if (structHierarchy && structHierarchy.components) {
for (_i = 0, _a = structHierarchy.components; _i < _a.length; _i++) {
c = _a[_i];
currentHiddenState = c.cell.state.isHidden ? true : false;
if (currentHiddenState === this.state.isHidden) {
commands_1.PluginCommands.State.ToggleVisibility(this.plugin, { state: c.cell.parent, ref: c.cell.transform.ref });
}
}
this.setState({ isHidden: !this.state.isHidden });
}
return [3 /*break*/, 3];
case 1: return [4 /*yield*/, superposition_1.renderSuperposition(this.plugin, this.props.segmentIndex, [this.props.structure])];
case 2:
_b.sent();
_b.label = 3;
case 3:
this.setState({ isProcessing: false });
commands_1.PluginCommands.Camera.Reset(this.plugin);
return [2 /*return*/];
}
});
}); };
_this.selectAction = function (item) {
if (!item)
return;
_this.setState({ showControls: false });
(item === null || item === void 0 ? void 0 : item.value)();
};
_this.highlight = function (e) {
e.preventDefault();
if (_this.ref) {
var cell = _this.plugin.state.data.cells.get(_this.ref);
commands_1.PluginCommands.Interactivity.Object.Highlight(_this.plugin, { state: cell.parent, ref: _this.ref });
}
e.currentTarget.blur();
};
_this.clearHighlight = function (e) {
e.preventDefault();
commands_1.PluginCommands.Interactivity.ClearHighlights(_this.plugin);
e.currentTarget.blur();
};
_this.toggleControls = function (e) {
e.preventDefault();
_this.setState({ showControls: !_this.state.showControls });
e.currentTarget.blur();
};
return _this;
}
Object.defineProperty(StructureNode.prototype, "customState", {
get: function () {
return this.plugin.customState;
},
enumerable: false,
configurable: true
});
Object.defineProperty(StructureNode.prototype, "ref", {
get: function () {
if (this.customState && this.customState.superpositionState && this.customState.superpositionState.models[this.props.structure.pdb_id + "_" + this.props.structure.struct_asym_id]) {
return this.customState.superpositionState.models[this.props.structure.pdb_id + "_" + this.props.structure.struct_asym_id];
}
else {
return undefined;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(StructureNode.prototype, "modelCell", {
get: function () {
if (this.ref) {
return this.plugin.state.data.cells.get(this.ref);
}
else {
return undefined;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(StructureNode.prototype, "isAllHidden", {
get: function () {
var isHidden = true;
if (this.ref) {
var structHierarchy = this.plugin.managers.structure.hierarchy.current.refs.get(this.ref);
if (structHierarchy && structHierarchy.components) {
for (var _i = 0, _a = structHierarchy.components; _i < _a.length; _i++) {
var c = _a[_i];
if (c && c.cell && !c.cell.state.isHidden) {
isHidden = false;
break;
}
}
}
else {
isHidden = false;
}
}
return isHidden;
},
enumerable: false,
configurable: true
});
StructureNode.prototype.checkRelation = function (ref) {
var isRelated = false;
var cell = this.plugin.state.data.cells.get(ref);
if (cell && cell.transform.parent) {
if (cell && cell.transform.parent === this.ref) {
isRelated = true;
}
else {
var pcell = this.plugin.state.data.cells.get(cell.transform.parent);
if (pcell && pcell.transform.parent === this.ref)
isRelated = true;
}
}
else {
var currentNodeCell = this.plugin.state.data.cells.get(this.ref);
if (currentNodeCell && currentNodeCell.transform.parent === cell.transform.parent) {
isRelated = true;
}
}
return isRelated;
};
StructureNode.prototype.is = function (e) {
if (!this.ref)
return false;
var isRelated = false;
if (this.ref && e.ref !== this.ref) {
isRelated = this.checkRelation(e.ref);
}
if (e.ref === this.ref || isRelated) {
return true;
}
else {
var invalidStruct = (this.customState.superpositionState.invalidStruct.indexOf(this.props.structure.pdb_id + "_" + this.props.structure.struct_asym_id) > -1) ? true : false;
return invalidStruct ? true : false;
}
};
StructureNode.prototype.componentDidMount = function () {
var _this = this;
this.setState({ isHidden: this.isAllHidden });
this.subscribe(this.plugin.customState.events.isBusy, function (e) {
_this.setState({ isBusy: e, showControls: false });
});
this.subscribe(this.plugin.state.events.cell.stateUpdated.pipe(operators_1.filter(function (e) { return _this.is(e); }), operators_1.debounceTime(33)), function (e) {
_this.setState({ isHidden: _this.isAllHidden });
// this.forceUpdate();
});
};
StructureNode.prototype.getTagRefs = function (tags) {
var TagSet = new Set(tags);
var tree = this.plugin.state.data.tree;
return mol_state_2.StateSelection.findUniqueTagsInSubtree(tree, this.modelCell.transform.ref, TagSet);
};
StructureNode.prototype.getRandomColor = function () {
var clList = lists_1.ColorLists;
var spState = this.plugin.customState.superpositionState;
var palleteIndex = spState.colorState[this.props.segmentIndex].palleteIndex;
var colorIndex = spState.colorState[this.props.segmentIndex].colorIndex;
if (clList[spState.colorPalette[palleteIndex]].list[colorIndex + 1]) {
colorIndex += 1;
}
else {
colorIndex = 0;
palleteIndex = spState.colorPalette[palleteIndex + 1] ? palleteIndex + 1 : 0;
}
var palleteName = spState.colorPalette[palleteIndex];
this.plugin.customState.superpositionState.colorState[this.props.segmentIndex].palleteIndex = palleteIndex;
this.plugin.customState.superpositionState.colorState[this.props.segmentIndex].colorIndex = colorIndex;
return clList[palleteName].list[colorIndex];
};
StructureNode.prototype.addChainRepr = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var uniformColor1, strInstance, query, chainSel;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
uniformColor1 = this.getRandomColor();
strInstance = this.plugin.state.data.select(this.ref)[0];
query = builder_1.MolScriptBuilder.struct.generator.atomGroups({
'chain-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.struct.atomProperty.macromolecular.label_asym_id(), this.props.structure.struct_asym_id])
});
return [4 /*yield*/, this.plugin.builders.structure.tryCreateComponentFromExpression(strInstance, query, "Chain-" + this.props.segmentIndex, { label: "Chain", tags: ["superposition-sel"] })];
case 1:
chainSel = _a.sent();
if (!chainSel) return [3 /*break*/, 3];
return [4 /*yield*/, this.plugin.builders.structure.representation.addRepresentation(chainSel, { type: 'cartoon', color: 'uniform', colorParams: { value: uniformColor1 } }, { tag: "superposition-visual" })];
case 2:
_a.sent();
_a.label = 3;
case 3: return [2 /*return*/];
}
});
});
};
StructureNode.prototype.updates = function () {
var _this = this;
var structHierarchy = this.plugin.managers.structure.hierarchy.current.refs.get(this.ref);
if (structHierarchy && structHierarchy.components) {
var representations_1 = [];
var showAddChainBtn_1 = true;
structHierarchy.components.forEach(function (comps) {
var gKeys = comps.key.split(',');
var cId1Arr = gKeys[0].split('-');
if (cId1Arr[2] === 'Chain')
showAddChainBtn_1 = false;
if (comps.representations) {
comps.representations.forEach(function (repr) {
representations_1.push(repr);
});
}
});
var customState = this.plugin.customState;
if (customState.initParams && customState.initParams.superpositionParams && !customState.initParams.superpositionParams.ligandView) {
showAddChainBtn_1 = false;
}
if (representations_1.length > 0) {
return React.createElement("div", { className: 'msp-accent-offset', style: { marginLeft: '40px' } },
representations_1.length > 0 && representations_1.map(function (r, i) { return React.createElement(StructureRepresentationEntry, { group: [structHierarchy], key: r.cell.transform.ref + "-" + i, representation: r }); }),
showAddChainBtn_1 && React.createElement("div", { className: 'msp-control-group-header', style: { marginTop: '1px' } },
React.createElement(common_1.Button, { noOverflow: true, className: 'msp-control-button-label', title: "Click to add chain representaion", onClick: function () { return _this.addChainRepr(); } },
"\u00A0\u00A0Add Chain ",
this.props.structure.struct_asym_id,
" Representation")));
}
}
return React.createElement(React.Fragment, null);
};
StructureNode.prototype.getSubtitle = function () {
var customState = this.plugin.customState;
var hetList = customState.superpositionState.hets[this.props.structure.pdb_id + "_" + this.props.structure.struct_asym_id];
var subtitle;
if (hetList) {
var hetLimit = this.props.structure.is_representative ? 1 : 4;
var totalHets = hetList.length;
var hetStr = hetList.join(', ');
if (totalHets > hetLimit) {
hetStr = hetList.slice(0, hetLimit).join(', ');
hetStr += " + " + (totalHets - hetLimit);
}
subtitle = " ( " + hetStr + " )";
if (this.props.structure.is_representative)
subtitle = " " + subtitle + " ( Representative )";
}
else if (this.props.structure.is_representative) {
subtitle = ' ( Representative )';
}
return subtitle;
};
Object.defineProperty(StructureNode.prototype, "panelColor", {
get: function () {
var panelColor = '#808080';
if (!this.state.isHidden) {
if (this.modelCell) {
var refs = this.getTagRefs(["superposition-visual", "superposition-ligand-visual"]);
var visualRef = refs["superposition-ligand-visual"] ? refs["superposition-ligand-visual"] : refs["superposition-visual"] ? refs["superposition-visual"] : undefined;
if (visualRef) {
var visualCell = this.plugin.state.data.cells.get(visualRef);
if (visualCell.params && visualCell.params.values && visualCell.params.values.colorTheme) {
var colorTheme = visualCell.params.values.colorTheme;
if (colorTheme.params && colorTheme.params.value) {
panelColor = "" + color_1.Color.toStyle(colorTheme.params.value);
}
else if (colorTheme.params && colorTheme.params.palette) {
var colorList1 = colorTheme.params.palette.params.list.colors;
panelColor = "" + color_1.Color.toStyle(colorList1[0]);
}
else if (colorTheme.params && colorTheme.params.list) {
var colorList2 = colorTheme.params.list.colors;
panelColor = "" + color_1.Color.toStyle(colorList2[0]);
}
}
}
}
}
return panelColor;
},
enumerable: false,
configurable: true
});
StructureNode.prototype.render = function () {
var superpositionParams = this.customState.initParams.superpositionParams;
var strutStateId = this.props.structure.pdb_id + "_" + this.props.structure.struct_asym_id;
var invalidStruct = (this.customState.superpositionState.invalidStruct.indexOf(strutStateId) > -1) ? true : false;
var noMatrixStruct = (this.customState.superpositionState.noMatrixStruct.indexOf(strutStateId) > -1) ? true : false;
var subTitle = invalidStruct ? noMatrixStruct ? " Matrix not available!" : " No Ligand found!" : this.getSubtitle();
var strTitle = this.props.structure.pdb_id + " chain " + this.props.structure.auth_asym_id;
if (superpositionParams && superpositionParams.ligandView) {
strTitle = this.props.structure.pdb_id + " " + this.props.structure.struct_asym_id;
}
var label = React.createElement(common_1.Button, { className: "msp-btn-tree-label", style: { borderLeftColor: this.panelColor }, noOverflow: true, title: strTitle, disabled: (invalidStruct || this.state.isBusy || this.state.isProcessing) ? true : false, onMouseEnter: this.highlight, onMouseLeave: this.clearHighlight },
React.createElement("span", null, strTitle),
subTitle && React.createElement("small", null, subTitle));
var expand = React.createElement(common_1.IconButton, { svg: !this.state.showControls ? icons_1.ArrowRightSvg : icons_1.ArrowDropDownSvg, flex: '20px', onClick: this.toggleControls, transparent: true, className: 'msp-no-hover-outline', disabled: (invalidStruct || this.state.isBusy || this.state.isProcessing) ? true : false });
var visibility = React.createElement(common_1.IconButton, { svg: this.state.isHidden ? icons_1.VisibilityOffOutlinedSvg : icons_1.VisibilityOutlinedSvg, toggleState: false, small: true, onClick: this.toggleVisible, disabled: (invalidStruct || this.state.isBusy || this.state.isProcessing) ? true : false, title: this.state.isHidden ? "Show chain" : "Hide chain" });
var row = React.createElement("div", { className: "msp-flex-row msp-tree-row", style: { marginLeft: !this.state.isHidden ? '10px' : '31px' } },
!this.state.isHidden && expand,
label,
visibility);
return React.createElement("div", { style: { marginBottom: '1px' } },
row,
this.state.showControls && this.updates());
};
return StructureNode;
}(base_1.PluginUIComponent));
var StructureRepresentationEntry = /** @class */ (function (_super) {
tslib_1.__extends(StructureRepresentationEntry, _super);
function StructureRepresentationEntry() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.toggleVisible = function (e) {
e.preventDefault();
e.currentTarget.blur();
var cell = _this.props.representation.cell;
commands_1.PluginCommands.State.ToggleVisibility(_this.plugin, { state: cell.parent, ref: cell.transform.parent });
};
return _this;
}
StructureRepresentationEntry.prototype.componentDidMount = function () {
var _this = this;
this.subscribe(this.plugin.state.events.cell.stateUpdated, function (e) {
if (mol_state_1.State.ObjectEvent.isCell(e, _this.props.representation.cell))
_this.forceUpdate();
});
};
StructureRepresentationEntry.prototype.render = function () {
var _a, _b, _c, _d, _e, _f, _g;
var repr = this.props.representation.cell;
var label = (_a = repr.obj) === null || _a === void 0 ? void 0 : _a.label;
if (((_b = repr.obj) === null || _b === void 0 ? void 0 : _b.data.source) && ((_c = repr.obj) === null || _c === void 0 ? void 0 : _c.data.source.label)) {
var sourceLabel = (((_d = repr.obj) === null || _d === void 0 ? void 0 : _d.data.source.label.indexOf('[Focus]')) >= 0) ? '[Focus]' : (_e = repr.obj) === null || _e === void 0 ? void 0 : _e.data.source.label;
label = sourceLabel + " " + ((label && label.length < 21) ? ' - ' + label : '');
}
if (((_f = repr.obj) === null || _f === void 0 ? void 0 : _f.data.source) && ((_g = repr.obj) === null || _g === void 0 ? void 0 : _g.data.source.label) === 'Custom Selection')
label = 'Custom Selection';
return React.createElement("div", { className: 'msp-representation-entry' },
repr.parent && React.createElement(common_1.ExpandGroup, { header: "" + (label || 'Representation'), noOffset: true, headerStyle: { overflow: 'hidden' } },
React.createElement(update_transform_1.UpdateTransformControl, { state: repr.parent, transform: repr.transform, customHeader: 'none', noMargin: true })),
React.createElement(common_1.IconButton, { svg: this.props.representation.cell.state.isHidden ? icons_1.VisibilityOffOutlinedSvg : icons_1.VisibilityOutlinedSvg, toggleState: false, onClick: this.toggleVisible, title: this.props.representation.cell.state.isHidden ? "Show representation" : "Hide representation", small: true, className: 'msp-default-bg', style: { position: 'absolute', top: 0, right: 0, lineHeight: '24px', height: '24px', textAlign: 'right', width: '32px', paddingRight: '6px', background: 'none' } }));
};
return StructureRepresentationEntry;
}(base_1.PurePluginUIComponent));
//# sourceMappingURL=segment-tree.js.map