protvista-uniprot 2.12.2 → 2.13.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/README.md +2 -2
- package/dist/es/commonTypes.d.ts +1 -1
- package/dist/es/config.json +94 -67
- package/dist/es/filterConfig.d.ts +4 -3
- package/dist/es/filterConfig.js +48 -32
- package/dist/es/filterConfig.js.map +1 -1
- package/dist/es/index.d.ts +0 -2
- package/dist/es/index.js +0 -3
- package/dist/es/index.js.map +1 -1
- package/dist/es/protvista-alphafold-confidence.d.ts +1 -1
- package/dist/es/protvista-alphamissense-heatmap.d.ts +8 -0
- package/dist/es/protvista-alphamissense-heatmap.js +35 -0
- package/dist/es/protvista-alphamissense-heatmap.js.map +1 -0
- package/dist/es/protvista-alphamissense-pathogenicity.d.ts +3 -1
- package/dist/es/protvista-alphamissense-pathogenicity.js +2 -2
- package/dist/es/protvista-alphamissense-pathogenicity.js.map +1 -1
- package/dist/es/protvista-ptm-exchange.d.ts +7 -7
- package/dist/es/protvista-ptm-exchange.js +6 -4
- package/dist/es/protvista-ptm-exchange.js.map +1 -1
- package/dist/es/protvista-uniprot-structure.d.ts +6 -1
- package/dist/es/protvista-uniprot-structure.js +137 -66
- package/dist/es/protvista-uniprot-structure.js.map +1 -1
- package/dist/es/protvista-uniprot.d.ts +27 -16
- package/dist/es/protvista-uniprot.js +166 -145
- package/dist/es/protvista-uniprot.js.map +1 -1
- package/dist/es/protvista-variation-graph-adapter.d.ts +9 -0
- package/dist/es/protvista-variation-graph-adapter.js +46 -0
- package/dist/es/protvista-variation-graph-adapter.js.map +1 -0
- package/dist/es/styles/protvista-styles.js +8 -13
- package/dist/es/styles/protvista-styles.js.map +1 -1
- package/dist/protvista-uniprot.js +217 -217
- package/dist/protvista-uniprot.js.LICENSE.txt +24 -57
- package/dist/protvista-uniprot.js.map +1 -1
- package/package.json +15 -16
- package/src/config.json +94 -67
- package/src/filterConfig.ts +58 -55
- package/src/index.ts +0 -3
- package/src/protvista-alphamissense-heatmap.ts +52 -0
- package/src/protvista-alphamissense-pathogenicity.ts +2 -2
- package/src/protvista-ptm-exchange.ts +21 -19
- package/src/protvista-uniprot-structure.ts +168 -94
- package/src/protvista-uniprot.ts +226 -168
- package/src/protvista-variation-graph-adapter.ts +47 -0
- package/src/styles/protvista-styles.ts +8 -13
- package/src/types/nightingale-components.d.ts +1 -1
- package/src/types/nightingale-sequence-heatmap.d.ts +1 -0
- package/dist/es/download-panel.d.ts +0 -29
- package/dist/es/download-panel.js +0 -137
- package/dist/es/download-panel.js.map +0 -1
- package/src/download-panel.ts +0 -164
- package/src/types/protvista-filter.d.ts +0 -16
- package/src/types/protvista-interpro-track.d.ts +0 -1
- package/src/types/protvista-manager.d.ts +0 -1
- package/src/types/protvista-navigation.d.ts +0 -1
- package/src/types/protvista-sequence.d.ts +0 -1
- package/src/types/protvista-tooltip.d.ts +0 -8
- package/src/types/protvista-track.d.ts +0 -5
- package/src/types/protvista-variation-graph.d.ts +0 -1
package/src/filterConfig.ts
CHANGED
|
@@ -33,6 +33,35 @@ export const getFilteredVariants = (
|
|
|
33
33
|
};
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
+
const filterPredicates = {
|
|
37
|
+
disease: (variantPos) =>
|
|
38
|
+
variantPos.association?.some((association) => association.disease),
|
|
39
|
+
predicted: (variantPos) => variantPos.hasPredictions,
|
|
40
|
+
nonDisease: (variantPos) =>
|
|
41
|
+
variantPos.association?.some(
|
|
42
|
+
(association) => association.disease === false
|
|
43
|
+
),
|
|
44
|
+
uncertain: (variantPos) =>
|
|
45
|
+
(typeof variantPos.clinicalSignificances === 'undefined' &&
|
|
46
|
+
!variantPos.hasPredictions) ||
|
|
47
|
+
(variantPos.clinicalSignificances &&
|
|
48
|
+
significanceMatches(
|
|
49
|
+
variantPos.clinicalSignificances,
|
|
50
|
+
consequences.uncertain
|
|
51
|
+
)),
|
|
52
|
+
UniProt: (variantPos) =>
|
|
53
|
+
variantPos.xrefNames &&
|
|
54
|
+
(variantPos.xrefNames.includes('uniprot') ||
|
|
55
|
+
variantPos.xrefNames.includes('UniProt')),
|
|
56
|
+
ClinVar: (variantPos) =>
|
|
57
|
+
variantPos.xrefNames &&
|
|
58
|
+
(variantPos.xrefNames.includes('ClinVar') ||
|
|
59
|
+
variantPos.xrefNames.includes('clinvar')),
|
|
60
|
+
LSS: (variantPos) =>
|
|
61
|
+
variantPos.sourceType === 'large_scale_study' ||
|
|
62
|
+
variantPos.sourceType === 'mixed',
|
|
63
|
+
};
|
|
64
|
+
|
|
36
65
|
const filterConfig = [
|
|
37
66
|
{
|
|
38
67
|
name: 'disease',
|
|
@@ -41,13 +70,12 @@ const filterConfig = [
|
|
|
41
70
|
text: 'Filter Consequence',
|
|
42
71
|
},
|
|
43
72
|
options: {
|
|
44
|
-
|
|
45
|
-
|
|
73
|
+
label: 'Likely pathogenic or pathogenic',
|
|
74
|
+
color: scaleColors.UPDiseaseColor,
|
|
46
75
|
},
|
|
76
|
+
filterPredicate: filterPredicates['disease'],
|
|
47
77
|
filterData: (variants: ProtvistaVariationData) =>
|
|
48
|
-
getFilteredVariants(variants,
|
|
49
|
-
variantPos.association?.some((association) => association.disease)
|
|
50
|
-
),
|
|
78
|
+
getFilteredVariants(variants, filterPredicates['disease']),
|
|
51
79
|
},
|
|
52
80
|
{
|
|
53
81
|
name: 'predicted',
|
|
@@ -56,11 +84,12 @@ const filterConfig = [
|
|
|
56
84
|
text: 'Filter Consequence',
|
|
57
85
|
},
|
|
58
86
|
options: {
|
|
59
|
-
|
|
60
|
-
|
|
87
|
+
label: 'Predicted consequence',
|
|
88
|
+
color: scaleColors.predictedColor,
|
|
61
89
|
},
|
|
90
|
+
filterPredicate: filterPredicates['predicted'],
|
|
62
91
|
filterData: (variants: ProtvistaVariationData) =>
|
|
63
|
-
getFilteredVariants(variants,
|
|
92
|
+
getFilteredVariants(variants, filterPredicates['predicted']),
|
|
64
93
|
},
|
|
65
94
|
{
|
|
66
95
|
name: 'nonDisease',
|
|
@@ -69,15 +98,12 @@ const filterConfig = [
|
|
|
69
98
|
text: 'Filter Consequence',
|
|
70
99
|
},
|
|
71
100
|
options: {
|
|
72
|
-
|
|
73
|
-
|
|
101
|
+
label: 'Likely benign or benign',
|
|
102
|
+
color: scaleColors.UPNonDiseaseColor,
|
|
74
103
|
},
|
|
104
|
+
filterPredicate: filterPredicates['nonDisease'],
|
|
75
105
|
filterData: (variants: ProtvistaVariationData) =>
|
|
76
|
-
getFilteredVariants(variants,
|
|
77
|
-
variantPos.association?.some(
|
|
78
|
-
(association) => association.disease === false
|
|
79
|
-
)
|
|
80
|
-
),
|
|
106
|
+
getFilteredVariants(variants, filterPredicates['nonDisease']),
|
|
81
107
|
},
|
|
82
108
|
{
|
|
83
109
|
name: 'uncertain',
|
|
@@ -86,21 +112,12 @@ const filterConfig = [
|
|
|
86
112
|
text: 'Filter Consequence',
|
|
87
113
|
},
|
|
88
114
|
options: {
|
|
89
|
-
|
|
90
|
-
|
|
115
|
+
label: 'Uncertain significance',
|
|
116
|
+
color: scaleColors.othersColor,
|
|
91
117
|
},
|
|
118
|
+
filterPredicate: filterPredicates['uncertain'],
|
|
92
119
|
filterData: (variants: ProtvistaVariationData) =>
|
|
93
|
-
getFilteredVariants(
|
|
94
|
-
variants,
|
|
95
|
-
(variantPos) =>
|
|
96
|
-
(typeof variantPos.clinicalSignificances === 'undefined' &&
|
|
97
|
-
!variantPos.hasPredictions) ||
|
|
98
|
-
(variantPos.clinicalSignificances &&
|
|
99
|
-
significanceMatches(
|
|
100
|
-
variantPos.clinicalSignificances,
|
|
101
|
-
consequences.uncertain
|
|
102
|
-
))
|
|
103
|
-
),
|
|
120
|
+
getFilteredVariants(variants, filterPredicates['uncertain']),
|
|
104
121
|
},
|
|
105
122
|
{
|
|
106
123
|
name: 'UniProt',
|
|
@@ -109,17 +126,12 @@ const filterConfig = [
|
|
|
109
126
|
text: 'Filter Provenance',
|
|
110
127
|
},
|
|
111
128
|
options: {
|
|
112
|
-
|
|
113
|
-
|
|
129
|
+
label: 'UniProt reviewed',
|
|
130
|
+
color: '#9f9f9f',
|
|
114
131
|
},
|
|
132
|
+
filterPredicate: filterPredicates['UniProt'],
|
|
115
133
|
filterData: (variants: ProtvistaVariationData) =>
|
|
116
|
-
getFilteredVariants(
|
|
117
|
-
variants,
|
|
118
|
-
(variantPos) =>
|
|
119
|
-
variantPos.xrefNames &&
|
|
120
|
-
(variantPos.xrefNames.includes('uniprot') ||
|
|
121
|
-
variantPos.xrefNames.includes('UniProt'))
|
|
122
|
-
),
|
|
134
|
+
getFilteredVariants(variants, filterPredicates['UniProt']),
|
|
123
135
|
},
|
|
124
136
|
{
|
|
125
137
|
name: 'ClinVar',
|
|
@@ -128,17 +140,12 @@ const filterConfig = [
|
|
|
128
140
|
text: 'Filter Provenance',
|
|
129
141
|
},
|
|
130
142
|
options: {
|
|
131
|
-
|
|
132
|
-
|
|
143
|
+
label: 'ClinVar',
|
|
144
|
+
color: '#9f9f9f',
|
|
133
145
|
},
|
|
146
|
+
filterPredicate: filterPredicates['ClinVar'],
|
|
134
147
|
filterData: (variants: ProtvistaVariationData) =>
|
|
135
|
-
getFilteredVariants(
|
|
136
|
-
variants,
|
|
137
|
-
(variantPos) =>
|
|
138
|
-
variantPos.xrefNames &&
|
|
139
|
-
(variantPos.xrefNames.includes('ClinVar') ||
|
|
140
|
-
variantPos.xrefNames.includes('clinvar'))
|
|
141
|
-
),
|
|
148
|
+
getFilteredVariants(variants, filterPredicates['ClinVar']),
|
|
142
149
|
},
|
|
143
150
|
{
|
|
144
151
|
name: 'LSS',
|
|
@@ -147,16 +154,12 @@ const filterConfig = [
|
|
|
147
154
|
text: 'Filter Provenance',
|
|
148
155
|
},
|
|
149
156
|
options: {
|
|
150
|
-
|
|
151
|
-
|
|
157
|
+
label: 'Large scale studies',
|
|
158
|
+
color: '#9f9f9f',
|
|
152
159
|
},
|
|
160
|
+
filterPredicate: filterPredicates['LSS'],
|
|
153
161
|
filterData: (variants: ProtvistaVariationData) =>
|
|
154
|
-
getFilteredVariants(
|
|
155
|
-
variants,
|
|
156
|
-
(variantPos) =>
|
|
157
|
-
variantPos.sourceType === 'large_scale_study' ||
|
|
158
|
-
variantPos.sourceType === 'mixed'
|
|
159
|
-
),
|
|
162
|
+
getFilteredVariants(variants, filterPredicates['LSS']),
|
|
160
163
|
},
|
|
161
164
|
];
|
|
162
165
|
|
|
@@ -172,7 +175,7 @@ const countVariantsForFilter = (
|
|
|
172
175
|
return false;
|
|
173
176
|
};
|
|
174
177
|
|
|
175
|
-
export const colorConfig = (variant:
|
|
178
|
+
export const colorConfig = (variant: any) => {
|
|
176
179
|
if (countVariantsForFilter('disease', variant)) {
|
|
177
180
|
return scaleColors.UPDiseaseColor;
|
|
178
181
|
} else if (countVariantsForFilter('nonDisease', variant)) {
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { loadComponent } from './loadComponents';
|
|
2
2
|
|
|
3
3
|
import ProtvistaUniprot from './protvista-uniprot';
|
|
4
|
-
import _DownloadPanel from './download-panel';
|
|
5
4
|
import _ProtvistaUniprotStructure from './protvista-uniprot-structure';
|
|
6
5
|
|
|
7
6
|
import { transformDataFeatureAdapter as _transformDataFeatureAdapter } from './protvista-uniprot';
|
|
@@ -16,10 +15,8 @@ export const transformDataStructureAdapter = _transformDataStructureAdapter;
|
|
|
16
15
|
export const transformDataVariationAdapter = _transformDataVariationAdapter;
|
|
17
16
|
export const transformDataInterproAdapter = _transformDataInterproAdapter;
|
|
18
17
|
export const ProtvistaUniprotStructure = _ProtvistaUniprotStructure;
|
|
19
|
-
export const DownloadPanel = _DownloadPanel;
|
|
20
18
|
|
|
21
19
|
loadComponent('protvista-uniprot', ProtvistaUniprot);
|
|
22
|
-
loadComponent('download-panel', _DownloadPanel);
|
|
23
20
|
loadComponent('protvista-uniprot-structure', _ProtvistaUniprotStructure);
|
|
24
21
|
|
|
25
22
|
export default ProtvistaUniprot;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cellSplitter,
|
|
3
|
+
rowSplitter,
|
|
4
|
+
} from './protvista-alphamissense-pathogenicity';
|
|
5
|
+
import { AlphafoldPayload } from './commonTypes';
|
|
6
|
+
|
|
7
|
+
const parseCSV = (rawText: string): Array<Record<string, string>> => {
|
|
8
|
+
const data = [];
|
|
9
|
+
|
|
10
|
+
for (const [i, row] of rawText.split(rowSplitter).entries()) {
|
|
11
|
+
if (i === 0 || !row) {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
const [, , positionString, mutated, pathogenicityScore] =
|
|
15
|
+
row.match(cellSplitter);
|
|
16
|
+
|
|
17
|
+
data.push({
|
|
18
|
+
xValue: +positionString,
|
|
19
|
+
yValue: mutated,
|
|
20
|
+
score: +pathogenicityScore,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return data;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Load and parse
|
|
27
|
+
const loadAndParseAnnotations = async (url: string): Promise<Array<Record<string, string>>> => {
|
|
28
|
+
try {
|
|
29
|
+
const payload = await fetch(url);
|
|
30
|
+
const rawCSV = await payload.text();
|
|
31
|
+
return parseCSV(rawCSV);
|
|
32
|
+
} catch (e) {
|
|
33
|
+
console.error('Could not load AlphaMissense pathogenicity', e);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
type PartialProtein = {
|
|
38
|
+
sequence: {
|
|
39
|
+
sequence: string;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const transformData = async (
|
|
44
|
+
data: AlphafoldPayload,
|
|
45
|
+
protein: PartialProtein
|
|
46
|
+
) => {
|
|
47
|
+
const { amAnnotationsUrl, uniprotSequence } = data?.[0] || {};
|
|
48
|
+
if (amAnnotationsUrl && uniprotSequence === protein.sequence.sequence) {
|
|
49
|
+
const heatmapData = await loadAndParseAnnotations(amAnnotationsUrl);
|
|
50
|
+
return heatmapData;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
@@ -7,8 +7,8 @@ import { AlphafoldPayload } from './commonTypes';
|
|
|
7
7
|
const benign = 0.34;
|
|
8
8
|
const pathogenic = 0.564;
|
|
9
9
|
|
|
10
|
-
const rowSplitter = /\s*\n\s*/;
|
|
11
|
-
const cellSplitter = /^(.)(\d+)(.),(.+),(\w+)$/;
|
|
10
|
+
export const rowSplitter = /\s*\n\s*/;
|
|
11
|
+
export const cellSplitter = /^(.)(\d+)(.),(.+),(\w+)$/;
|
|
12
12
|
|
|
13
13
|
type Row = {
|
|
14
14
|
wildType: string;
|
|
@@ -91,9 +91,7 @@ const convertPtmExchangePtms = (
|
|
|
91
91
|
console.log('PTM has no confidence score');
|
|
92
92
|
} else if (confidenceScores.size > 1) {
|
|
93
93
|
console.error(
|
|
94
|
-
`PTM has a mixture of confidence scores: ${Array.from(
|
|
95
|
-
confidenceScores
|
|
96
|
-
)}`
|
|
94
|
+
`PTM has a mixture of confidence scores: ${Array.from(confidenceScores)}`
|
|
97
95
|
);
|
|
98
96
|
} else {
|
|
99
97
|
[confidenceScore] = confidenceScores;
|
|
@@ -101,22 +99,26 @@ const convertPtmExchangePtms = (
|
|
|
101
99
|
|
|
102
100
|
const tooltip = `
|
|
103
101
|
<h5>Description</h5><p>${phosphorylate(aa)}</p>
|
|
104
|
-
${
|
|
102
|
+
${
|
|
103
|
+
confidenceScore
|
|
104
|
+
? `<h5 data-article-id="mod_res_large_scale#confidence-score">Confidence Score</h5><p>${confidenceScore}</p>`
|
|
105
|
+
: ''
|
|
106
|
+
}
|
|
105
107
|
${
|
|
106
108
|
evidences
|
|
107
109
|
? `<h5>Evidence</h5><ul>${evidences
|
|
108
|
-
.map(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
(<a href="https://www.ebi.ac.uk/pride/archive/projects/${id}" style="color:#FFF" target="_blank">PRIDE</a>)
|
|
110
|
+
.map((id) => {
|
|
111
|
+
const datasetID = id === 'Glue project' ? 'PXD012174' : id;
|
|
112
|
+
return `<li title='${datasetID}' style="padding: .25rem 0">${datasetID}
|
|
113
|
+
(<a href="https://proteomecentral.proteomexchange.org/dataset/${datasetID}" style="color:#FFF" target="_blank">ProteomeXchange</a>)
|
|
113
114
|
</li>
|
|
114
|
-
${
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
115
|
+
${
|
|
116
|
+
id === 'Glue project'
|
|
117
|
+
? `<li title="publication" style="padding: .25rem 0">Publication: 31819260 (<a href="https://pubmed.ncbi.nlm.nih.gov/31819260" style="color:#FFF" target="_blank">PubMed</a>)</li>`
|
|
118
|
+
: ''
|
|
119
|
+
}
|
|
120
|
+
`;
|
|
121
|
+
})
|
|
120
122
|
.join('')}</ul>`
|
|
121
123
|
: ''
|
|
122
124
|
}
|
|
@@ -139,7 +141,7 @@ export const transformData = (data: ProteomicsPtm) => {
|
|
|
139
141
|
|
|
140
142
|
const absolutePositionToPtms: Record<number, { ptms: PTM[]; aa: string }> =
|
|
141
143
|
{};
|
|
142
|
-
|
|
144
|
+
|
|
143
145
|
if (features) {
|
|
144
146
|
for (const feature of features) {
|
|
145
147
|
for (const ptm of feature.ptms) {
|
|
@@ -167,12 +169,12 @@ export const transformData = (data: ProteomicsPtm) => {
|
|
|
167
169
|
}
|
|
168
170
|
}
|
|
169
171
|
}
|
|
170
|
-
|
|
172
|
+
|
|
171
173
|
return Object.entries(absolutePositionToPtms).map(
|
|
172
174
|
([absolutePosition, { ptms, aa }]) =>
|
|
173
175
|
convertPtmExchangePtms(ptms, aa, +absolutePosition)
|
|
174
176
|
);
|
|
175
|
-
}
|
|
177
|
+
}
|
|
176
178
|
}
|
|
177
|
-
return [];
|
|
179
|
+
return [];
|
|
178
180
|
};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { LitElement, html, svg, TemplateResult, css } from 'lit-element';
|
|
2
2
|
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
|
|
3
3
|
import { load } from 'data-loader';
|
|
4
|
-
import
|
|
4
|
+
import NightingaleStructure, {
|
|
5
|
+
PredictionData,
|
|
6
|
+
StructureData,
|
|
7
|
+
} from '@nightingale-elements/nightingale-structure';
|
|
5
8
|
import ProtvistaDatatable from 'protvista-datatable';
|
|
6
9
|
import { loadComponent } from './loadComponents';
|
|
7
10
|
|
|
@@ -9,11 +12,6 @@ import loaderIcon from './icons/spinner.svg';
|
|
|
9
12
|
import downloadIcon from './icons/download.svg';
|
|
10
13
|
import loaderStyles from './styles/loader-styles';
|
|
11
14
|
|
|
12
|
-
import {
|
|
13
|
-
PredictionData,
|
|
14
|
-
StructureData,
|
|
15
|
-
} from 'protvista-structure/dist/es/protvista-structure';
|
|
16
|
-
|
|
17
15
|
const PDBLinks = [
|
|
18
16
|
{ name: 'PDBe', link: 'https://www.ebi.ac.uk/pdbe-srv/view/entry/' },
|
|
19
17
|
{ name: 'RCSB-PDB', link: 'https://www.rcsb.org/structure/' },
|
|
@@ -110,8 +108,35 @@ const AFMetaInfo = html`
|
|
|
110
108
|
</p>
|
|
111
109
|
`;
|
|
112
110
|
|
|
111
|
+
const AMMetaInfo = html`<strong>Model Pathogenicity:</strong>
|
|
112
|
+
<ul class="no-bullet">
|
|
113
|
+
<li>
|
|
114
|
+
<span class="af-legend" style="background-color: rgb(154, 19, 26)"></span>
|
|
115
|
+
Likely pathogenic (score > 0.564)
|
|
116
|
+
</li>
|
|
117
|
+
<li>
|
|
118
|
+
<span
|
|
119
|
+
class="af-legend"
|
|
120
|
+
style="background-color: rgb(168, 169, 173)"
|
|
121
|
+
></span>
|
|
122
|
+
Uncertain (0.564 >= score >= 0.34)
|
|
123
|
+
</li>
|
|
124
|
+
<li>
|
|
125
|
+
<span class="af-legend" style="background-color: rgb(61, 84, 147)"></span>
|
|
126
|
+
Likely benign (score < 0.34)
|
|
127
|
+
</li>
|
|
128
|
+
</ul>
|
|
129
|
+
<p class="small">
|
|
130
|
+
The displayed colour for each residue is the average AlphaMissense
|
|
131
|
+
pathogenicity score across all possible amino acid substitutions at that
|
|
132
|
+
position.
|
|
133
|
+
</p>`;
|
|
134
|
+
|
|
113
135
|
const foldseekURL = (accession, sourceDB) => {
|
|
114
|
-
return html`<a
|
|
136
|
+
return html`<a
|
|
137
|
+
href="${foldseekLink}?accession=${accession}&source=${sourceDB}"
|
|
138
|
+
>Foldseek</a
|
|
139
|
+
>`;
|
|
115
140
|
};
|
|
116
141
|
|
|
117
142
|
const styleId = 'protvista-styles';
|
|
@@ -120,15 +145,17 @@ class ProtvistaUniprotStructure extends LitElement {
|
|
|
120
145
|
data?: ProcessedStructureData[];
|
|
121
146
|
structureId?: string;
|
|
122
147
|
metaInfo?: TemplateResult;
|
|
148
|
+
colorTheme?: string;
|
|
123
149
|
private loading?: boolean;
|
|
124
150
|
|
|
125
151
|
constructor() {
|
|
126
152
|
super();
|
|
127
|
-
loadComponent('
|
|
153
|
+
loadComponent('nightingale-structure', NightingaleStructure);
|
|
128
154
|
loadComponent('protvista-datatable', ProtvistaDatatable);
|
|
129
155
|
this.loading = true;
|
|
130
156
|
this.onTableRowClick = this.onTableRowClick.bind(this);
|
|
131
157
|
this.addStyles();
|
|
158
|
+
this.colorTheme = 'alphafold';
|
|
132
159
|
}
|
|
133
160
|
|
|
134
161
|
static get properties() {
|
|
@@ -137,6 +164,7 @@ class ProtvistaUniprotStructure extends LitElement {
|
|
|
137
164
|
structureId: { type: String },
|
|
138
165
|
data: { type: Object },
|
|
139
166
|
loading: { type: Boolean },
|
|
167
|
+
colorTheme: { type: String },
|
|
140
168
|
};
|
|
141
169
|
}
|
|
142
170
|
|
|
@@ -219,6 +247,12 @@ class ProtvistaUniprotStructure extends LitElement {
|
|
|
219
247
|
|
|
220
248
|
get cssStyle() {
|
|
221
249
|
return css`
|
|
250
|
+
.protvista-uniprot-structure {
|
|
251
|
+
line-height: normal;
|
|
252
|
+
}
|
|
253
|
+
.theme-selection {
|
|
254
|
+
padding-bottom: 1rem;
|
|
255
|
+
}
|
|
222
256
|
.protvista-uniprot-structure__structure {
|
|
223
257
|
display: flex;
|
|
224
258
|
}
|
|
@@ -226,7 +260,7 @@ class ProtvistaUniprotStructure extends LitElement {
|
|
|
226
260
|
flex: 1;
|
|
227
261
|
padding: 1rem;
|
|
228
262
|
}
|
|
229
|
-
.protvista-uniprot-structure__structure
|
|
263
|
+
.protvista-uniprot-structure__structure nightingale-structure {
|
|
230
264
|
z-index: 40000;
|
|
231
265
|
width: 100%;
|
|
232
266
|
flex: 4;
|
|
@@ -263,102 +297,142 @@ class ProtvistaUniprotStructure extends LitElement {
|
|
|
263
297
|
return this;
|
|
264
298
|
}
|
|
265
299
|
|
|
300
|
+
toggleColorTheme(e) {
|
|
301
|
+
this.colorTheme = e.target.value;
|
|
302
|
+
if (e.target.value === 'alphafold') {
|
|
303
|
+
this.metaInfo = AFMetaInfo;
|
|
304
|
+
} else {
|
|
305
|
+
this.metaInfo = AMMetaInfo;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
266
309
|
render() {
|
|
267
310
|
return html`
|
|
268
311
|
<div class="protvista-uniprot-structure">
|
|
269
312
|
<div class="protvista-uniprot-structure__structure">
|
|
270
313
|
${this.metaInfo
|
|
271
|
-
? html
|
|
314
|
+
? html` <div class="protvista-uniprot-structure__meta">
|
|
315
|
+
<div class="theme-selection">
|
|
316
|
+
Select color scale <br />
|
|
317
|
+
<input
|
|
318
|
+
type="radio"
|
|
319
|
+
id="alphafold"
|
|
320
|
+
name="colorScheme"
|
|
321
|
+
value="alphafold"
|
|
322
|
+
@click=${(e) => this.toggleColorTheme(e)}
|
|
323
|
+
checked
|
|
324
|
+
/>
|
|
325
|
+
<label for="alphafold">Confidence</label><br />
|
|
326
|
+
<input
|
|
327
|
+
type="radio"
|
|
328
|
+
id="alphamissense"
|
|
329
|
+
name="colorScheme"
|
|
330
|
+
value="alphamissense"
|
|
331
|
+
@click=${(e) => this.toggleColorTheme(e)}
|
|
332
|
+
/>
|
|
333
|
+
<label for="alphamissense">Pathogenecity</label><br />
|
|
334
|
+
</div>
|
|
272
335
|
${this.metaInfo}
|
|
273
336
|
</div>`
|
|
274
337
|
: html``}
|
|
275
338
|
${this.structureId
|
|
276
|
-
? html`<
|
|
277
|
-
|
|
278
|
-
accession=${this.accession}
|
|
279
|
-
|
|
339
|
+
? html`<nightingale-structure
|
|
340
|
+
structure-id=${this.structureId}
|
|
341
|
+
protein-accession=${this.accession}
|
|
342
|
+
color-theme=${this.colorTheme}
|
|
343
|
+
></nightingale-structure>`
|
|
344
|
+
: html``}
|
|
345
|
+
</div>
|
|
346
|
+
<div class="protvista-uniprot-structure__table">
|
|
347
|
+
${this.data && this.data.length
|
|
348
|
+
? html`<protvista-datatable noScrollToRow noDeselect filter-scroll>
|
|
349
|
+
<table>
|
|
350
|
+
<thead>
|
|
351
|
+
<tr>
|
|
352
|
+
<th data-filter="source">Source</th>
|
|
353
|
+
<th>Identifier</th>
|
|
354
|
+
<th data-filter="method">Method</th>
|
|
355
|
+
<th>Resolution</th>
|
|
356
|
+
<th>Chain</th>
|
|
357
|
+
<th>Positions</th>
|
|
358
|
+
<th>Links</th>
|
|
359
|
+
<th><!--Download--></th>
|
|
360
|
+
</tr>
|
|
361
|
+
</thead>
|
|
362
|
+
<tbody>
|
|
363
|
+
${this.data?.map(
|
|
364
|
+
({
|
|
365
|
+
source,
|
|
366
|
+
id,
|
|
367
|
+
method,
|
|
368
|
+
resolution,
|
|
369
|
+
chain,
|
|
370
|
+
positions,
|
|
371
|
+
downloadLink,
|
|
372
|
+
}) => html`<tr
|
|
373
|
+
data-id="${id}"
|
|
374
|
+
@click="${() => this.onTableRowClick({ id })}"
|
|
375
|
+
>
|
|
376
|
+
<td data-filter="source" data-filter-value="${source}">
|
|
377
|
+
<strong>${source}</strong>
|
|
378
|
+
</td>
|
|
379
|
+
<td>${id}</td>
|
|
380
|
+
<td data-filter="method" data-filter-value="${method}">
|
|
381
|
+
${method}
|
|
382
|
+
</td>
|
|
383
|
+
<td>
|
|
384
|
+
${resolution ? resolution.replace('A', 'Å') : ''}
|
|
385
|
+
</td>
|
|
386
|
+
<td>${chain || ''}</td>
|
|
387
|
+
<td>${positions || ''}</td>
|
|
388
|
+
<td>
|
|
389
|
+
${source === 'PDB'
|
|
390
|
+
? html`
|
|
391
|
+
${PDBLinks.map((pdbLink) => {
|
|
392
|
+
return html`
|
|
393
|
+
<a href="${pdbLink.link}${id}"
|
|
394
|
+
>${pdbLink.name}</a
|
|
395
|
+
>
|
|
396
|
+
`;
|
|
397
|
+
}).reduce(
|
|
398
|
+
(prev, curr) => html` ${prev} · ${curr} `
|
|
399
|
+
)}
|
|
400
|
+
`
|
|
401
|
+
: html`<a href="${alphaFoldLink}${this.accession}"
|
|
402
|
+
>AlphaFold</a
|
|
403
|
+
>`}
|
|
404
|
+
</td>
|
|
405
|
+
<td>
|
|
406
|
+
${downloadLink
|
|
407
|
+
? html`<a
|
|
408
|
+
href="${downloadLink}"
|
|
409
|
+
class="download-link"
|
|
410
|
+
>${svg`${unsafeHTML(downloadIcon)}`}</a
|
|
411
|
+
>
|
|
412
|
+
·
|
|
413
|
+
${foldseekURL(
|
|
414
|
+
source === 'PDB' ? id : this.accession,
|
|
415
|
+
source === 'PDB' ? 'PDB' : 'AlphaFoldDB'
|
|
416
|
+
)}`
|
|
417
|
+
: ''}
|
|
418
|
+
</td>
|
|
419
|
+
</tr>`
|
|
420
|
+
)}
|
|
421
|
+
</tbody>
|
|
422
|
+
</table>
|
|
423
|
+
</protvista-datatable>`
|
|
424
|
+
: html``}
|
|
425
|
+
${this.loading
|
|
426
|
+
? html`<div class="protvista-loader">
|
|
427
|
+
${svg`${unsafeHTML(loaderIcon)}`}
|
|
428
|
+
</div>`
|
|
429
|
+
: html``}
|
|
430
|
+
${!this.data && !this.loading
|
|
431
|
+
? html`<div class="protvista-no-results">
|
|
432
|
+
No structure information available for ${this.accession}
|
|
433
|
+
</div>`
|
|
280
434
|
: html``}
|
|
281
435
|
</div>
|
|
282
|
-
<div class="class="protvista-uniprot-structure__table">
|
|
283
|
-
${this.data && this.data.length
|
|
284
|
-
? html`<protvista-datatable noScrollToRow noDeselect filter-scroll>
|
|
285
|
-
<table>
|
|
286
|
-
<thead>
|
|
287
|
-
<tr>
|
|
288
|
-
<th data-filter="source">Source</th>
|
|
289
|
-
<th>Identifier</th>
|
|
290
|
-
<th data-filter="method">Method</th>
|
|
291
|
-
<th>Resolution</th>
|
|
292
|
-
<th>Chain</th>
|
|
293
|
-
<th>Positions</th>
|
|
294
|
-
<th>Links</th>
|
|
295
|
-
<th><!--Download--></th>
|
|
296
|
-
</tr>
|
|
297
|
-
</thead>
|
|
298
|
-
<tbody>
|
|
299
|
-
${this.data?.map(
|
|
300
|
-
({
|
|
301
|
-
source,
|
|
302
|
-
id,
|
|
303
|
-
method,
|
|
304
|
-
resolution,
|
|
305
|
-
chain,
|
|
306
|
-
positions,
|
|
307
|
-
downloadLink,
|
|
308
|
-
}) => html`<tr
|
|
309
|
-
data-id="${id}"
|
|
310
|
-
@click="${() => this.onTableRowClick({ id })}"
|
|
311
|
-
>
|
|
312
|
-
<td data-filter="source" data-filter-value="${source}">
|
|
313
|
-
<strong>${source}</strong>
|
|
314
|
-
</td>
|
|
315
|
-
<td>${id}</td>
|
|
316
|
-
<td data-filter="method" data-filter-value="${method}">
|
|
317
|
-
${method}
|
|
318
|
-
</td>
|
|
319
|
-
<td>${resolution ? resolution.replace('A', 'Å') : ''}</td>
|
|
320
|
-
<td>${chain || ''}</td>
|
|
321
|
-
<td>${positions || ''}</td>
|
|
322
|
-
<td>
|
|
323
|
-
${source === 'PDB'
|
|
324
|
-
? html`
|
|
325
|
-
${PDBLinks.map((pdbLink) => {
|
|
326
|
-
return html`
|
|
327
|
-
<a href="${pdbLink.link}${id}"
|
|
328
|
-
>${pdbLink.name}</a
|
|
329
|
-
>
|
|
330
|
-
`;
|
|
331
|
-
}).reduce(
|
|
332
|
-
(prev, curr) => html` ${prev} · ${curr} `
|
|
333
|
-
)}
|
|
334
|
-
`
|
|
335
|
-
: html`<a href="${alphaFoldLink}${this.accession}"
|
|
336
|
-
>AlphaFold</a
|
|
337
|
-
>`}
|
|
338
|
-
</td>
|
|
339
|
-
<td>
|
|
340
|
-
${downloadLink
|
|
341
|
-
? html`<a href="${downloadLink}" class="download-link"
|
|
342
|
-
>${svg`${unsafeHTML(downloadIcon)}`}</a
|
|
343
|
-
> · ${foldseekURL(source === 'PDB' ? id: this.accession, source === 'PDB' ? 'PDB' : 'AlphaFoldDB')}`
|
|
344
|
-
: ''}
|
|
345
|
-
</td>
|
|
346
|
-
</tr>`
|
|
347
|
-
)}
|
|
348
|
-
</tbody>
|
|
349
|
-
</table>
|
|
350
|
-
</protvista-datatable>`
|
|
351
|
-
: html``}
|
|
352
|
-
${this.loading
|
|
353
|
-
? html`<div class="protvista-loader">
|
|
354
|
-
${svg`${unsafeHTML(loaderIcon)}`}
|
|
355
|
-
</div>`
|
|
356
|
-
: html``}
|
|
357
|
-
${!this.data && !this.loading
|
|
358
|
-
? html`<div class="protvista-no-results">
|
|
359
|
-
No structure information available for ${this.accession}
|
|
360
|
-
</div>`
|
|
361
|
-
: html``}
|
|
362
436
|
</div>
|
|
363
437
|
`;
|
|
364
438
|
}
|