Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix uniprot PTM crash when centain fields are missing in uniprot data #4034

Merged
merged 1 commit into from
Nov 10, 2021
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
10 changes: 5 additions & 5 deletions packages/cbioportal-utils/src/model/Uniprot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ export interface UniprotFeatureEvidence {
export interface UniprotFeature {
type: string; // "MOD_RES"
category: string; // "PTM"
description: string; // "Phosphoserine; by HIPK4"
description?: string; // "Phosphoserine; by HIPK4"
begin: string; // "9"
end: string; // "9"
molecule: string;
evidences: UniprotFeatureEvidence[];
molecule?: string;
evidences?: UniprotFeatureEvidence[];
}

export interface UniprotTopology {
type: string; // TOPO_DOM
startPosition: number; // 25
endPosition: number; // 645
description: string; // Extracellular
evidence: UniprotFeatureEvidence[]; // ECO:0000255
description?: string; // Extracellular
evidence?: UniprotFeatureEvidence[]; // ECO:0000255
}
27 changes: 27 additions & 0 deletions packages/cbioportal-utils/src/ptm/PtmUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
compareByPtmTypePriority,
convertDbPtmToPtm,
convertUniprotFeatureToPtm,
getPtmTypeFromUniprotFeature,
getPubmedIdsFromUniprotFeature,
groupPtmDataByPosition,
groupPtmDataByTypeAndPosition,
ptmColor,
Expand Down Expand Up @@ -197,6 +199,15 @@ describe('PtmUtils', () => {
},
];

const partialUniprotPtm = [
{
type: 'MOD_RES',
category: 'PTM',
begin: '2',
end: '2',
},
];

describe('convertToPtmData', () => {
it('identically converts residues for both dbPTM and uniprotPTM data', () => {
assert.deepEqual(
Expand Down Expand Up @@ -341,4 +352,20 @@ describe('PtmUtils', () => {
);
});
});
describe('partial Uniprot data', () => {
it('uses default ptm type when description is empty', () => {
assert.equal(
getPtmTypeFromUniprotFeature(partialUniprotPtm[0]),
'Other',
'Type should be "Other" if no "description" in data'
);
});
it('returns no pubmed ids when evidence is empty', () => {
assert.equal(
getPubmedIdsFromUniprotFeature(partialUniprotPtm[0]).length,
0,
'No pubmed ids could be found if no "evidence" in data'
);
});
});
});
33 changes: 20 additions & 13 deletions packages/cbioportal-utils/src/ptm/PtmUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,12 @@ export function groupPtmDataByTypeAndPosition(
export function ptmColor(ptms: PostTranslationalModification[]) {
let color = PTM_COLORS.default;
const uniqueTypes = _.uniq((ptms || []).map(ptm => ptm.type));

if (uniqueTypes.length === 1) {
color = PTM_COLORS[uniqueTypes[0]] || PTM_COLORS.default;
if (uniqueTypes[0]) {
return PTM_COLORS[uniqueTypes[0]] || PTM_COLORS.default;
} else {
return PTM_COLORS.default;
}
} else if (uniqueTypes.length > 1) {
color = PTM_COLORS.multiType;
}
Expand Down Expand Up @@ -304,25 +307,29 @@ function getResiduesFromUniprotFeature(ptm: UniprotFeature) {

export function getPubmedIdsFromUniprotFeature(ptm: UniprotFeature) {
return ptm.evidences
.filter(
e =>
e.source &&
e.source.name &&
e.source.name.toLowerCase().includes('pubmed')
)
.map(e => e.source!.id);
? ptm.evidences
.filter(
e =>
e.source &&
e.source.name &&
e.source.name.toLowerCase().includes('pubmed')
)
.map(e => e.source!.id)
: [];
}

export function getPtmTypeFromUniprotFeature(ptm: UniprotFeature) {
// actual `type` field provided by the feature itself (MOD_RES, CROSS_LINK, etc.) is not what we want to display
// we need specific PTM types (Ubiquitination, Phosphorylation, etc.)
const keyword = ptm.description.split(';')[0].trim();
let ptmType: PtmType | undefined = KEYWORD_TO_PTM_TYPE[keyword];
const keyword = ptm.description?.split(';')[0].trim();
let ptmType: PtmType | undefined = keyword
? KEYWORD_TO_PTM_TYPE[keyword]
: undefined;

if (!ptmType) {
if (ptm.description.toLowerCase().includes('ubiquitin')) {
if (ptm.description?.toLowerCase().includes('ubiquitin')) {
ptmType = PtmType.Ubiquitination;
} else if (ptm.description.toLowerCase().includes('sumo')) {
} else if (ptm.description?.toLowerCase().includes('sumo')) {
ptmType = PtmType.Sumoylation;
} else {
ptmType = PtmType.Other;
Expand Down
40 changes: 25 additions & 15 deletions packages/cbioportal-utils/src/uniprot/UniprotUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,33 @@ export const UniprotCategory = {
TOPOLOGY: 'TOPOLOGY',
};

function getTopologyTypeName(type: string, description: string | undefined) {
// need to conver TOPO_DOM to detailed type name(e.g. TOPO_DOM_EXTRACELLULAR), keep the same name for TRANSMEM and INTRAMEM
if (type === 'TOPO_DOM') {
return description
? _.toUpper(`${type}_${description.replace(/\s+/g, '_')}`)
: undefined;
} else {
return type;
}
}

export function convertUniprotFeatureToUniprotTopology(
uniprotFeature: UniprotFeature
): UniprotTopology {
return {
type:
uniprotFeature.type === 'TOPO_DOM'
? _.toUpper(
`${
uniprotFeature.type
}_${uniprotFeature.description.replace(/\s+/g, '_')}`
)
: uniprotFeature.type,
startPosition: Number(uniprotFeature.begin),
endPosition: Number(uniprotFeature.end),
description: uniprotFeature.description,
evidence: uniprotFeature.evidences,
};
): UniprotTopology | undefined {
const typeName = getTopologyTypeName(
uniprotFeature.type,
uniprotFeature.description
);
return typeName
? {
type: typeName,
startPosition: Number(uniprotFeature.begin),
endPosition: Number(uniprotFeature.end),
description: uniprotFeature.description,
evidence: uniprotFeature.evidences,
}
: undefined;
}

export const UniprotTopologyTypeToTitle: { [type: string]: string } = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -802,11 +802,12 @@ class DefaultMutationMapperStore<T extends Mutation>
[UniprotCategory.TOPOLOGY]
);
uniprotFeatures.forEach(uniprotFeature => {
data.push(
convertUniprotFeatureToUniprotTopology(
uniprotFeature
)
let uniprotTopology = convertUniprotFeatureToUniprotTopology(
uniprotFeature
);
if (uniprotTopology) {
data.push(uniprotTopology);
}
});
return data;
} else {
Expand Down