pdbe-molstar 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/pdbe-molstar-component.js +2 -2
- package/build/pdbe-molstar-light.css +1 -1
- package/build/pdbe-molstar-plugin.js +2 -2
- package/build/pdbe-molstar-plugin.js.LICENSE.txt +1 -1
- package/build/pdbe-molstar.css +1 -1
- package/lib/alphafold-transparency.js +7 -8
- package/lib/extensions/complexes/coloring.d.ts +15 -0
- package/lib/extensions/complexes/coloring.js +20 -9
- package/lib/extensions/complexes/index.d.ts +32 -17
- package/lib/extensions/complexes/index.js +24 -48
- package/lib/extensions/complexes/superpose-by-biggest-chain.d.ts +13 -15
- package/lib/extensions/complexes/superpose-by-biggest-chain.js +62 -56
- package/lib/extensions/complexes/superpose-by-sequence-alignment.d.ts +10 -0
- package/lib/extensions/complexes/superpose-by-sequence-alignment.js +181 -0
- package/lib/helpers.d.ts +11 -1
- package/lib/helpers.js +11 -5
- package/lib/plugin-custom-state.d.ts +0 -2
- package/lib/sequence-color/behavior.d.ts +5 -0
- package/lib/sequence-color/behavior.js +54 -0
- package/lib/sequence-color/color.d.ts +11 -0
- package/lib/sequence-color/color.js +58 -0
- package/lib/sequence-color/prop.d.ts +38 -0
- package/lib/sequence-color/prop.js +38 -0
- package/lib/superposition.d.ts +2 -2
- package/lib/superposition.js +41 -60
- package/lib/ui/alphafold-superposition.js +2 -2
- package/lib/viewer.js +1 -1
- package/package.json +1 -1
- package/lib/superposition-sifts-mapping.d.ts +0 -22
- package/lib/superposition-sifts-mapping.js +0 -153
package/build/pdbe-molstar.css
CHANGED
|
@@ -13,7 +13,8 @@ const compiler_1 = require("molstar/lib/mol-script/runtime/query/compiler");
|
|
|
13
13
|
const mol_state_1 = require("molstar/lib/mol-state");
|
|
14
14
|
const transparency_1 = require("molstar/lib/mol-theme/transparency");
|
|
15
15
|
const TransparencyManagerTag = 'transparency-controls';
|
|
16
|
-
|
|
16
|
+
/** Select part of the structure with pLDDT <= score. */
|
|
17
|
+
function getLociBelowPLDDT(score, contextData) {
|
|
17
18
|
const queryExp = builder_1.MolScriptBuilder.struct.modifier.union([
|
|
18
19
|
builder_1.MolScriptBuilder.struct.modifier.wholeResidues([
|
|
19
20
|
builder_1.MolScriptBuilder.struct.modifier.union([
|
|
@@ -28,13 +29,11 @@ function getLociByPLDDT(score, contextData) {
|
|
|
28
29
|
const sel = query(new structure_1.QueryContext(contextData));
|
|
29
30
|
return structure_1.StructureSelection.toLociWithSourceUnits(sel);
|
|
30
31
|
}
|
|
31
|
-
function applyAFTransparency(
|
|
32
|
-
return tslib_1.__awaiter(this,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}), { canUndo: 'Apply Transparency' });
|
|
37
|
-
});
|
|
32
|
+
function applyAFTransparency(plugin, structure, transparency, pLDDT = 70) {
|
|
33
|
+
return plugin.dataTransaction((ctx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
const loci = getLociBelowPLDDT(pLDDT, structure.cell.obj.data);
|
|
35
|
+
yield setStructureTransparency(plugin, structure.components, transparency, loci);
|
|
36
|
+
}), { canUndo: 'Apply Transparency' });
|
|
38
37
|
}
|
|
39
38
|
function setStructureTransparency(plugin, components, value, loci, types) {
|
|
40
39
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
@@ -9,6 +9,13 @@ export declare function colorComponents(viewer: PDBeMolstarPlugin, params: {
|
|
|
9
9
|
coreColor?: string;
|
|
10
10
|
componentColors?: string[];
|
|
11
11
|
}): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
Coloring - subcomplexes:
|
|
14
|
+
- base common -> by entity, lighter
|
|
15
|
+
- base additional -> gray, lighter
|
|
16
|
+
- sub common -> by entity, darker
|
|
17
|
+
- sub additional -> gray, darker (these are all unmapped components, includes antibodies and ligands)
|
|
18
|
+
*/
|
|
12
19
|
export declare function colorSubcomplex(viewer: PDBeMolstarPlugin, params: {
|
|
13
20
|
baseStructId?: string;
|
|
14
21
|
otherStructId?: string;
|
|
@@ -23,6 +30,14 @@ export declare function colorSubcomplex(viewer: PDBeMolstarPlugin, params: {
|
|
|
23
30
|
coreColor?: string;
|
|
24
31
|
componentColors?: string[];
|
|
25
32
|
}): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
Coloring - supercomplexes:
|
|
35
|
+
- base common -> gray, lighter
|
|
36
|
+
- base additional -> unmapped color, lighter (these are all unmapped components, includes antibodies and ligands)
|
|
37
|
+
- super common -> gray, darker
|
|
38
|
+
- super additional mapped -> by entity, darker
|
|
39
|
+
- super additional unmapped -> unmapped color, darker
|
|
40
|
+
*/
|
|
26
41
|
export declare function colorSupercomplex(viewer: PDBeMolstarPlugin, params: {
|
|
27
42
|
baseStructId?: string;
|
|
28
43
|
otherStructId?: string;
|
|
@@ -7,18 +7,14 @@ const tslib_1 = require("tslib");
|
|
|
7
7
|
const color_1 = require("molstar/lib/mol-util/color");
|
|
8
8
|
const helpers_1 = require("../../helpers");
|
|
9
9
|
const DEFAULT_CORE_COLOR = '#d8d8d8';
|
|
10
|
-
const DEFAULT_UNMAPPED_COLOR = '#
|
|
10
|
+
const DEFAULT_UNMAPPED_COLOR = '#f000f0';
|
|
11
11
|
const DEFAULT_COMPONENT_COLORS = [
|
|
12
|
-
'#1b9e77', '#d95f02', '#7570b3', '#
|
|
13
|
-
'#
|
|
14
|
-
'#
|
|
15
|
-
'#e5c494', '#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', // Set-2
|
|
12
|
+
'#1b9e77', '#d95f02', '#7570b3', '#66a61e', '#e6ab02', '#a6761d', // Dark-2 without gray and magenta
|
|
13
|
+
'#1f77b4', '#2ca02c', '#d62728', '#927ba7', '#8c564b', '#e377c2', '#bcbd22', '#17becf', // More non-conflicting colors from other palettes
|
|
14
|
+
'#fc8d62', '#9eb9f3', '#ff9da7', '#ffff33', '#8be0a4', '#e15759', '#c69fbb', '#76b7b2', // More non-conflicting colors from other palettes
|
|
16
15
|
];
|
|
17
|
-
// TODO compare color variants:
|
|
18
|
-
// http://127.0.0.1:1339/complexes-demo.html?complexId=PDB-CPX-159519&unmappedColor=%23222222
|
|
19
|
-
// http://127.0.0.1:1339/complexes-demo.html?complexId=PDB-CPX-159519&unmappedColor=%23ff0000
|
|
20
16
|
/** How much lighter/darker colors should be for the base/other complex */
|
|
21
|
-
const COLOR_ADJUSTMENT_STRENGTH = 0.
|
|
17
|
+
const COLOR_ADJUSTMENT_STRENGTH = 0.8;
|
|
22
18
|
function colorComponents(viewer, params) {
|
|
23
19
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24
20
|
const { coreColor = DEFAULT_CORE_COLOR, componentColors = DEFAULT_COMPONENT_COLORS, components, mappings = {} } = params;
|
|
@@ -34,6 +30,13 @@ function colorComponents(viewer, params) {
|
|
|
34
30
|
yield viewer.visual.tooltips({ data: tooltipData, structureId: params.structId });
|
|
35
31
|
});
|
|
36
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
Coloring - subcomplexes:
|
|
35
|
+
- base common -> by entity, lighter
|
|
36
|
+
- base additional -> gray, lighter
|
|
37
|
+
- sub common -> by entity, darker
|
|
38
|
+
- sub additional -> gray, darker (these are all unmapped components, includes antibodies and ligands)
|
|
39
|
+
*/
|
|
37
40
|
function colorSubcomplex(viewer, params) {
|
|
38
41
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
39
42
|
const { coreColor = DEFAULT_CORE_COLOR, componentColors = DEFAULT_COMPONENT_COLORS, baseComponents, baseMappings = {}, otherMappings = {} } = params;
|
|
@@ -65,6 +68,14 @@ function colorSubcomplex(viewer, params) {
|
|
|
65
68
|
}
|
|
66
69
|
});
|
|
67
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
Coloring - supercomplexes:
|
|
73
|
+
- base common -> gray, lighter
|
|
74
|
+
- base additional -> unmapped color, lighter (these are all unmapped components, includes antibodies and ligands)
|
|
75
|
+
- super common -> gray, darker
|
|
76
|
+
- super additional mapped -> by entity, darker
|
|
77
|
+
- super additional unmapped -> unmapped color, darker
|
|
78
|
+
*/
|
|
68
79
|
function colorSupercomplex(viewer, params) {
|
|
69
80
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
70
81
|
const { coreColor = DEFAULT_CORE_COLOR, unmappedColor = DEFAULT_UNMAPPED_COLOR, componentColors = DEFAULT_COMPONENT_COLORS, baseMappings = {}, otherMappings = {} } = params;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/** Helper functions to allow superposition of complexes */
|
|
2
|
-
import {
|
|
2
|
+
import { MinimizeRmsd } from 'molstar/lib/mol-math/linear-algebra/3d/minimize-rmsd';
|
|
3
3
|
import { PDBeMolstarPlugin } from '../..';
|
|
4
4
|
import { QueryParam } from '../../helpers';
|
|
5
|
-
import { SuperpositionResult } from './superpose-by-biggest-chain';
|
|
6
5
|
export * as Coloring from './coloring';
|
|
6
|
+
/** Parameters to `loadComplexSuperposition` */
|
|
7
7
|
export interface LoadComplexSuperpositionParams {
|
|
8
8
|
/** PDB identifier of complex structure */
|
|
9
9
|
pdbId: string;
|
|
@@ -27,29 +27,44 @@ export interface LoadComplexSuperpositionParams {
|
|
|
27
27
|
unmappedColor?: string;
|
|
28
28
|
/** List of colors for coloring unique entities. */
|
|
29
29
|
componentColors?: string[];
|
|
30
|
-
/** Optional specification of which parts of the base complex structure belong to individual Uniprot/Rfam accessions (will be inferred from mmCIF atom_site if not provided)
|
|
30
|
+
/** Optional specification of which parts of the base complex structure belong to individual Uniprot/Rfam accessions (will be inferred from mmCIF atom_site if not provided).
|
|
31
|
+
* It is recommended to provide this for nucleic acids as they don't have mapping in atom_site. */
|
|
31
32
|
baseMappings?: {
|
|
32
33
|
[accession: string]: QueryParam[];
|
|
33
34
|
};
|
|
34
|
-
/** Optional specification of which parts of the other complex structure belong to individual Uniprot/Rfam accessions (will be inferred from mmCIF atom_site if not provided)
|
|
35
|
+
/** Optional specification of which parts of the other complex structure belong to individual Uniprot/Rfam accessions (will be inferred from mmCIF atom_site if not provided).
|
|
36
|
+
* It is recommended to provide this for nucleic acids as they don't have mapping in atom_site. */
|
|
35
37
|
otherMappings?: {
|
|
36
38
|
[accession: string]: QueryParam[];
|
|
37
39
|
};
|
|
38
|
-
/** Superposition method */
|
|
39
|
-
method?: 'biggest-matched-chain' | 'molstar-builtin';
|
|
40
40
|
}
|
|
41
|
-
/**
|
|
42
|
-
export
|
|
41
|
+
/** Result type of `loadComplexSuperposition` */
|
|
42
|
+
export interface LoadComplexSuperpositionResult {
|
|
43
43
|
/** Structure identifier of the newly loaded complex structure, to refer to this structure later */
|
|
44
44
|
id: string;
|
|
45
|
-
/**
|
|
46
|
-
|
|
47
|
-
/** Superposition RMSD and tranform (if status is 'success') */
|
|
48
|
-
superposition: (import("molstar/lib/mol-math/linear-algebra/3d/minimize-rmsd").MinimizeRmsd.Result & {
|
|
49
|
-
nAlignedElements: number;
|
|
50
|
-
}) | undefined;
|
|
45
|
+
/** Superposition RMSD, number of aligned residues, and tranform; if superposition was successful */
|
|
46
|
+
superposition: SuperpositionResult | undefined;
|
|
51
47
|
/** Function that deletes the newly loaded complex structure */
|
|
52
48
|
delete: () => Promise<void>;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
export
|
|
49
|
+
}
|
|
50
|
+
/** Temporary type until `nAlignedElements` gets into `MinimizeRmsd.Result` in core Molstar */
|
|
51
|
+
export interface SuperpositionResult extends MinimizeRmsd.Result {
|
|
52
|
+
nAlignedElements: number;
|
|
53
|
+
method: 'uniprot-numbering' | 'sequence-alignment';
|
|
54
|
+
accession: string;
|
|
55
|
+
}
|
|
56
|
+
/** Load a structure, superpose onto the main structure based on Uniprot residue numbers (or seq alignment if numbers not available),
|
|
57
|
+
* and optionally apply coloring to show common/additional components.
|
|
58
|
+
*
|
|
59
|
+
* **Superposition method:**
|
|
60
|
+
* Complexes are superposed based on the largest common component (measured the by number of residues) with a UniProt mapping (taken from atom_site mmCIF category).
|
|
61
|
+
* In case there are no common components with Uniprot mapping, the largest common component with an Rfam mapping is used (taken from `baseMappings` and `otherMappings` parameters).
|
|
62
|
+
* Residue-residue correspondence is determined by UniProt residue numbers (for UniProt mappings) or by sequence alignment (for Rfam mappings).
|
|
63
|
+
*
|
|
64
|
+
* **Coloring - subcomplexes:**
|
|
65
|
+
* Common components are colored by entity; additional components are gray. Components in the subcomplex are slightly darkened.
|
|
66
|
+
*
|
|
67
|
+
* **Coloring - supercomplexes:**
|
|
68
|
+
* Common components are gray; mapped additional components are colored by entity; unmapped additional components are magenta. Components in the supercomplex are slightly darkened.
|
|
69
|
+
*/
|
|
70
|
+
export declare function loadComplexSuperposition(viewer: PDBeMolstarPlugin, params: LoadComplexSuperpositionParams): Promise<LoadComplexSuperpositionResult>;
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.Coloring = void 0;
|
|
5
5
|
exports.loadComplexSuperposition = loadComplexSuperposition;
|
|
6
|
-
exports.superposeStructuresByMolstarDefault = superposeStructuresByMolstarDefault;
|
|
7
6
|
const tslib_1 = require("tslib");
|
|
8
|
-
const superposition_sifts_mapping_1 = require("molstar/lib/mol-model/structure/structure/util/superposition-sifts-mapping");
|
|
9
7
|
const commands_1 = require("molstar/lib/mol-plugin/commands");
|
|
10
8
|
const sleep_1 = require("molstar/lib/mol-util/sleep");
|
|
11
9
|
const __1 = require("../..");
|
|
@@ -13,12 +11,26 @@ const helpers_1 = require("../../helpers");
|
|
|
13
11
|
const superposition_1 = require("../../superposition");
|
|
14
12
|
const Coloring = tslib_1.__importStar(require("./coloring"));
|
|
15
13
|
const superpose_by_biggest_chain_1 = require("./superpose-by-biggest-chain");
|
|
14
|
+
const superpose_by_sequence_alignment_1 = require("./superpose-by-sequence-alignment");
|
|
16
15
|
exports.Coloring = tslib_1.__importStar(require("./coloring"));
|
|
17
|
-
/** Load a structure, superpose onto the main structure based on Uniprot residue numbers
|
|
16
|
+
/** Load a structure, superpose onto the main structure based on Uniprot residue numbers (or seq alignment if numbers not available),
|
|
17
|
+
* and optionally apply coloring to show common/additional components.
|
|
18
|
+
*
|
|
19
|
+
* **Superposition method:**
|
|
20
|
+
* Complexes are superposed based on the largest common component (measured the by number of residues) with a UniProt mapping (taken from atom_site mmCIF category).
|
|
21
|
+
* In case there are no common components with Uniprot mapping, the largest common component with an Rfam mapping is used (taken from `baseMappings` and `otherMappings` parameters).
|
|
22
|
+
* Residue-residue correspondence is determined by UniProt residue numbers (for UniProt mappings) or by sequence alignment (for Rfam mappings).
|
|
23
|
+
*
|
|
24
|
+
* **Coloring - subcomplexes:**
|
|
25
|
+
* Common components are colored by entity; additional components are gray. Components in the subcomplex are slightly darkened.
|
|
26
|
+
*
|
|
27
|
+
* **Coloring - supercomplexes:**
|
|
28
|
+
* Common components are gray; mapped additional components are colored by entity; unmapped additional components are magenta. Components in the supercomplex are slightly darkened.
|
|
29
|
+
*/
|
|
18
30
|
function loadComplexSuperposition(viewer, params) {
|
|
19
31
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
20
32
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
21
|
-
const { pdbId, assemblyId, animationDuration = 250, coloring, baseComponents, otherComponents, baseMappings, otherMappings, coreColor, unmappedColor, componentColors
|
|
33
|
+
const { pdbId, assemblyId, animationDuration = 250, coloring, baseComponents, otherComponents, baseMappings, otherMappings, coreColor, unmappedColor, componentColors } = params;
|
|
22
34
|
const baseStructId = __1.PDBeMolstarPlugin.MAIN_STRUCTURE_ID;
|
|
23
35
|
const otherStructId = (_a = params.id) !== null && _a !== void 0 ? _a : `${pdbId}_${assemblyId}`;
|
|
24
36
|
// Apply coloring to base structure
|
|
@@ -45,12 +57,17 @@ function loadComplexSuperposition(viewer, params) {
|
|
|
45
57
|
if (!otherStruct)
|
|
46
58
|
throw new Error('Mobile structure not loaded');
|
|
47
59
|
// Superpose other structure on base structure
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
60
|
+
let superposition = (0, superpose_by_biggest_chain_1.superposeByBiggestCommonChain)(baseStruct, otherStruct, baseComponents, otherComponents);
|
|
61
|
+
if (!superposition) {
|
|
62
|
+
console.log(`UniProt-based superposition method failed, trying sequence alignment superposition (RNAs)`);
|
|
63
|
+
superposition = (0, superpose_by_sequence_alignment_1.superposeBySequenceAlignment)(baseStruct, otherStruct, baseMappings !== null && baseMappings !== void 0 ? baseMappings : {}, otherMappings !== null && otherMappings !== void 0 ? otherMappings : {});
|
|
64
|
+
}
|
|
51
65
|
if (superposition) {
|
|
52
66
|
yield (0, superposition_1.transform)(viewer.plugin, viewer.getStructure(otherStructId).cell, superposition.bTransform);
|
|
53
67
|
}
|
|
68
|
+
else {
|
|
69
|
+
console.log(`Sequence alignment superposition method failed, leaving unsuperposed`);
|
|
70
|
+
}
|
|
54
71
|
// Apply coloring to other structure
|
|
55
72
|
if (coloring === 'subcomplex') {
|
|
56
73
|
yield Coloring.colorSubcomplex(viewer, { otherStructId, baseComponents: baseComponents, otherComponents: otherComponents, baseMappings, otherMappings, coreColor, componentColors });
|
|
@@ -74,50 +91,9 @@ function loadComplexSuperposition(viewer, params) {
|
|
|
74
91
|
// Reveal new structure
|
|
75
92
|
yield viewer.visual.structureVisibility(otherStructId, true);
|
|
76
93
|
return {
|
|
77
|
-
/** Structure identifier of the newly loaded complex structure, to refer to this structure later */
|
|
78
94
|
id: otherStructId,
|
|
79
|
-
/** Status of pairwise superposition ('success' / 'zero-overlap' / 'failed') */
|
|
80
|
-
status,
|
|
81
|
-
/** Superposition RMSD and tranform (if status is 'success') */
|
|
82
95
|
superposition,
|
|
83
|
-
/** Function that deletes the newly loaded complex structure */
|
|
84
96
|
delete: () => viewer.deleteStructure(otherStructId),
|
|
85
97
|
};
|
|
86
98
|
});
|
|
87
99
|
}
|
|
88
|
-
/** Superpose mobile structure onto static structure, based on Uniprot residue numbers. */
|
|
89
|
-
function superposeStructuresByMolstarDefault(staticStruct, mobileStruct) {
|
|
90
|
-
var _a;
|
|
91
|
-
const aln = (0, superposition_sifts_mapping_1.alignAndSuperposeWithSIFTSMapping)([staticStruct, mobileStruct], { traceOnly: true });
|
|
92
|
-
const superposition = (_a = aln.entries.find(e => e.pivot === 0 && e.other === 1)) === null || _a === void 0 ? void 0 : _a.transform;
|
|
93
|
-
if (superposition) {
|
|
94
|
-
return { status: 'success', superposition: Object.assign(Object.assign({}, superposition), { nAlignedElements: Number.NaN }) };
|
|
95
|
-
}
|
|
96
|
-
else if (aln.zeroOverlapPairs.find(e => e[0] === 0 && e[1] === 1)) {
|
|
97
|
-
return { status: 'zero-overlap', superposition: undefined };
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
return { status: 'failed', superposition: undefined };
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
/*
|
|
104
|
-
Coloring - subcomplexes:
|
|
105
|
-
- base common -> by entity, lighter
|
|
106
|
-
- base additional -> gray, lighter
|
|
107
|
-
- sub common -> by entity, darker
|
|
108
|
-
- sub additional -> gray, darker (these are all unmapped components, includes antibodies and ligands)
|
|
109
|
-
|
|
110
|
-
-> Colors can be assigned based on base complex and applied to subcomplex
|
|
111
|
-
|
|
112
|
-
Coloring - supercomplexes:
|
|
113
|
-
- base common -> gray, lighter
|
|
114
|
-
- base additional -> unmapped color, lighter (these are all unmapped components, includes antibodies and ligands)
|
|
115
|
-
- super common -> gray, darker
|
|
116
|
-
- super additional mapped -> by entity, darker
|
|
117
|
-
- super additional unmapped -> unmapped color, darker
|
|
118
|
-
|
|
119
|
-
-> Colors can be assigned based on supercomplex complex, consistency between supercomplexes is probably not necessary
|
|
120
|
-
|
|
121
|
-
-> For both subcomplexes and supercomplexes, colors could be assigned based on UniprotID hash -> database-wide consistency but complexes with similar-color components will occur
|
|
122
|
-
|
|
123
|
-
*/
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { MinimizeRmsd } from 'molstar/lib/mol-math/linear-algebra/3d/minimize-rmsd';
|
|
2
1
|
import { Structure } from 'molstar/lib/mol-model/structure';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { SuperpositionResult } from './index';
|
|
3
|
+
/** Superpose structures based on the largest common component (measured the by number of residues) with a UniProt mapping (taken from atom_site mmCIF category).
|
|
4
|
+
* Residue-residue correspondence is determined by UniProt residue numbers.
|
|
5
|
+
* This differs from UniProt-based superposition in core Molstar (`alignAndSuperposeWithSIFTSMapping`) which takes all components (regardless of their spacial arrangement). */
|
|
6
|
+
export declare function superposeByBiggestCommonChain(structA: Structure, structB: Structure, allowedComponentsA: string[] | undefined, allowedComponentsB: string[] | undefined): SuperpositionResult | undefined;
|
|
7
|
+
export interface SortedAccessionsAndUnits<T extends object = object> {
|
|
8
|
+
accessions: string[];
|
|
9
|
+
units: {
|
|
10
|
+
[accession: string]: ({
|
|
11
|
+
unitId: string;
|
|
12
|
+
size: number;
|
|
13
|
+
} & T)[];
|
|
7
14
|
};
|
|
8
|
-
}
|
|
9
|
-
status: 'zero-overlap';
|
|
10
|
-
superposition: undefined;
|
|
11
|
-
} | {
|
|
12
|
-
status: 'failed';
|
|
13
|
-
superposition: undefined;
|
|
14
|
-
};
|
|
15
|
-
/** Status of pairwise superposition (success = superposed, zero-overlap = failed to superpose because the two structures have no matchable elements, failed = failed to superpose for other reasons) */
|
|
16
|
-
export type SuperpositionStatus = SuperpositionResult['status'];
|
|
17
|
-
export declare function superposeStructuresByBiggestCommonChain(structA: Structure, structB: Structure, allowedComponentsA: string[] | undefined, allowedComponentsB: string[] | undefined): SuperpositionResult;
|
|
15
|
+
}
|
|
@@ -1,8 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.superposeByBiggestCommonChain = superposeByBiggestCommonChain;
|
|
4
4
|
const minimize_rmsd_1 = require("molstar/lib/mol-math/linear-algebra/3d/minimize-rmsd");
|
|
5
5
|
const mmcif_1 = require("molstar/lib/mol-model-formats/structure/mmcif");
|
|
6
|
+
/** Superpose structures based on the largest common component (measured the by number of residues) with a UniProt mapping (taken from atom_site mmCIF category).
|
|
7
|
+
* Residue-residue correspondence is determined by UniProt residue numbers.
|
|
8
|
+
* This differs from UniProt-based superposition in core Molstar (`alignAndSuperposeWithSIFTSMapping`) which takes all components (regardless of their spacial arrangement). */
|
|
9
|
+
function superposeByBiggestCommonChain(structA, structB, allowedComponentsA, allowedComponentsB) {
|
|
10
|
+
const indexA = extractUniprotIndex(structA, allowedComponentsA);
|
|
11
|
+
const indexB = extractUniprotIndex(structB, allowedComponentsB);
|
|
12
|
+
const bestMatch = bestUniprotMatch(indexA, indexB);
|
|
13
|
+
if (!bestMatch) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
const unitA = structA.unitMap.get(Number(bestMatch.unitA));
|
|
17
|
+
const unitB = structB.unitMap.get(Number(bestMatch.unitB));
|
|
18
|
+
const unitIndexA = indexA[bestMatch.accession][bestMatch.unitA];
|
|
19
|
+
const unitIndexB = indexB[bestMatch.accession][bestMatch.unitB];
|
|
20
|
+
const positionsA = minimize_rmsd_1.MinimizeRmsd.Positions.empty(bestMatch.nMatchedElements);
|
|
21
|
+
const positionsB = minimize_rmsd_1.MinimizeRmsd.Positions.empty(bestMatch.nMatchedElements);
|
|
22
|
+
let i = 0;
|
|
23
|
+
for (const unpNum in unitIndexA.atomMap) {
|
|
24
|
+
const iAtomB = unitIndexB.atomMap[unpNum];
|
|
25
|
+
if (iAtomB === undefined)
|
|
26
|
+
continue;
|
|
27
|
+
const iAtomA = unitIndexA.atomMap[unpNum];
|
|
28
|
+
positionsA.x[i] = unitA.conformation.coordinates.x[iAtomA];
|
|
29
|
+
positionsA.y[i] = unitA.conformation.coordinates.y[iAtomA];
|
|
30
|
+
positionsA.z[i] = unitA.conformation.coordinates.z[iAtomA];
|
|
31
|
+
positionsB.x[i] = unitB.conformation.coordinates.x[iAtomB];
|
|
32
|
+
positionsB.y[i] = unitB.conformation.coordinates.y[iAtomB];
|
|
33
|
+
positionsB.z[i] = unitB.conformation.coordinates.z[iAtomB];
|
|
34
|
+
i++;
|
|
35
|
+
}
|
|
36
|
+
const superposition = minimize_rmsd_1.MinimizeRmsd.compute({ a: positionsA, b: positionsB });
|
|
37
|
+
if (!isNaN(superposition.rmsd)) {
|
|
38
|
+
return Object.assign(Object.assign({}, superposition), { nAlignedElements: bestMatch.nMatchedElements, method: 'uniprot-numbering', accession: bestMatch.accession });
|
|
39
|
+
// TODO remove explicit nAlignedElements, once in core Molstar
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
6
45
|
function extractUniprotIndex(structure, allowedAccessions) {
|
|
7
46
|
var _a, _b, _c;
|
|
8
47
|
var _d, _e;
|
|
@@ -42,9 +81,29 @@ function extractUniprotIndex(structure, allowedAccessions) {
|
|
|
42
81
|
}
|
|
43
82
|
return out;
|
|
44
83
|
}
|
|
84
|
+
/** Sort units for each accession by decreasing size and sort accessions by decreasing biggest unit size. */
|
|
85
|
+
function sortAccessionsAndUnits(uniprotIndex) {
|
|
86
|
+
const unitsByAccession = {};
|
|
87
|
+
for (const accession in uniprotIndex) {
|
|
88
|
+
const unitIds = uniprotIndex[accession];
|
|
89
|
+
const units = [];
|
|
90
|
+
for (const unitId in unitIds) {
|
|
91
|
+
const size = Object.keys(unitIds[unitId].atomMap).length;
|
|
92
|
+
units.push({ unitId, size });
|
|
93
|
+
}
|
|
94
|
+
units.sort((a, b) => b.size - a.size);
|
|
95
|
+
unitsByAccession[accession] = units;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
/** Accessions sorted by decreasing biggest unit size */
|
|
99
|
+
accessions: Object.keys(unitsByAccession).sort((a, b) => unitsByAccession[b][0].size - unitsByAccession[a][0].size),
|
|
100
|
+
/** Units per accession, sorted by decreasing unit size */
|
|
101
|
+
units: unitsByAccession,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
45
104
|
function bestUniprotMatch(a, b) {
|
|
46
|
-
const sortedA =
|
|
47
|
-
const sortedB =
|
|
105
|
+
const sortedA = sortAccessionsAndUnits(a);
|
|
106
|
+
const sortedB = sortAccessionsAndUnits(b);
|
|
48
107
|
let bestMatch = undefined;
|
|
49
108
|
let bestScore = 0;
|
|
50
109
|
for (const accession of sortedA.accessions) {
|
|
@@ -70,26 +129,6 @@ function bestUniprotMatch(a, b) {
|
|
|
70
129
|
}
|
|
71
130
|
return bestMatch;
|
|
72
131
|
}
|
|
73
|
-
/** Sort units for each accession by decreasing size and sort accessions by decreasing biggest unit size. */
|
|
74
|
-
function sortAccessionAndChains(uniprotIndex) {
|
|
75
|
-
const unitsByAccession = {};
|
|
76
|
-
for (const accession in uniprotIndex) {
|
|
77
|
-
const unitIds = uniprotIndex[accession];
|
|
78
|
-
const units = [];
|
|
79
|
-
for (const unitId in unitIds) {
|
|
80
|
-
const size = Object.keys(unitIds[unitId].atomMap).length;
|
|
81
|
-
units.push({ unitId, size });
|
|
82
|
-
}
|
|
83
|
-
units.sort((a, b) => b.size - a.size);
|
|
84
|
-
unitsByAccession[accession] = units;
|
|
85
|
-
}
|
|
86
|
-
return {
|
|
87
|
-
/** Accessions sorted by decreasing biggest unit size */
|
|
88
|
-
accessions: Object.keys(unitsByAccession).sort((a, b) => unitsByAccession[b][0].size - unitsByAccession[a][0].size),
|
|
89
|
-
/** Units per accession, sorted by decreasing unit size */
|
|
90
|
-
units: unitsByAccession,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
132
|
/** Return number of keys common to objects `a` and `b` */
|
|
94
133
|
function objectKeyOverlap(a, b) {
|
|
95
134
|
let overlap = 0;
|
|
@@ -100,36 +139,3 @@ function objectKeyOverlap(a, b) {
|
|
|
100
139
|
}
|
|
101
140
|
return overlap;
|
|
102
141
|
}
|
|
103
|
-
function superposeStructuresByBiggestCommonChain(structA, structB, allowedComponentsA, allowedComponentsB) {
|
|
104
|
-
const indexA = extractUniprotIndex(structA, allowedComponentsA);
|
|
105
|
-
const indexB = extractUniprotIndex(structB, allowedComponentsB);
|
|
106
|
-
const bestMatch = bestUniprotMatch(indexA, indexB);
|
|
107
|
-
if (!bestMatch) {
|
|
108
|
-
return { status: 'zero-overlap', superposition: undefined };
|
|
109
|
-
}
|
|
110
|
-
const unitA = structA.unitMap.get(Number(bestMatch.unitA));
|
|
111
|
-
const unitB = structB.unitMap.get(Number(bestMatch.unitB));
|
|
112
|
-
const unitIndexA = indexA[bestMatch.accession][bestMatch.unitA];
|
|
113
|
-
const unitIndexB = indexB[bestMatch.accession][bestMatch.unitB];
|
|
114
|
-
const positionsA = minimize_rmsd_1.MinimizeRmsd.Positions.empty(bestMatch.nMatchedElements);
|
|
115
|
-
const positionsB = minimize_rmsd_1.MinimizeRmsd.Positions.empty(bestMatch.nMatchedElements);
|
|
116
|
-
let i = 0;
|
|
117
|
-
for (const unpNum in unitIndexA.atomMap) {
|
|
118
|
-
const iAtomB = unitIndexB.atomMap[unpNum];
|
|
119
|
-
if (iAtomB === undefined)
|
|
120
|
-
continue;
|
|
121
|
-
const iAtomA = unitIndexA.atomMap[unpNum];
|
|
122
|
-
positionsA.x[i] = unitA.conformation.coordinates.x[iAtomA];
|
|
123
|
-
positionsA.y[i] = unitA.conformation.coordinates.y[iAtomA];
|
|
124
|
-
positionsA.z[i] = unitA.conformation.coordinates.z[iAtomA];
|
|
125
|
-
positionsB.x[i] = unitB.conformation.coordinates.x[iAtomB];
|
|
126
|
-
positionsB.y[i] = unitB.conformation.coordinates.y[iAtomB];
|
|
127
|
-
positionsB.z[i] = unitB.conformation.coordinates.z[iAtomB];
|
|
128
|
-
i++;
|
|
129
|
-
}
|
|
130
|
-
const superposition = minimize_rmsd_1.MinimizeRmsd.compute({ a: positionsA, b: positionsB });
|
|
131
|
-
if (isNaN(superposition.rmsd)) {
|
|
132
|
-
return { status: 'failed', superposition: undefined };
|
|
133
|
-
}
|
|
134
|
-
return { status: 'success', superposition: Object.assign(Object.assign({}, superposition), { nAlignedElements: bestMatch.nMatchedElements }) };
|
|
135
|
-
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Structure } from 'molstar/lib/mol-model/structure';
|
|
2
|
+
import { QueryParam } from '../../helpers';
|
|
3
|
+
import { SuperpositionResult } from './index';
|
|
4
|
+
/** Superpose structures based on the largest common component (measured the by number of residues), components being defined by `mappingsA` and `mappingsB`.
|
|
5
|
+
* Residue-residue correspondence is determined by sequence alignment. */
|
|
6
|
+
export declare function superposeBySequenceAlignment(structA: Structure, structB: Structure, mappingsA: {
|
|
7
|
+
[accession: string]: QueryParam[];
|
|
8
|
+
}, mappingsB: {
|
|
9
|
+
[accession: string]: QueryParam[];
|
|
10
|
+
}): SuperpositionResult | undefined;
|