drugflow-molstar
Version:
Molstar implementation for DrugFlow
179 lines (178 loc) • 14.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AfSuperpositionControls = exports.AlphafoldSuperpositionParams = exports.AlphafoldSuperpositionControls = exports.AlphafoldPaeControls = exports.InfoIconSvg = void 0;
var tslib_1 = require("tslib");
var jsx_runtime_1 = require("react/jsx-runtime");
var react_1 = tslib_1.__importDefault(require("react"));
var base_1 = require("Molstar/mol-plugin-ui/base");
var icons_1 = require("Molstar/mol-plugin-ui/controls/icons");
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 superposition_1 = require("../superposition");
var d3_scale_1 = require("d3-scale");
var d3_axis_1 = require("d3-axis");
var d3_selection_1 = require("d3-selection");
var _InfoIcon = (0, jsx_runtime_1.jsx)("svg", tslib_1.__assign({ width: '24px', height: '24px', viewBox: '0 0 24 24', strokeWidth: '0.1px' }, { children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z" }) }));
function InfoIconSvg() { return _InfoIcon; }
exports.InfoIconSvg = InfoIconSvg;
var AlphafoldPaeControls = /** @class */ (function (_super) {
tslib_1.__extends(AlphafoldPaeControls, _super);
function AlphafoldPaeControls(props, context) {
var _this = _super.call(this, props, context) || this;
_this.axisBoxRef = react_1.default.createRef();
return _this;
}
AlphafoldPaeControls.prototype.defaultState = function () {
return {
isCollapsed: false,
header: 'AlphaFold PAE',
brand: { accent: 'gray', svg: icons_1.SuperpositionSvg },
isHidden: true
};
};
AlphafoldPaeControls.prototype.componentDidMount = function () {
var _this = this;
this.subscribe(this.plugin.managers.structure.hierarchy.behaviors.selection, function (sel) {
var superpositionState = _this.plugin.customState.superpositionState;
if (superpositionState && superpositionState.alphafold.ref && superpositionState.alphafold.apiData.pae && superpositionState.alphafold.apiData.pae !== '' && superpositionState.alphafold.apiData.pae !== '') {
_this.setState({ isHidden: false });
var domainMax = superpositionState.alphafold.apiData.length;
var x = (0, d3_scale_1.scaleLinear)().domain([0, domainMax]).range([0, 200]);
var xAxis = (0, d3_axis_1.axisBottom)(x).ticks(6).tickFormat(_this.formatTicks).tickSizeOuter(0);
var yAxis = (0, d3_axis_1.axisLeft)(x).ticks(6).tickFormat(_this.formatTicks).tickSizeOuter(0);
var axisContainer = (0, d3_selection_1.select)(_this.axisBoxRef.current);
axisContainer.append('svg:svg')
.attr('width', 220)
.attr('height', 30)
.attr('class', 'pae-x-axis')
.style('z-index', '1')
.style('position', 'absolute')
.attr('transform', "translate(-93,202)")
.append('g')
.attr('transform', "translate(6,0)")
.call(xAxis);
axisContainer.append('svg:svg')
.attr('width', 50)
.attr('height', 220)
.attr('class', 'pae-y-axis')
.style('z-index', '1')
.style('position', 'absolute')
.attr('transform', "translate(-123,0)")
.append('g')
.attr('transform', "translate(36,4)")
.call(yAxis);
}
});
};
AlphafoldPaeControls.prototype.formatTicks = function (d) {
return d > 999 ? d / 1000 + 'k' : d;
};
AlphafoldPaeControls.prototype.renderControls = function () {
var superpositionState = this.plugin.customState.superpositionState;
if (!superpositionState || !superpositionState.alphafold)
return null;
var errorScale = [0, 5, 10, 15, 20, 25, 30];
return (0, jsx_runtime_1.jsxs)("div", tslib_1.__assign({ className: 'msp-flex-row', style: { height: 'auto', textAlign: 'center', justifyContent: 'center', padding: '15px 0', position: 'relative', fontSize: '12px' } }, { children: [(0, jsx_runtime_1.jsx)("div", { ref: this.axisBoxRef, className: 'pae-axis-box', style: { position: 'absolute', width: '100%', height: '100%' } }), (0, jsx_runtime_1.jsx)("span", tslib_1.__assign({ style: { transform: 'rotate(270deg)', position: 'absolute', transformOrigin: '0 0', left: '10px', top: '165px', fontWeight: 500 } }, { children: "Aligned residue" })), (0, jsx_runtime_1.jsxs)("div", tslib_1.__assign({ className: 'msp-flex-row', style: { height: 'auto', flexDirection: 'column' } }, { children: [(0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ style: { width: '200px', height: '200px', border: '1px solid #6a635a', margin: '2px 0 25px 25px', position: 'relative' } }, { children: (0, jsx_runtime_1.jsx)("img", { style: { width: '100%', height: '100%', position: 'absolute', left: 0, top: 0 }, src: "".concat(superpositionState.alphafold.apiData.pae), alt: "PAE" }) })), (0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ style: { textAlign: 'center', paddingLeft: '30px', marginBottom: '20px', fontWeight: 500 } }, { children: "Scored residue" })), (0, jsx_runtime_1.jsx)("img", { style: { width: '200px', height: '10px', border: '1px solid #6a635a', margin: '2px 0 25px 25px', transform: 'rotate(180deg)' }, src: 'https://alphafold.ebi.ac.uk/assets/img/horizontal_colorbar.png', alt: "PAE Scale" }), (0, jsx_runtime_1.jsx)("ul", tslib_1.__assign({ style: { listStyleType: 'none', fontWeight: 500, margin: 0, display: 'inline-block', position: 'absolute', top: '292px', marginLeft: '24px' } }, { children: errorScale.map(function (errValue) { return (0, jsx_runtime_1.jsx)("li", tslib_1.__assign({ style: { float: 'left', marginRight: '18px' } }, { children: errValue }), errValue); }) })), (0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ style: { textAlign: 'center', paddingLeft: '20px', fontWeight: 500 } }, { children: "Expected position error (\u00C5ngstr\u00F6ms)" }))] }))] }));
};
return AlphafoldPaeControls;
}(base_1.CollapsableControls));
exports.AlphafoldPaeControls = AlphafoldPaeControls;
var AlphafoldSuperpositionControls = /** @class */ (function (_super) {
tslib_1.__extends(AlphafoldSuperpositionControls, _super);
function AlphafoldSuperpositionControls() {
return _super !== null && _super.apply(this, arguments) || this;
}
AlphafoldSuperpositionControls.prototype.defaultState = function () {
return {
isCollapsed: false,
header: 'AlphaFold Superposition',
brand: { accent: 'gray', svg: icons_1.SuperpositionSvg },
isHidden: true
};
};
AlphafoldSuperpositionControls.prototype.componentDidMount = function () {
var _this = this;
this.subscribe(this.plugin.managers.structure.hierarchy.behaviors.selection, function (sel) {
var superpositionState = _this.plugin.customState.superpositionState;
if (superpositionState && superpositionState.alphafold.apiData.cif && superpositionState.alphafold.apiData.cif !== '') {
_this.setState({ isHidden: false });
}
});
};
AlphafoldSuperpositionControls.prototype.rmsdTable = function () {
var spData = this.plugin.customState.superpositionState;
var activeSegment = spData.activeSegment;
var rmsds = spData.alphafold.rmsds;
return (0, jsx_runtime_1.jsxs)("div", tslib_1.__assign({ className: 'msp-control-offset' }, { children: [(rmsds.length == 0 || !rmsds[activeSegment - 1]) && (0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ className: 'msp-flex-row', style: { padding: '5px 0 0 10px' } }, { children: (0, jsx_runtime_1.jsx)("strong", { children: "No overlap found!" }) })), rmsds[activeSegment - 1] && (0, jsx_runtime_1.jsxs)("div", tslib_1.__assign({ className: 'msp-flex-row' }, { children: [(0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ style: { width: '40%', borderRight: '1px solid rgb(213 206 196)', padding: '5px 0 0 5px' } }, { children: (0, jsx_runtime_1.jsx)("strong", { children: "Entry" }) })), (0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ style: { padding: '5px 0 0 5px' } }, { children: (0, jsx_runtime_1.jsx)("strong", { children: "RMSD (\u212B)" }) }))] })), rmsds[activeSegment - 1] && rmsds[activeSegment - 1].map(function (d) {
var details = d.split(':');
return details[1] !== '-' ? (0, jsx_runtime_1.jsxs)("div", tslib_1.__assign({ className: 'msp-flex-row' }, { children: [(0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ className: 'msp-control-row-label', style: { width: '40%', borderRight: '1px solid rgb(213 206 196)', padding: '5px 0 0 5px' } }, { children: details[0] })), (0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ style: { padding: '5px 0 0 5px' } }, { children: details[1] }))] }), d) : null;
})] }));
};
AlphafoldSuperpositionControls.prototype.renderControls = function () {
var superpositionState = this.plugin.customState.superpositionState;
return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [superpositionState.alphafold.ref !== '' && this.rmsdTable(), superpositionState.alphafold.ref === '' && (0, jsx_runtime_1.jsx)(AfSuperpositionControls, {})] });
};
return AlphafoldSuperpositionControls;
}(base_1.CollapsableControls));
exports.AlphafoldSuperpositionControls = AlphafoldSuperpositionControls;
exports.AlphafoldSuperpositionParams = {
// alignSequences: PD.Boolean(true, { isEssential: true, description: 'For Chain-based 3D superposition, perform a sequence alignment and use the aligned residue pairs to guide the 3D superposition.' }),
traceOnly: param_definition_1.ParamDefinition.Boolean(true, { description: 'For Chain- and Uniprot-based 3D superposition, base superposition only on CA (and equivalent) atoms.' })
};
var DefaultAlphafoldSuperpositionOptions = param_definition_1.ParamDefinition.getDefaultValues(exports.AlphafoldSuperpositionParams);
var AfSuperpositionControls = /** @class */ (function (_super) {
tslib_1.__extends(AfSuperpositionControls, _super);
function AfSuperpositionControls() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = {
isBusy: false,
canUseDb: true,
action: undefined,
options: DefaultAlphafoldSuperpositionOptions
};
_this.superposeDb = function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var spData;
return tslib_1.__generator(this, function (_a) {
this.setState({ isBusy: true });
spData = this.plugin.customState.superpositionState;
spData.alphafold.traceOnly = this.state.options.traceOnly;
(0, superposition_1.superposeAf)(this.plugin, this.state.options.traceOnly);
return [2 /*return*/];
});
}); };
_this.toggleOptions = function () { return _this.setState({ action: _this.state.action === 'options' ? void 0 : 'options' }); };
_this.setOptions = function (values) {
_this.setState({ options: values });
};
return _this;
}
AfSuperpositionControls.prototype.componentDidMount = function () {
var _this = this;
this.subscribe(this.plugin.behaviors.state.isBusy, function (v) {
_this.setState({ isBusy: v });
});
};
Object.defineProperty(AfSuperpositionControls.prototype, "selection", {
get: function () {
return this.plugin.managers.structure.selection;
},
enumerable: false,
configurable: true
});
Object.defineProperty(AfSuperpositionControls.prototype, "customState", {
get: function () {
return this.plugin.customState;
},
enumerable: false,
configurable: true
});
AfSuperpositionControls.prototype.superposeByDbMapping = function () {
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(common_1.Button, tslib_1.__assign({ icon: icons_1.SuperposeChainsSvg, title: 'Superpose AlphaFold structure using intersection of residues from SIFTS UNIPROT mapping.', className: 'msp-btn msp-btn-block', onClick: this.superposeDb, style: { marginTop: '1px', textAlign: 'left' }, disabled: this.state.isBusy }, { children: "Load AlphaFold structure" })) });
};
AfSuperpositionControls.prototype.render = function () {
return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ style: { backgroundColor: '#dce54e', fontWeight: 500, padding: '5px 12px' } }, { children: "New Feature!" })), (0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ className: 'msp-help-text', style: { margin: '2px 0' } }, { children: (0, jsx_runtime_1.jsxs)("div", tslib_1.__assign({ className: 'msp-help-description' }, { children: [(0, jsx_runtime_1.jsx)(icons_1.Icon, { svg: InfoIconSvg, inline: true }), "Load and superpose AlphaFold structure against representative chains."] })) })), (0, jsx_runtime_1.jsxs)("div", tslib_1.__assign({ className: 'msp-flex-row' }, { children: [this.state.canUseDb && this.superposeByDbMapping(), (0, jsx_runtime_1.jsx)(common_1.ToggleButton, { icon: icons_1.TuneSvg, label: '', title: 'Options', toggle: this.toggleOptions, isSelected: this.state.action === 'options', disabled: this.state.isBusy, style: { flex: '0 0 40px', padding: 0 } })] })), this.state.action === 'options' && (0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ className: 'msp-control-offset' }, { children: (0, jsx_runtime_1.jsx)(parameters_1.ParameterControls, { params: exports.AlphafoldSuperpositionParams, values: this.state.options, onChangeValues: this.setOptions, isDisabled: this.state.isBusy }) }))] });
};
return AfSuperpositionControls;
}(base_1.PurePluginUIComponent));
exports.AfSuperpositionControls = AfSuperpositionControls;