Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"@nightingale-elements/nightingale-navigation": "5.6.0",
"@nightingale-elements/nightingale-sequence": "5.6.0",
"@nightingale-elements/nightingale-sequence-heatmap": "5.6.2",
"@nightingale-elements/nightingale-structure": "5.7.0",
"@nightingale-elements/nightingale-structure": "5.8.0",
"@nightingale-elements/nightingale-track-canvas": "5.6.0",
"@nightingale-elements/nightingale-variation": "5.6.0",
"color-hash": "2.0.2",
Expand Down
15 changes: 10 additions & 5 deletions src/adapters/alphafold-confidence-adapter.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { AlphafoldPayload } from './types/alphafold';
import { AlphaFoldPayload } from '@nightingale-elements/nightingale-structure';

type AlphafoldConfidencePayload = {
residueNumber: Array<number>;
confidenceScore: Array<number>;
confidenceCategory: Array<string>;
};

const getConfidenceURLFromPayload = (data: AlphafoldPayload) => {
const getConfidenceURLFromPayload = (data: AlphaFoldPayload) => {
const cifURL = data?.[0]?.cifUrl;
return cifURL?.length
? cifURL.replace('-model', '-confidence').replace('.cif', '.json')
Expand All @@ -31,12 +31,17 @@ type PartialProtein = {
};

const transformData = async (
data: AlphafoldPayload,
data: AlphaFoldPayload,
protein: PartialProtein
) => {
const confidenceUrl = getConfidenceURLFromPayload(data);
const { uniprotSequence } = data?.[0] || {};
if (confidenceUrl && uniprotSequence === protein.sequence.sequence) {
if (!confidenceUrl) {
return;
}
const alphaFoldSequenceMatch = data?.filter(
({ sequence }) => protein.sequence.sequence === sequence
);
if (alphaFoldSequenceMatch.length) {
const confidenceData = await loadConfidence(confidenceUrl);
return confidenceData?.confidenceCategory.join('');
}
Expand Down
20 changes: 15 additions & 5 deletions src/adapters/alphamissense-heatmap-adapter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { AlphaFoldPayload } from '@nightingale-elements/nightingale-structure';

import {
cellSplitter,
rowSplitter,
} from './alphamissense-pathogenicity-adapter';
import { AlphafoldPayload } from './types/alphafold';

const parseCSV = (rawText: string): Array<Record<string, string>> => {
const data = [];
Expand Down Expand Up @@ -43,13 +44,22 @@ type PartialProtein = {
};

const transformData = async (
data: AlphafoldPayload,
data: AlphaFoldPayload,
protein: PartialProtein
) => {
const { amAnnotationsUrl, uniprotSequence } = data?.[0] || {};
if (amAnnotationsUrl && uniprotSequence === protein.sequence.sequence) {
const heatmapData = await loadAndParseAnnotations(amAnnotationsUrl);
const alphaFoldSequenceMatch = data?.filter(
({ sequence, amAnnotationsUrl }) =>
protein.sequence.sequence === sequence && amAnnotationsUrl
);
if (alphaFoldSequenceMatch.length === 1) {
const heatmapData = await loadAndParseAnnotations(
alphaFoldSequenceMatch[0].amAnnotationsUrl
);
return heatmapData;
} else if (alphaFoldSequenceMatch.length > 1) {
console.warn(
`Found more than one matches (${alphaFoldSequenceMatch.length}) for AlphaMissense pathogenicity against protein sequence: ${protein.sequence}`
);
}
};

Expand Down
24 changes: 16 additions & 8 deletions src/adapters/alphamissense-pathogenicity-adapter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AlphafoldPayload } from './types/alphafold';
import { AlphaFoldPayload } from '@nightingale-elements/nightingale-structure';

// from color scale B:0,H:0.1132,V:0.2264,L:0.3395,A:0.4527,l:0.5895,h:0.7264,p:0.8632,P:1
const certainlyBenign = 0;
Expand Down Expand Up @@ -95,7 +95,7 @@ const loadAndParseAnnotations = async (url: string): Promise<string> => {
const rawCSV = await payload.text();
return parseCSV(rawCSV);
} catch (e) {
console.error('Could not load AlphaMissense pathogenicity', e);
console.error('Could not load AlphaMissense pathogenicity score', e);
}
};

Expand All @@ -106,14 +106,22 @@ type PartialProtein = {
};

const transformData = async (
data: AlphafoldPayload,
data: AlphaFoldPayload,
protein: PartialProtein
) => {
const { amAnnotationsUrl, uniprotSequence } = data?.[0] || {};
if (amAnnotationsUrl && uniprotSequence === protein.sequence.sequence) {
const variationData = await loadAndParseAnnotations(amAnnotationsUrl);
// return confidenceData?.confidenceCategory.join('');
return variationData;
const alphaFoldSequenceMatch = data?.filter(
({ sequence, amAnnotationsUrl }) =>
protein.sequence.sequence === sequence && amAnnotationsUrl
);
if (alphaFoldSequenceMatch.length === 1) {
const heatmapData = await loadAndParseAnnotations(
alphaFoldSequenceMatch[0].amAnnotationsUrl
);
return heatmapData;
} else if (alphaFoldSequenceMatch.length > 1) {
console.warn(
`Found more than one matches (${alphaFoldSequenceMatch.length}) for AlphaMissense pathogenicity score against protein sequence: ${protein.sequence}`
);
}
};

Expand Down
25 changes: 0 additions & 25 deletions src/adapters/types/alphafold.ts

This file was deleted.

10 changes: 6 additions & 4 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -815,8 +815,10 @@ const config: ProtvistaConfig = {
name: 'ALPHAMISSENSE_PATHOGENICITY',
label: 'AlphaMissense',
trackType: 'nightingale-colored-sequence',
scale: 'B:0,H:0.1132,V:0.2264,L:0.3395,A:0.4527,l:0.5895,h:0.7264,p:0.8632,P:1',
'color-range': '#2166ac:0,#4290bf:0.1132,#8cbcd4:0.2264,#c3d6e0:0.3395,#e2e2e2:0.4527,#edcdba:0.5895,#e99e7c:0.7264,#d15e4b:0.8632,#b2182b:1',
scale:
'B:0,H:0.1132,V:0.2264,L:0.3395,A:0.4527,l:0.5895,h:0.7264,p:0.8632,P:1',
'color-range':
'#2166ac:0,#4290bf:0.1132,#8cbcd4:0.2264,#c3d6e0:0.3395,#e2e2e2:0.4527,#edcdba:0.5895,#e99e7c:0.7264,#d15e4b:0.8632,#b2182b:1',
tracks: [
{
name: 'alphamissense_pathogenicity',
Expand All @@ -836,13 +838,13 @@ const config: ProtvistaConfig = {
{
name: 'alphamissense_pathogenicity_heatmap',
label: 'AlphaMissense Pathogenicity',
labelUrl: 'https://alphafold.ebi.ac.uk/entry/{accession}',
labelUrl: `${alphafoldEntry}{accession}`,
trackType: 'nightingale-sequence-heatmap',
data: [
{
adapter: 'alphamissense-heatmap-adapter',
url: [
'https://alphafold.ebi.ac.uk/api/prediction/{accession}',
`${alphafoldApi}prediction/{accession}`,
`${proteinsApiServices.proteins}{accession}`,
],
},
Expand Down
22 changes: 12 additions & 10 deletions src/protvista-uniprot-structure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { LitElement, html, svg, TemplateResult, css, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import NightingaleStructure, {
PredictionData,
AlphaFoldPayload,
} from '@nightingale-elements/nightingale-structure';
import ProtvistaDatatable from 'protvista-datatable';
import { fetchAll, loadComponent } from './utils';
Expand Down Expand Up @@ -164,13 +164,13 @@ const processPDBData = (data: UniProtKBData): ProcessedStructureData[] =>
transformedItem !== undefined
);

const processAFData = (data: PredictionData[]): ProcessedStructureData[] =>
const processAFData = (data: AlphaFoldPayload): ProcessedStructureData[] =>
data.map((d) => ({
id: d.entryId,
id: d.modelEntityId,
source: 'AlphaFold',
method: 'Predicted',
positions: `${d.uniprotStart}-${d.uniprotEnd}`,
protvistaFeatureId: d.entryId,
positions: `${d.sequenceStart}-${d.sequenceEnd}`,
protvistaFeatureId: d.modelEntityId,
downloadLink: d.pdbUrl,
}));

Expand Down Expand Up @@ -308,14 +308,16 @@ class ProtvistaUniprotStructure extends LitElement {
const pdbData = processPDBData(rawData[pdbUrl] || []);
let afData = [];
// Check if AF sequence matches UniProt sequence
if (
rawData[pdbUrl].sequence?.value === rawData[alphaFoldUrl]?.[0]?.sequence
) {
afData = processAFData(rawData[alphaFoldUrl] || []);
this.alphamissenseAvailable = rawData[alphaFoldUrl].some(
const alphaFoldSequenceMatch = rawData[alphaFoldUrl]?.filter(
({ sequence }) => rawData[pdbUrl].sequence?.value === sequence
);
if (alphaFoldSequenceMatch.length) {
afData = processAFData(alphaFoldSequenceMatch);
this.alphamissenseAvailable = alphaFoldSequenceMatch.some(
(data) => data.amAnnotationsUrl
);
}

const beaconsData = process3DBeaconsData(rawData[beaconsUrl] || []);

// TODO: return if no data at all
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1841,10 +1841,10 @@
"@nightingale-elements/nightingale-new-core" "^5.6.0"
d3 "7.9.0"

"@nightingale-elements/nightingale-structure@5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@nightingale-elements/nightingale-structure/-/nightingale-structure-5.7.0.tgz#dcfb75b3d73332c01abc0e34090bec173f211bf6"
integrity sha512-sP554EZqt1gJcZTok5qVa4kdBC7pM1OSTbqnx15LYqThqHiUJ0RwiJoCVyPD6RcjlKUZEM4l60e7kISnaKGNbA==
"@nightingale-elements/nightingale-structure@5.8.0":
version "5.8.0"
resolved "https://registry.yarnpkg.com/@nightingale-elements/nightingale-structure/-/nightingale-structure-5.8.0.tgz#55e69196a05206fa6cb8507a7e97836f2c3765b9"
integrity sha512-HdInDB0hh7d7LSyAOUJwEYgoBNffR/kvOU1p8I9ezMccpQ4YYf6E/Fj3xUd9NxWfULNfGk9AF/Fsg43qC6HzHw==
dependencies:
"@nightingale-elements/nightingale-new-core" "^5.6.0"
d3 "7.9.0"
Expand Down