import {
defaultSortMethod,
formatFrequencyValue,
formatNumberValueInSignificantDigits,
ISignalTumorTypeDecomposition,
} from 'cbioportal-utils';
import _ from 'lodash';
import React from 'react';
import DefaultTooltip from '../defaultTooltip/DefaultTooltip';
import FrequencyCell from './FrequencyCell';
export enum FrequencyTableColumnEnum {
TUMOR_TYPE = 'tumorType',
MUTATION_STATUS = 'mutationStatus',
SAMPLE_COUNT = 'tumorTypeCount',
VARIANT_COUNT = 'variantCount',
PREVALENCE_FREQUENCY = 'frequency',
BIALLELIC_RATIO = 'biallelicRatio',
MEDIAN_AGE_AT_DX = 'ageAtDx',
MEDIAN_TMB = 'tmb',
MSI_SCORE = 'msiScore',
MEDIAN_HRD_LST = 'lst',
MEDIAN_HRD_NTELOMERIC_AI = 'ntelomericAi',
MEDIAN_HRD_FRACTION_LOH = 'fractionLoh',
OVERALL_NUMBER_OF_GERMLINE_HOMOZYGOUS = 'overallNumberOfGermlineHomozygous',
NUMBER_OF_GERMLINE_HOMOZYGOUS = 'numberOfGermlineHomozygous',
}
export function columnHeader(
headerContent: string | JSX.Element,
overlay: JSX.Element | string
) {
return (
<>{headerContent}>
);
}
export const FREQUENCY_TABLE_HEADER_COMPONENT: { [id: string]: JSX.Element } = {
[FrequencyTableColumnEnum.TUMOR_TYPE]: columnHeader(
Cancer Type,
'Main cancer type based on OncoTree'
),
[FrequencyTableColumnEnum.MUTATION_STATUS]: columnHeader(
Mutation Status,
'Somatic, Pathogenic Germline, or Rare Benign/VUS Germline'
),
[FrequencyTableColumnEnum.SAMPLE_COUNT]: columnHeader(
# Patients,
'Total number of patients'
),
[FrequencyTableColumnEnum.VARIANT_COUNT]: columnHeader(
# Carriers,
'Total number of patients harboring a germline pathogenic variant'
),
[FrequencyTableColumnEnum.NUMBER_OF_GERMLINE_HOMOZYGOUS]: columnHeader(
# Germline Homozygous,
'Number of germline homozygous'
),
[FrequencyTableColumnEnum.PREVALENCE_FREQUENCY]: columnHeader(
% Prevalence,
'# Carriers / # Patients'
),
[FrequencyTableColumnEnum.BIALLELIC_RATIO]: columnHeader(
% Biallelic,
'Fraction of carriers with somatic biallelic inactivation in the corresponding tumor sample.'
),
[FrequencyTableColumnEnum.MEDIAN_AGE_AT_DX]: columnHeader(
Median Age at Dx,
'Median age at diagnosis of carriers'
),
[FrequencyTableColumnEnum.MEDIAN_TMB]: columnHeader(
Median TMB,
'Median tumor mutational burden (TMB)'
),
[FrequencyTableColumnEnum.MSI_SCORE]: columnHeader(
MSI Score,
'Median microsatellite instability (MSI) score determined by MSIsensor'
),
[FrequencyTableColumnEnum.MEDIAN_HRD_LST]: columnHeader(
Median HRD LST,
'Median of LST (large-scale state transitions) scores for carriers (a measure of # of breakpoints between large copy-number segments)'
),
[FrequencyTableColumnEnum.MEDIAN_HRD_NTELOMERIC_AI]: columnHeader(
Median HRD ntelomeric AI,
'Median of HRD-TAI scores for carriers (a measure of allelic imbalance at telomeres)'
),
[FrequencyTableColumnEnum.MEDIAN_HRD_FRACTION_LOH]: columnHeader(
Median HRD Fraction LOH %,
'Median of HRD-LOH scores for carriers (a measure of large LOH regions in the genome)'
),
};
export const FREQUENCY_COLUMNS_DEFINITION = {
[FrequencyTableColumnEnum.TUMOR_TYPE]: {
id: FrequencyTableColumnEnum.TUMOR_TYPE,
Cell: renderTextData,
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.TUMOR_TYPE
],
accessor: FrequencyTableColumnEnum.TUMOR_TYPE,
minWidth: 180,
Footer: Total,
},
[FrequencyTableColumnEnum.MUTATION_STATUS]: {
id: FrequencyTableColumnEnum.MUTATION_STATUS,
Cell: renderTextData,
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.MUTATION_STATUS
],
accessor: FrequencyTableColumnEnum.MUTATION_STATUS,
minWidth: 130,
},
[FrequencyTableColumnEnum.SAMPLE_COUNT]: {
id: FrequencyTableColumnEnum.SAMPLE_COUNT,
Cell: renderNumber,
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.SAMPLE_COUNT
],
accessor: FrequencyTableColumnEnum.SAMPLE_COUNT,
minWidth: 90,
Footer: (col: any) => {
const tumorTypeCount = col.data.reduce(
(sum: any, row: ISignalTumorTypeDecomposition) =>
sum + row.tumorTypeCount,
0
);
return {tumorTypeCount};
},
},
[FrequencyTableColumnEnum.VARIANT_COUNT]: {
id: FrequencyTableColumnEnum.VARIANT_COUNT,
Cell: renderNumber,
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.VARIANT_COUNT
],
accessor: FrequencyTableColumnEnum.VARIANT_COUNT,
minWidth: 90,
Footer: (col: any) => {
const variantCount = col.data.reduce(
(sum: any, row: ISignalTumorTypeDecomposition) =>
sum + row.variantCount,
0
);
return {variantCount};
},
},
[FrequencyTableColumnEnum.NUMBER_OF_GERMLINE_HOMOZYGOUS]: {
id: FrequencyTableColumnEnum.NUMBER_OF_GERMLINE_HOMOZYGOUS,
Cell: renderNumber,
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.NUMBER_OF_GERMLINE_HOMOZYGOUS
],
accessor: FrequencyTableColumnEnum.NUMBER_OF_GERMLINE_HOMOZYGOUS,
sortMethod: defaultSortMethod,
minWidth: 100,
Footer: (col: any) => {
const numberOfGermlineHomozygous = col.data.reduce(
(sum: any, row: ISignalTumorTypeDecomposition) =>
sum + row.numberOfGermlineHomozygous,
0
);
return (
{numberOfGermlineHomozygous}
);
},
},
[FrequencyTableColumnEnum.PREVALENCE_FREQUENCY]: {
id: FrequencyTableColumnEnum.PREVALENCE_FREQUENCY,
Cell: (cell: any) => {
const styles = {
fontWeight: cell.value > 0 ? 'bold' : 'normal',
};
return renderPercentage(cell, styles);
},
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.PREVALENCE_FREQUENCY
],
accessor: FrequencyTableColumnEnum.PREVALENCE_FREQUENCY,
sortMethod: defaultSortMethod,
minWidth: 110,
Footer: (col: any) => {
const tumorTypeCount = col.data.reduce(
(sum: any, row: ISignalTumorTypeDecomposition) =>
sum + row.tumorTypeCount,
0
);
const variantCount = col.data.reduce(
(sum: any, row: ISignalTumorTypeDecomposition) =>
sum + row.variantCount,
0
);
const percent =
formatNumberValueInSignificantDigits(
(variantCount * 100) / tumorTypeCount,
2
) || 0;
return {percent};
},
},
[FrequencyTableColumnEnum.BIALLELIC_RATIO]: {
id: FrequencyTableColumnEnum.BIALLELIC_RATIO,
Cell: renderPercentage,
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.BIALLELIC_RATIO
],
accessor: FrequencyTableColumnEnum.BIALLELIC_RATIO,
sortMethod: defaultSortMethod,
minWidth: 90,
Footer: (col: any) => {
const biallelicTumorCount = col.data.reduce(
(sum: any, row: any) => sum + row._original.biallelicTumorCount,
0
);
const qcPassTumorCount = col.data.reduce(
(sum: any, row: any) => sum + row._original.qcPassTumorCount,
0
);
const percent =
formatNumberValueInSignificantDigits(
(biallelicTumorCount * 100) / qcPassTumorCount,
2
) || 0;
return {percent};
},
},
[FrequencyTableColumnEnum.MEDIAN_AGE_AT_DX]: {
id: FrequencyTableColumnEnum.MEDIAN_AGE_AT_DX,
Cell: renderNumber,
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.MEDIAN_AGE_AT_DX
],
sortMethod: defaultSortMethod,
accessor: FrequencyTableColumnEnum.MEDIAN_AGE_AT_DX,
minWidth: 90,
},
[FrequencyTableColumnEnum.MEDIAN_TMB]: {
id: FrequencyTableColumnEnum.MEDIAN_TMB,
Cell: (column: any) => {
return renderNumber(column, 1);
},
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.MEDIAN_TMB
],
sortMethod: defaultSortMethod,
accessor: FrequencyTableColumnEnum.MEDIAN_TMB,
minWidth: 90,
},
[FrequencyTableColumnEnum.MSI_SCORE]: {
id: FrequencyTableColumnEnum.MSI_SCORE,
Cell: renderNumber,
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.MSI_SCORE
],
sortMethod: defaultSortMethod,
accessor: FrequencyTableColumnEnum.MSI_SCORE,
minWidth: 80,
},
[FrequencyTableColumnEnum.MEDIAN_HRD_LST]: {
id: FrequencyTableColumnEnum.MEDIAN_HRD_LST,
Cell: renderNumber,
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.MEDIAN_HRD_LST
],
sortMethod: defaultSortMethod,
accessor: FrequencyTableColumnEnum.MEDIAN_HRD_LST,
minWidth: 90,
},
[FrequencyTableColumnEnum.MEDIAN_HRD_NTELOMERIC_AI]: {
id: FrequencyTableColumnEnum.MEDIAN_HRD_NTELOMERIC_AI,
Cell: renderNumber,
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.MEDIAN_HRD_NTELOMERIC_AI
],
sortMethod: defaultSortMethod,
accessor: FrequencyTableColumnEnum.MEDIAN_HRD_NTELOMERIC_AI,
minWidth: 100,
},
[FrequencyTableColumnEnum.MEDIAN_HRD_FRACTION_LOH]: {
id: FrequencyTableColumnEnum.MEDIAN_HRD_FRACTION_LOH,
Cell: renderFrequency,
Header:
FREQUENCY_TABLE_HEADER_COMPONENT[
FrequencyTableColumnEnum.MEDIAN_HRD_FRACTION_LOH
],
sortMethod: defaultSortMethod,
accessor: FrequencyTableColumnEnum.MEDIAN_HRD_FRACTION_LOH,
minWidth: 120,
},
};
export function renderPercentage(cellProps: any, styles?: any) {
return ;
}
export function renderNumber(cellProps: any, fractionDigits?: number) {
let displayValue;
if (cellProps.value !== undefined && cellProps.value !== null) {
if (fractionDigits) {
displayValue = cellProps.value.toFixed(fractionDigits);
} else {
displayValue = cellProps.value;
}
} else {
displayValue = '-';
}
return {displayValue};
}
export function renderFrequency(cellProps: any) {
const displayValue =
cellProps.value === 0 ? 0 : formatFrequencyValue(cellProps.value);
return {displayValue};
}
export function renderTextData(cellProps: any) {
return (
{_.upperFirst(cellProps.value)}
);
}