molstar
Version:
A comprehensive macromolecular library.
421 lines • 25 kB
JavaScript
"use strict";
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ValidationReportRandomCoilIndexPreset = exports.ValidationReportDensityFitPreset = exports.ValidationReportGeometryQualityPreset = exports.RCSBValidationReport = void 0;
var tslib_1 = require("tslib");
var param_definition_1 = require("../../../mol-util/param-definition");
var behavior_1 = require("../../../mol-plugin/behavior/behavior");
var prop_1 = require("./prop");
var random_coil_index_1 = require("./color/random-coil-index");
var geometry_quality_1 = require("./color/geometry-quality");
var int_1 = require("../../../mol-data/int");
var representation_1 = require("./representation");
var density_fit_1 = require("./color/density-fit");
var util_1 = require("../../../mol-data/util");
var compiler_1 = require("../../../mol-script/runtime/query/compiler");
var structure_selection_query_1 = require("../../../mol-plugin-state/helpers/structure-selection-query");
var builder_1 = require("../../../mol-script/language/builder");
var mol_task_1 = require("../../../mol-task");
var representation_preset_1 = require("../../../mol-plugin-state/builder/structure/representation-preset");
var mol_state_1 = require("../../../mol-state");
var structure_1 = require("../../../mol-model/structure");
exports.RCSBValidationReport = behavior_1.PluginBehavior.create({
name: 'rcsb-validation-report-prop',
category: 'custom-props',
display: {
name: 'Validation Report',
description: 'Data from wwPDB Validation Report, obtained via RCSB PDB.'
},
ctor: /** @class */ (function (_super) {
(0, tslib_1.__extends)(class_1, _super);
function class_1() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.provider = prop_1.ValidationReportProvider;
_this.labelProvider = {
label: function (loci) {
if (!_this.params.showTooltip)
return;
return [
geometryQualityLabel(loci),
densityFitLabel(loci),
randomCoilIndexLabel(loci)
].filter(function (l) { return !!l; }).join('</br>');
}
};
return _this;
}
class_1.prototype.register = function () {
compiler_1.DefaultQueryRuntimeTable.addCustomProp(this.provider.descriptor);
this.ctx.customModelProperties.register(this.provider, this.params.autoAttach);
this.ctx.managers.lociLabels.addProvider(this.labelProvider);
this.ctx.representation.structure.themes.colorThemeRegistry.add(density_fit_1.DensityFitColorThemeProvider);
this.ctx.representation.structure.themes.colorThemeRegistry.add(geometry_quality_1.GeometryQualityColorThemeProvider);
this.ctx.representation.structure.themes.colorThemeRegistry.add(random_coil_index_1.RandomCoilIndexColorThemeProvider);
this.ctx.representation.structure.registry.add(representation_1.ClashesRepresentationProvider);
this.ctx.query.structure.registry.add(hasClash);
this.ctx.builders.structure.representation.registerPreset(exports.ValidationReportGeometryQualityPreset);
this.ctx.builders.structure.representation.registerPreset(exports.ValidationReportDensityFitPreset);
this.ctx.builders.structure.representation.registerPreset(exports.ValidationReportRandomCoilIndexPreset);
};
class_1.prototype.update = function (p) {
var updated = this.params.autoAttach !== p.autoAttach;
this.params.autoAttach = p.autoAttach;
this.params.showTooltip = p.showTooltip;
this.ctx.customStructureProperties.setDefaultAutoAttach(this.provider.descriptor.name, this.params.autoAttach);
return updated;
};
class_1.prototype.unregister = function () {
compiler_1.DefaultQueryRuntimeTable.removeCustomProp(this.provider.descriptor);
this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
this.ctx.managers.lociLabels.removeProvider(this.labelProvider);
this.ctx.representation.structure.themes.colorThemeRegistry.remove(density_fit_1.DensityFitColorThemeProvider);
this.ctx.representation.structure.themes.colorThemeRegistry.remove(geometry_quality_1.GeometryQualityColorThemeProvider);
this.ctx.representation.structure.themes.colorThemeRegistry.remove(random_coil_index_1.RandomCoilIndexColorThemeProvider);
this.ctx.representation.structure.registry.remove(representation_1.ClashesRepresentationProvider);
this.ctx.query.structure.registry.remove(hasClash);
this.ctx.builders.structure.representation.unregisterPreset(exports.ValidationReportGeometryQualityPreset);
this.ctx.builders.structure.representation.unregisterPreset(exports.ValidationReportDensityFitPreset);
this.ctx.builders.structure.representation.unregisterPreset(exports.ValidationReportRandomCoilIndexPreset);
};
return class_1;
}(behavior_1.PluginBehavior.Handler)),
params: function () { return ({
autoAttach: param_definition_1.ParamDefinition.Boolean(false),
showTooltip: param_definition_1.ParamDefinition.Boolean(true),
baseUrl: param_definition_1.ParamDefinition.Text(prop_1.ValidationReport.DefaultBaseUrl)
}); }
});
//
function geometryQualityLabel(loci) {
if (loci.kind === 'element-loci') {
if (loci.elements.length === 0)
return;
if (loci.elements.length === 1 && int_1.OrderedSet.size(loci.elements[0].indices) === 1) {
var _a = loci.elements[0], unit = _a.unit, indices = _a.indices;
var validationReport = prop_1.ValidationReportProvider.get(unit.model).value;
if (!validationReport)
return;
if (!unit.model.customProperties.hasReference(prop_1.ValidationReportProvider.descriptor))
return;
var bondOutliers_1 = validationReport.bondOutliers, angleOutliers_1 = validationReport.angleOutliers;
var eI = unit.elements[int_1.OrderedSet.start(indices)];
var issues_1 = new Set();
var bonds = bondOutliers_1.index.get(eI);
if (bonds)
bonds.forEach(function (b) { return issues_1.add(bondOutliers_1.data[b].tag); });
var angles = angleOutliers_1.index.get(eI);
if (angles)
angles.forEach(function (a) { return issues_1.add(angleOutliers_1.data[a].tag); });
if (issues_1.size === 0) {
return "Geometry Quality <small>(1 Atom)</small>: no issues";
}
var summary_1 = [];
issues_1.forEach(function (name) { return summary_1.push(name); });
return "Geometry Quality <small>(1 Atom)</small>: " + summary_1.join(', ');
}
var hasValidationReport = false;
var seen_1 = new Set();
var cummulativeIssues_1 = new Map();
var _loop_1 = function (indices, unit) {
var validationReport = prop_1.ValidationReportProvider.get(unit.model).value;
if (!validationReport)
return "continue";
if (!unit.model.customProperties.hasReference(prop_1.ValidationReportProvider.descriptor))
return "continue";
hasValidationReport = true;
var geometryIssues = validationReport.geometryIssues;
var residueIndex = unit.model.atomicHierarchy.residueAtomSegments.index;
var elements = unit.elements;
int_1.OrderedSet.forEach(indices, function (idx) {
var eI = elements[idx];
var rI = residueIndex[eI];
var residueKey = (0, util_1.cantorPairing)(rI, unit.id);
if (!seen_1.has(residueKey)) {
var issues = geometryIssues.get(rI);
if (issues) {
issues.forEach(function (name) {
var count = cummulativeIssues_1.get(name) || 0;
cummulativeIssues_1.set(name, count + 1);
});
}
seen_1.add(residueKey);
}
});
};
for (var _i = 0, _b = loci.elements; _i < _b.length; _i++) {
var _c = _b[_i], indices = _c.indices, unit = _c.unit;
_loop_1(indices, unit);
}
if (!hasValidationReport)
return;
var residueCount = "<small>(" + seen_1.size + " " + (seen_1.size > 1 ? 'Residues' : 'Residue') + ")</small>";
if (cummulativeIssues_1.size === 0) {
return "Geometry Quality " + residueCount + ": no issues";
}
var summary_2 = [];
cummulativeIssues_1.forEach(function (count, name) {
summary_2.push("" + name + (count > 1 ? " \u00D7 " + count : ''));
});
return "Geometry Quality " + residueCount + ": " + summary_2.join(', ');
}
}
function densityFitLabel(loci) {
if (loci.kind === 'element-loci') {
if (loci.elements.length === 0)
return;
var seen_2 = new Set();
var rsrzSeen_1 = new Set();
var rsccSeen_1 = new Set();
var rsrzSum_1 = 0;
var rsccSum_1 = 0;
var _loop_2 = function (indices, unit) {
var validationReport = prop_1.ValidationReportProvider.get(unit.model).value;
if (!validationReport)
return "continue";
if (!unit.model.customProperties.hasReference(prop_1.ValidationReportProvider.descriptor))
return "continue";
var rsrz = validationReport.rsrz, rscc = validationReport.rscc;
var residueIndex = unit.model.atomicHierarchy.residueAtomSegments.index;
var elements = unit.elements;
int_1.OrderedSet.forEach(indices, function (idx) {
var eI = elements[idx];
var rI = residueIndex[eI];
var residueKey = (0, util_1.cantorPairing)(rI, unit.id);
if (!seen_2.has(residueKey)) {
var rsrzValue = rsrz.get(rI);
var rsccValue = rscc.get(rI);
if (rsrzValue !== undefined) {
rsrzSum_1 += rsrzValue;
rsrzSeen_1.add(residueKey);
}
else if (rsccValue !== undefined) {
rsccSum_1 += rsccValue;
rsccSeen_1.add(residueKey);
}
seen_2.add(residueKey);
}
});
};
for (var _i = 0, _a = loci.elements; _i < _a.length; _i++) {
var _b = _a[_i], indices = _b.indices, unit = _b.unit;
_loop_2(indices, unit);
}
if (seen_2.size === 0)
return;
var summary = [];
if (rsrzSeen_1.size) {
var rsrzCount = "<small>(" + rsrzSeen_1.size + " " + (rsrzSeen_1.size > 1 ? 'Residues avg.' : 'Residue') + ")</small>";
var rsrzAvg = rsrzSum_1 / rsrzSeen_1.size;
summary.push("Real-Space R Z-score " + rsrzCount + ": " + rsrzAvg.toFixed(2));
}
if (rsccSeen_1.size) {
var rsccCount = "<small>(" + rsccSeen_1.size + " " + (rsccSeen_1.size > 1 ? 'Residues avg.' : 'Residue') + ")</small>";
var rsccAvg = rsccSum_1 / rsccSeen_1.size;
summary.push("Real-Space Correlation Coefficient " + rsccCount + ": " + rsccAvg.toFixed(2));
}
if (summary.length) {
return summary.join('</br>');
}
}
}
function randomCoilIndexLabel(loci) {
if (loci.kind === 'element-loci') {
if (loci.elements.length === 0)
return;
var seen_3 = new Set();
var sum_1 = 0;
var _loop_3 = function (indices, unit) {
var validationReport = prop_1.ValidationReportProvider.get(unit.model).value;
if (!validationReport)
return "continue";
if (!unit.model.customProperties.hasReference(prop_1.ValidationReportProvider.descriptor))
return "continue";
var rci = validationReport.rci;
var residueIndex = unit.model.atomicHierarchy.residueAtomSegments.index;
var elements = unit.elements;
int_1.OrderedSet.forEach(indices, function (idx) {
var eI = elements[idx];
var rI = residueIndex[eI];
var residueKey = (0, util_1.cantorPairing)(rI, unit.id);
if (!seen_3.has(residueKey)) {
var rciValue = rci.get(rI);
if (rciValue !== undefined) {
sum_1 += rciValue;
seen_3.add(residueKey);
}
}
});
};
for (var _i = 0, _a = loci.elements; _i < _a.length; _i++) {
var _b = _a[_i], indices = _b.indices, unit = _b.unit;
_loop_3(indices, unit);
}
if (seen_3.size === 0)
return;
var residueCount = "<small>(" + seen_3.size + " " + (seen_3.size > 1 ? 'Residues avg.' : 'Residue') + ")</small>";
var rciAvg = sum_1 / seen_3.size;
return "Random Coil Index " + residueCount + ": " + rciAvg.toFixed(2);
}
}
//
var hasClash = (0, structure_selection_query_1.StructureSelectionQuery)('Residues with Clashes', builder_1.MolScriptBuilder.struct.modifier.union([
builder_1.MolScriptBuilder.struct.modifier.wholeResidues([
builder_1.MolScriptBuilder.struct.modifier.union([
builder_1.MolScriptBuilder.struct.generator.atomGroups({
'chain-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.ammp('objectPrimitive'), 'atomistic']),
'atom-test': prop_1.ValidationReport.symbols.hasClash.symbol(),
})
])
])
]), {
description: 'Select residues with clashes in the wwPDB validation report.',
category: structure_selection_query_1.StructureSelectionCategory.Residue,
ensureCustomProperties: function (ctx, structure) {
return prop_1.ValidationReportProvider.attach(ctx, structure.models[0]);
}
});
//
exports.ValidationReportGeometryQualityPreset = (0, representation_preset_1.StructureRepresentationPresetProvider)({
id: 'preset-structure-representation-rcsb-validation-report-geometry-uality',
display: {
name: 'Validation Report (Geometry Quality)', group: 'Annotation',
description: 'Color structure based on geometry quality; show geometry clashes. Data from wwPDB Validation Report, obtained via RCSB PDB.'
},
isApplicable: function (a) {
return a.data.models.length === 1 && prop_1.ValidationReport.isApplicable(a.data.models[0]);
},
params: function () { return representation_preset_1.StructureRepresentationPresetProvider.CommonParams; },
apply: function (ref, params, plugin) {
var _a;
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var structureCell, structure, colorTheme, _b, components, representations, clashes, _c, update, builder, typeParams, color, clashesBallAndStick, clashesRepr;
var _this = this;
return (0, tslib_1.__generator)(this, function (_d) {
switch (_d.label) {
case 0:
structureCell = mol_state_1.StateObjectRef.resolveAndCheck(plugin.state.data, ref);
structure = (_a = structureCell === null || structureCell === void 0 ? void 0 : structureCell.obj) === null || _a === void 0 ? void 0 : _a.data;
if (!structureCell || !structure)
return [2 /*return*/, {}];
return [4 /*yield*/, plugin.runTask(mol_task_1.Task.create('Validation Report', function (runtime) { return (0, tslib_1.__awaiter)(_this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, prop_1.ValidationReportProvider.attach({ runtime: runtime, assetManager: plugin.managers.asset }, structure.models[0])];
case 1:
_a.sent();
return [2 /*return*/];
}
});
}); }))];
case 1:
_d.sent();
colorTheme = geometry_quality_1.GeometryQualityColorThemeProvider.name;
return [4 /*yield*/, representation_preset_1.PresetStructureRepresentations.auto.apply(ref, (0, tslib_1.__assign)((0, tslib_1.__assign)({}, params), { theme: { globalName: colorTheme, focus: { name: colorTheme } } }), plugin)];
case 2:
_b = _d.sent(), components = _b.components, representations = _b.representations;
return [4 /*yield*/, plugin.builders.structure.tryCreateComponentFromExpression(structureCell, hasClash.expression, 'clashes', { label: 'Clashes' })];
case 3:
clashes = _d.sent();
_c = representation_preset_1.StructureRepresentationPresetProvider.reprBuilder(plugin, params), update = _c.update, builder = _c.builder, typeParams = _c.typeParams, color = _c.color;
if (representations) {
clashesBallAndStick = builder.buildRepresentation(update, clashes, { type: 'ball-and-stick', typeParams: typeParams, color: colorTheme }, { tag: 'clashes-ball-and-stick' });
clashesRepr = builder.buildRepresentation(update, clashes, { type: representation_1.ClashesRepresentationProvider.name, typeParams: typeParams, color: color }, { tag: 'clashes-repr' });
}
return [4 /*yield*/, update.commit({ revertOnError: true })];
case 4:
_d.sent();
return [2 /*return*/, { components: (0, tslib_1.__assign)((0, tslib_1.__assign)({}, components), { clashes: clashes }), representations: (0, tslib_1.__assign)((0, tslib_1.__assign)({}, representations), { clashesBallAndStick: clashesBallAndStick, clashesRepr: clashesRepr }) }];
}
});
});
}
});
exports.ValidationReportDensityFitPreset = (0, representation_preset_1.StructureRepresentationPresetProvider)({
id: 'preset-structure-representation-rcsb-validation-report-density-fit',
display: {
name: 'Validation Report (Density Fit)', group: 'Annotation',
description: 'Color structure based on density fit. Data from wwPDB Validation Report, obtained via RCSB PDB.'
},
isApplicable: function (a) {
return a.data.models.length === 1 && prop_1.ValidationReport.isApplicable(a.data.models[0]) && structure_1.Model.isFromXray(a.data.models[0]) && structure_1.Model.probablyHasDensityMap(a.data.models[0]);
},
params: function () { return representation_preset_1.StructureRepresentationPresetProvider.CommonParams; },
apply: function (ref, params, plugin) {
var _a;
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var structureCell, structure, colorTheme;
var _this = this;
return (0, tslib_1.__generator)(this, function (_b) {
switch (_b.label) {
case 0:
structureCell = mol_state_1.StateObjectRef.resolveAndCheck(plugin.state.data, ref);
structure = (_a = structureCell === null || structureCell === void 0 ? void 0 : structureCell.obj) === null || _a === void 0 ? void 0 : _a.data;
if (!structureCell || !structure)
return [2 /*return*/, {}];
return [4 /*yield*/, plugin.runTask(mol_task_1.Task.create('Validation Report', function (runtime) { return (0, tslib_1.__awaiter)(_this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, prop_1.ValidationReportProvider.attach({ runtime: runtime, assetManager: plugin.managers.asset }, structure.models[0])];
case 1:
_a.sent();
return [2 /*return*/];
}
});
}); }))];
case 1:
_b.sent();
colorTheme = density_fit_1.DensityFitColorThemeProvider.name;
return [4 /*yield*/, representation_preset_1.PresetStructureRepresentations.auto.apply(ref, (0, tslib_1.__assign)((0, tslib_1.__assign)({}, params), { theme: { globalName: colorTheme, focus: { name: colorTheme } } }), plugin)];
case 2: return [2 /*return*/, _b.sent()];
}
});
});
}
});
exports.ValidationReportRandomCoilIndexPreset = (0, representation_preset_1.StructureRepresentationPresetProvider)({
id: 'preset-structure-representation-rcsb-validation-report-random-coil-index',
display: {
name: 'Validation Report (Random Coil Index)', group: 'Annotation',
description: 'Color structure based on Random Coil Index. Data from wwPDB Validation Report, obtained via RCSB PDB.'
},
isApplicable: function (a) {
return a.data.models.length === 1 && prop_1.ValidationReport.isApplicable(a.data.models[0]) && structure_1.Model.isFromNmr(a.data.models[0]);
},
params: function () { return representation_preset_1.StructureRepresentationPresetProvider.CommonParams; },
apply: function (ref, params, plugin) {
var _a;
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var structureCell, structure, colorTheme;
var _this = this;
return (0, tslib_1.__generator)(this, function (_b) {
switch (_b.label) {
case 0:
structureCell = mol_state_1.StateObjectRef.resolveAndCheck(plugin.state.data, ref);
structure = (_a = structureCell === null || structureCell === void 0 ? void 0 : structureCell.obj) === null || _a === void 0 ? void 0 : _a.data;
if (!structureCell || !structure)
return [2 /*return*/, {}];
return [4 /*yield*/, plugin.runTask(mol_task_1.Task.create('Validation Report', function (runtime) { return (0, tslib_1.__awaiter)(_this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, prop_1.ValidationReportProvider.attach({ runtime: runtime, assetManager: plugin.managers.asset }, structure.models[0])];
case 1:
_a.sent();
return [2 /*return*/];
}
});
}); }))];
case 1:
_b.sent();
colorTheme = random_coil_index_1.RandomCoilIndexColorThemeProvider.name;
return [4 /*yield*/, representation_preset_1.PresetStructureRepresentations.auto.apply(ref, (0, tslib_1.__assign)((0, tslib_1.__assign)({}, params), { theme: { globalName: colorTheme, focus: { name: colorTheme } } }), plugin)];
case 2: return [2 /*return*/, _b.sent()];
}
});
});
}
});
//# sourceMappingURL=behavior.js.map