diff --git a/packages/cbioportal-utils/src/model/Uniprot.ts b/packages/cbioportal-utils/src/model/Uniprot.ts index abecdc006ab..eaef258d0c6 100644 --- a/packages/cbioportal-utils/src/model/Uniprot.ts +++ b/packages/cbioportal-utils/src/model/Uniprot.ts @@ -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 } diff --git a/packages/cbioportal-utils/src/ptm/PtmUtils.spec.ts b/packages/cbioportal-utils/src/ptm/PtmUtils.spec.ts index 3f306f7057e..76148552947 100644 --- a/packages/cbioportal-utils/src/ptm/PtmUtils.spec.ts +++ b/packages/cbioportal-utils/src/ptm/PtmUtils.spec.ts @@ -5,6 +5,8 @@ import { compareByPtmTypePriority, convertDbPtmToPtm, convertUniprotFeatureToPtm, + getPtmTypeFromUniprotFeature, + getPubmedIdsFromUniprotFeature, groupPtmDataByPosition, groupPtmDataByTypeAndPosition, ptmColor, @@ -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( @@ -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' + ); + }); + }); }); diff --git a/packages/cbioportal-utils/src/ptm/PtmUtils.ts b/packages/cbioportal-utils/src/ptm/PtmUtils.ts index 8e63ab9a355..8c4723e281a 100644 --- a/packages/cbioportal-utils/src/ptm/PtmUtils.ts +++ b/packages/cbioportal-utils/src/ptm/PtmUtils.ts @@ -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; } @@ -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; diff --git a/packages/cbioportal-utils/src/uniprot/UniprotUtils.ts b/packages/cbioportal-utils/src/uniprot/UniprotUtils.ts index b056b8fc73d..1958f27e64c 100644 --- a/packages/cbioportal-utils/src/uniprot/UniprotUtils.ts +++ b/packages/cbioportal-utils/src/uniprot/UniprotUtils.ts @@ -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 } = { diff --git a/packages/react-mutation-mapper/src/store/DefaultMutationMapperStore.ts b/packages/react-mutation-mapper/src/store/DefaultMutationMapperStore.ts index d24bb308496..cd33fa3acad 100644 --- a/packages/react-mutation-mapper/src/store/DefaultMutationMapperStore.ts +++ b/packages/react-mutation-mapper/src/store/DefaultMutationMapperStore.ts @@ -802,11 +802,12 @@ class DefaultMutationMapperStore [UniprotCategory.TOPOLOGY] ); uniprotFeatures.forEach(uniprotFeature => { - data.push( - convertUniprotFeatureToUniprotTopology( - uniprotFeature - ) + let uniprotTopology = convertUniprotFeatureToUniprotTopology( + uniprotFeature ); + if (uniprotTopology) { + data.push(uniprotTopology); + } }); return data; } else {