Skip to content

Commit

Permalink
Mutational signature plot with cosmic reference signature (cBioPortal…
Browse files Browse the repository at this point in the history
…#4771)

---------

Co-authored-by: 🔧 Ino de Bruijn 🧬 <[email protected]>
  • Loading branch information
TJMKuijpers and inodb authored Jan 31, 2024
1 parent bfe81c1 commit 759b34f
Show file tree
Hide file tree
Showing 23 changed files with 321,485 additions and 407 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion src/pages/patientView/PatientViewPageTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ export function tabs(
<MSKTab
key={8}
id="mutationalSignatures"
linkText="Mutational Signature Data"
linkText="Mutational Signatures"
hide={
pageComponent.patientViewPageStore
.mutationalSignatureMolecularProfiles.isPending ||
Expand Down Expand Up @@ -642,6 +642,10 @@ export function tabs(
pageComponent.patientViewPageStore
.samplesWithCountDataAvailable
}
samplesNotProfiled={
pageComponent.patientViewPageStore
.samplesNotProfiledForMutationalSignatures
}
onSampleChange={pageComponent.onSampleIdChange}
/>
</MSKTab>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as ClinicalInformationMutationalSignatureTable from './ClinicalInformationMutationalSignatureTable';
import React from 'react';
import { assert } from 'chai';
import { prepareMutationalSignatureDataForTable } from './ClinicalInformationMutationalSignatureTable';
import { prepareMutationalSignatureDataForTable } from '../mutationalSignatures/MutationalSignatureBarChartUtils';
import { IMutationalSignature } from 'shared/model/MutationalSignature';

const sampleMutationalSignatureMeta = [
Expand Down Expand Up @@ -84,7 +84,7 @@ describe('ClinicalInformationMutationalSignatureTable', () => {
it('takes mutational signature sample data and formats it for mutational signature table to render', () => {
let result = prepareMutationalSignatureDataForTable(
sampleMutationalSignatureData,
samples
['firstSample', 'secondSample']
);
assert.deepEqual(result, [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,28 @@ import LazyMobXTable, {
} from 'shared/components/lazyMobXTable/LazyMobXTable';
import styles from './style/mutationalSignatureTable.module.scss';
import { SHOW_ALL_PAGE_SIZE } from '../../../shared/components/paginationControls/PaginationControls';
import { IMutationalSignature } from '../../../shared/model/MutationalSignature';
import { getMutationalSignaturePercentage } from '../../../shared/lib/FormatUtils';
import _ from 'lodash';
import { observer } from 'mobx-react';
import { action, computed, makeObservable, observable } from 'mobx';
import { MUTATIONAL_SIGNATURES_SIGNIFICANT_PVALUE_THRESHOLD } from 'shared/lib/GenericAssayUtils/MutationalSignaturesUtils';
import { DownloadControlOption } from 'cbioportal-frontend-commons';
import { getServerConfig } from 'config/config';
import Tooltip from 'rc-tooltip';

import { ILazyMobXTableApplicationDataStore } from 'shared/lib/ILazyMobXTableApplicationDataStore';
export interface IClinicalInformationMutationalSignatureTableProps {
data: IMutationalSignature[];
parentCallback: (childData: string, visibility: boolean) => void;
data: IMutationalSignatureRow[];
url: string;
signature: string;
description: string;
samples: string[];
onRowClick: (d: IMutationalSignatureRow) => void;
onRowMouseEnter?: (d: IMutationalSignatureRow) => void;
onRowMouseLeave?: (d: IMutationalSignatureRow) => void;
dataStore: ILazyMobXTableApplicationDataStore<IMutationalSignatureRow>;
}

class MutationalSignatureTable extends LazyMobXTable<IMutationalSignatureRow> {}

interface IMutationalSignatureRow {
export interface IMutationalSignatureRow {
name: string;
sampleValues: {
[sampleId: string]: {
Expand All @@ -36,55 +37,13 @@ interface IMutationalSignatureRow {
url: string;
}

export function prepareMutationalSignatureDataForTable(
mutationalSignatureData: IMutationalSignature[],
samples: { id: string }[]
): IMutationalSignatureRow[] {
const tableData: IMutationalSignatureRow[] = [];
//group data by mutational signature
//[{id: mutationalsignatureid, samples: [{}, {}]}]
let sampleInvertedDataByMutationalSignature: Array<any> = _(
mutationalSignatureData
)
.groupBy(
mutationalSignatureSample => mutationalSignatureSample.meta.name
)
.map((mutationalSignatureSampleData, name) => ({
name,
samples: mutationalSignatureSampleData,
url: mutationalSignatureSampleData[0].meta.url,
}))
.value();
for (const mutationalSignature of sampleInvertedDataByMutationalSignature) {
let mutationalSignatureRowForTable: IMutationalSignatureRow = {
name: '',
sampleValues: {},
url: '',
};
mutationalSignatureRowForTable.name = mutationalSignature.name;
mutationalSignatureRowForTable.url = mutationalSignature.url;
for (const sample of mutationalSignature.samples) {
mutationalSignatureRowForTable.sampleValues[sample.sampleId] = {
value: sample.value,
confidence: sample.confidence,
};
}
if (
Object.keys(mutationalSignatureRowForTable.sampleValues).length ===
samples.length
) {
tableData.push(mutationalSignatureRowForTable);
}
}
return tableData;
}
@observer
export default class ClinicalInformationMutationalSignatureTable extends React.Component<
IClinicalInformationMutationalSignatureTableProps,
{}
> {
@observable selectedSignature = '';

@observable
selectedSignature: string;
constructor(props: IClinicalInformationMutationalSignatureTableProps) {
super(props);
makeObservable(this);
Expand All @@ -96,40 +55,33 @@ export default class ClinicalInformationMutationalSignatureTable extends React.C
this.selectedSignature = e.currentTarget.innerHTML;
}
@computed get uniqueSamples() {
return _.map(_.uniqBy(this.props.data, 'sampleId'), uniqSample => ({
id: uniqSample.sampleId,
}));
}

@computed get tableData() {
return prepareMutationalSignatureDataForTable(
this.props.data,
this.uniqueSamples
return _.map(
this.props.data.map(x => Object.keys(x.sampleValues))[0],
uniqSample => ({
id: uniqSample,
})
);
}

@computed get tooltipInfo() {
return (
<div
style={{ maxWidth: 450 }}
data-test="SignificantMutationalSignaturesTooltip"
style={{ maxWidth: 400 }}
data-test="SignificantMutationalSignaturesTableTooltip"
>
<div>
<h4>
<b>Signature:</b>
<h5>
<b>Signature: </b>
{this.props.signature}
</h4>
<p>
</h5>
<p style={{ fontSize: '12px' }}>
<b>Description: </b>
{this.props.description}
</p>
<p>
{this.props.url != '' && (
<a href={this.props.url} target="_blank">
External link to signature (opens new tab)
</a>
)}
{this.props.url == '' &&
'No link to external website available'}
<p style={{ fontSize: '12px' }}>
<a href={this.props.url} target="_blank">
External link to signature (opens new tab)
</a>
</p>
</div>
</div>
Expand All @@ -141,17 +93,13 @@ export default class ClinicalInformationMutationalSignatureTable extends React.C
{
name: 'Mutational Signature',
render: (data: IMutationalSignatureRow) => (
<Tooltip overlay={this.tooltipInfo}>
{
<span
onMouseOver={() =>
this.props.parentCallback(data.name, false)
}
>
{data[this.firstCol]}
</span>
}
</Tooltip>
<span>
<a target="_blank">{data[this.firstCol]}</a>
{' '}
<Tooltip overlay={this.tooltipInfo}>
{<i className="fa fa-info-circle"></i>}
</Tooltip>
</span>
),
download: (data: IMutationalSignatureRow) =>
`${data[this.firstCol]}`,
Expand All @@ -174,20 +122,23 @@ export default class ClinicalInformationMutationalSignatureTable extends React.C
MUTATIONAL_SIGNATURES_SIGNIFICANT_PVALUE_THRESHOLD ? ( //if it's a significant signature, bold the contribution
// Based on significant pvalue the span is created with style.mutationalSignatureValue for bold (sign)
// or normal styling (not signficant)
<span className={styles.mutationalSignatureValue}>
<span
className={styles.mutationalSignatureValue}
style={{ float: 'right' }}
>
{getMutationalSignaturePercentage(
data.sampleValues[col.id].value
)}
</span>
) : (
<span>
<span style={{ float: 'right' }}>
{getMutationalSignaturePercentage(
data.sampleValues[col.id].value
)}
</span>
)
) : (
<span>
<span style={{ float: 'right' }}>
{getMutationalSignaturePercentage(
data.sampleValues[col.id].value
)}
Expand All @@ -209,25 +160,27 @@ export default class ClinicalInformationMutationalSignatureTable extends React.C
.indexOf(filterStringUpper) > -1,
sortBy: (data: IMutationalSignatureRow) =>
data.sampleValues[col.id].value,
align: 'right' as 'right',
})),
];
}

public render() {
return (
<MutationalSignatureTable
columns={this.columns}
data={this.tableData}
showPagination={false}
initialItemsPerPage={SHOW_ALL_PAGE_SIZE}
showColumnVisibility={false}
initialSortColumn={this.uniqueSamples[0].id}
initialSortDirection="desc"
showCopyDownload={
getServerConfig().skin_hide_download_controls ===
DownloadControlOption.SHOW_ALL
}
/>
<div style={{ paddingTop: '0' }}>
<MutationalSignatureTable
columns={this.columns}
data={this.props.data}
dataStore={this.props.dataStore}
showPagination={false}
initialItemsPerPage={SHOW_ALL_PAGE_SIZE}
showColumnVisibility={false}
initialSortColumn={this.uniqueSamples[0].id}
initialSortDirection="desc"
onRowClick={this.props.onRowClick}
onRowMouseEnter={this.props.onRowMouseEnter}
/>
</div>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,15 @@ export class PatientViewPageStore {
.filter((value, index, self) => self.indexOf(value) === index);
}

@computed get samplesNotProfiledForMutationalSignatures(): string[] {
const allSamples = this.samplesWithUniqueKeys.result.map(
sample => sample.sampleId
);
return allSamples.filter(
element => !this.samplesWithCountDataAvailable.includes(element)
);
}

readonly samplesWithoutCancerTypeClinicalData = remoteData(
{
await: () => [this.samples, this.clinicalDataForSamples],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const sampleMutationalSignatureData: IMutationalCounts[] = [

describe('MutationalSignatureBarChart', () => {
it('Takes unsorted IMutationalCounts[] and transforms it to sorted IColorDataChart', () => {
let result = getColorsForSignatures(sampleMutationalSignatureData);
let result = getColorsForSignatures(sampleMutationalSignatureData, '%');
assert.deepEqual(result, [
{
uniqueSampleKey: 's09e3B34',
Expand All @@ -97,6 +97,7 @@ describe('MutationalSignatureBarChart', () => {
colorValue: 'red',
label: 'A[C>T]G',
subcategory: ' ',
sublabel: ' ',
group: 'C>T',
},
{
Expand All @@ -112,6 +113,7 @@ describe('MutationalSignatureBarChart', () => {
colorValue: 'red',
label: 'A[C>T]G',
subcategory: ' ',
sublabel: ' ',
group: 'C>T',
},

Expand All @@ -125,16 +127,18 @@ describe('MutationalSignatureBarChart', () => {
mutationalSignatureClass: 'T>A',
version: 'v2',
value: 20,
colorValue: 'grey',
colorValue: '#99A3A4',
subcategory: ' ',
sublabel: ' ',
label: 'A[T>A]G',
group: 'T>A',
},
]);
});
it('Takes unsorted IMutationalCounts[] and transforms it to unsorted IColorDataChart', () => {
let result = getColorsForSignatures(
sampleMutationalSignatureDataWithoutClass
sampleMutationalSignatureDataWithoutClass,
'%'
);
assert.deepEqual(result, [
{
Expand All @@ -149,6 +153,7 @@ describe('MutationalSignatureBarChart', () => {
colorValue: 'red',
label: 'A[C>T]G',
subcategory: ' ',
sublabel: ' ',
mutationalSignatureClass: '',
group: 'C>T',
},
Expand All @@ -164,6 +169,7 @@ describe('MutationalSignatureBarChart', () => {
colorValue: 'red',
label: 'A[C>T]G',
subcategory: ' ',
sublabel: ' ',
mutationalSignatureClass: '',
group: 'C>T',
},
Expand All @@ -180,6 +186,7 @@ describe('MutationalSignatureBarChart', () => {
colorValue: 'red',
label: 'A[C>T]G',
subcategory: ' ',
sublabel: ' ',
mutationalSignatureClass: '',
group: 'C>T',
},
Expand Down
Loading

0 comments on commit 759b34f

Please sign in to comment.