Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
charlesshale committed Sep 23, 2022
2 parents 94e2488 + f5bae70 commit eedf9fd
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 115 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.hartwig.hmftools.common.cuppa.interpretation;

import org.immutables.value.Value;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@Value.Immutable
@Value.Style(passAnnotations = { NotNull.class, Nullable.class })
public abstract class CuppaReporting {

@NotNull
public abstract String bestCancerType();

public abstract double bestLikelihood();

@NotNull
public abstract String interpretCancerType();

@Nullable
public abstract Double interpretLikelihood();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.hartwig.hmftools.common.cuppa.interpretation;

import org.apache.logging.log4j.util.Strings;
import org.jetbrains.annotations.NotNull;

public class CuppaReportingFactory {

private CuppaReportingFactory() {
}

private static final String RESULTS_INCONCLUSIVE = "results inconclusive";

@NotNull
public static String curatedTumorLocation(@NotNull String cancerType) {
if (cancerType.equals("Uterus: Endometrium")) {
cancerType = "Endometrium";
} else if (cancerType.equals("Colorectum/Appendix/SmallIntestine")) {
cancerType = "Lower GI tract";
}
return cancerType;
}

@NotNull
public static String interpretTumorLocation(double likelihood, @NotNull String cancerType) {
// our cut-off is 80% likelihood. When this is below 80% then the results is inconclusive
String interpretCancerType = Strings.EMPTY;
if (likelihood <= 0.8) {
interpretCancerType = RESULTS_INCONCLUSIVE;
} else {
interpretCancerType = cancerType;
}
return interpretCancerType;
}

@NotNull
public static CuppaReporting createCuppaReportingData(@NotNull CuppaPrediction bestPrediction) {
double likelihood = bestPrediction.likelihood();
String cancerType = curatedTumorLocation(bestPrediction.cancerType());
String interpretCancerType = interpretTumorLocation(likelihood, cancerType);
Double interpretLikelihood = likelihood >= 0.5 ? likelihood : null;

return ImmutableCuppaReporting.builder()
.bestCancerType(cancerType)
.bestLikelihood(likelihood)
.interpretCancerType(interpretCancerType)
.interpretLikelihood(interpretLikelihood)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.hartwig.hmftools.common.cuppa.interpretation;

import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

public class CuppaReportingFactoryTest {

private static final double EPSILON = 1.0E-10;

@Test
public void canCreateCuppaReportingKnown() {
CuppaPrediction prediction = ImmutableCuppaPrediction.builder().cancerType("Melanoma").likelihood(0.90).build();
CuppaReporting reporting = CuppaReportingFactory.createCuppaReportingData(prediction);
assertEquals("Melanoma", reporting.bestCancerType());
assertEquals(0.90, reporting.bestLikelihood(), EPSILON);
assertEquals("Melanoma", reporting.interpretCancerType());
assertEquals(0.90, reporting.interpretLikelihood(), EPSILON);
}

@Test
public void canCreateCuppaReportingKnownUterus() {
CuppaPrediction prediction = ImmutableCuppaPrediction.builder().cancerType("Uterus: Endometrium").likelihood(0.90).build();
CuppaReporting reporting = CuppaReportingFactory.createCuppaReportingData(prediction);
assertEquals("Endometrium", reporting.bestCancerType());
assertEquals(0.90, reporting.bestLikelihood(), EPSILON);
assertEquals("Endometrium", reporting.interpretCancerType());
assertEquals(0.90, reporting.interpretLikelihood(), EPSILON);
}

@Test
public void canCreateCuppaReportingKnownColon() {
CuppaPrediction prediction = ImmutableCuppaPrediction.builder().cancerType("Colorectum/Appendix/SmallIntestine").likelihood(0.90).build();
CuppaReporting reporting = CuppaReportingFactory.createCuppaReportingData(prediction);
assertEquals("Lower GI tract", reporting.bestCancerType());
assertEquals(0.90, reporting.bestLikelihood(), EPSILON);
assertEquals("Lower GI tract", reporting.interpretCancerType());
assertEquals(0.90, reporting.interpretLikelihood(), EPSILON);
}

@Test
public void canCreateCuppaReportingInconclusiveWithLikelihood() {
CuppaPrediction prediction = ImmutableCuppaPrediction.builder().cancerType("Melanoma").likelihood(0.60).build();
CuppaReporting reporting = CuppaReportingFactory.createCuppaReportingData(prediction);
assertEquals("Melanoma", reporting.bestCancerType());
assertEquals(0.60, reporting.bestLikelihood(), EPSILON);
assertEquals("results inconclusive", reporting.interpretCancerType());
assertEquals(0.60, reporting.interpretLikelihood(), EPSILON);
}

@Test
public void canCreateCuppaReportingInconclusiveWithoutLikelihood() {
CuppaPrediction prediction = ImmutableCuppaPrediction.builder().cancerType("Melanoma").likelihood(0.40).build();
CuppaReporting reporting = CuppaReportingFactory.createCuppaReportingData(prediction);
assertEquals("Melanoma", reporting.bestCancerType());
assertEquals(0.40, reporting.bestLikelihood(), EPSILON);
assertEquals("results inconclusive", reporting.interpretCancerType());
assertNull(reporting.interpretLikelihood());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ public static HaplotypeQC create(
if(inPon(unmatched))
{
pon++;
LL_LOGGER.info(" UNMATCHED_PON_HAPLTOYPE - {}", unmatched);
LL_LOGGER.info(" UNMATCHED_PON_HAPLOTYPE - {}", unmatched);
}
else
{
maxSupport = max(maxSupport, unmatched.matchingFragmentCount());
unusedCount++;
LL_LOGGER.info(" UNMATCHED_HAPLTOYPE {}", unmatched);
LL_LOGGER.info(" UNMATCHED_HAPLOTYPE {}", unmatched);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import java.util.List;
import java.util.Optional;

import com.hartwig.hmftools.common.cuppa.interpretation.CuppaPrediction;
import com.hartwig.hmftools.common.cuppa.interpretation.CuppaReporting;
import com.hartwig.hmftools.common.peach.PeachGenotype;
import com.hartwig.hmftools.patientreporter.PatientReport;
import com.hartwig.hmftools.patientreporter.SampleReport;
Expand Down Expand Up @@ -38,7 +38,7 @@ public abstract class AnalysedPatientReport implements PatientReport {
public abstract GenomicAnalysis genomicAnalysis();

@Nullable
public abstract CuppaPrediction cuppaPrediction();
public abstract CuppaReporting cuppaReporting();

@Nullable
public abstract String cuppaPlot();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
import com.hartwig.hmftools.common.cuppa.CuppaDataFile;
import com.hartwig.hmftools.common.cuppa.interpretation.CuppaPrediction;
import com.hartwig.hmftools.common.cuppa.interpretation.CuppaPredictionFactory;
import com.hartwig.hmftools.common.cuppa.interpretation.ImmutableCuppaPrediction;
import com.hartwig.hmftools.common.cuppa.interpretation.CuppaReporting;
import com.hartwig.hmftools.common.cuppa.interpretation.CuppaReportingFactory;
import com.hartwig.hmftools.common.lims.LimsGermlineReportingLevel;
import com.hartwig.hmftools.common.peach.PeachGenotype;
import com.hartwig.hmftools.common.peach.PeachGenotypeFile;
Expand Down Expand Up @@ -95,12 +96,7 @@ public AnalysedPatientReport run(@NotNull SampleMetadata sampleMetadata, @NotNul

List<CuppaPrediction> predictions = CuppaPredictionFactory.create(cuppaEntries);
CuppaPrediction best = predictions.get(0);
if (best.likelihood() > 0.8) {
best = predictions.get(0);
} else {
// our cut-off is 80% likelihood. When this is below 80% then the results is inconclusive
best = ImmutableCuppaPrediction.builder().cancerType("results inconclusive").likelihood(0).build();
}
CuppaReporting cuppaReporting = CuppaReportingFactory.createCuppaReportingData(best);

LOGGER.info(" Predicted cancer type '{}' with likelihood {}", best.cancerType(), best.likelihood());

Expand All @@ -117,10 +113,10 @@ public AnalysedPatientReport run(@NotNull SampleMetadata sampleMetadata, @NotNul
.specialRemark(specialRemark)
.pipelineVersion(pipelineVersion)
.genomicAnalysis(curateGeneName)
.cuppaPrediction(
.cuppaReporting(
curateGeneName.purpleQCStatus().contains(PurpleQCStatus.FAIL_CONTAMINATION) || !curateGeneName.hasReliablePurity()
? null
: best)
: cuppaReporting)
.cuppaPlot(config.cuppaPlot())
.circosPath(config.purpleCircosPlot())
.comments(Optional.ofNullable(config.comments()))
Expand Down Expand Up @@ -179,8 +175,8 @@ private static void printReportState(@NotNull AnalysedPatientReport report) {
GenomicAnalysis analysis = report.genomicAnalysis();

LOGGER.info("Printing genomic analysis results for {}:", report.sampleReport().tumorSampleId());
if (report.cuppaPrediction() != null) {
LOGGER.info(" Molecular tissue origin conclusion: {}", report.cuppaPrediction().cancerType());
if (report.cuppaReporting() != null) {
LOGGER.info(" Molecular tissue origin conclusion: {}", report.cuppaReporting().interpretCancerType());
}
LOGGER.info(" Somatic variants to report: {}", analysis.reportableVariants().size());
if (report.sampleReport().germlineReportingLevel() != LimsGermlineReportingLevel.NO_REPORTING) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,15 @@ private void renderTumorCharacteristics(@NotNull Document reportDocument) {
TumorPurity.RANGE_MAX,
table);

String cuppaPrediction = patientReport.cuppaPrediction() != null && patientReport.genomicAnalysis().hasReliablePurity()
? patientReport.cuppaPrediction().cancerType() + " (" + patientReport.cuppaPrediction().likelihood() + ")"
: DataUtil.NA_STRING;
String cuppaPrediction = Strings.EMPTY;
if (patientReport.cuppaReporting() != null && patientReport.genomicAnalysis().hasReliablePurity()) {
if (patientReport.cuppaReporting().interpretLikelihood() == null) {
cuppaPrediction = patientReport.cuppaReporting().interpretCancerType();
} else {
cuppaPrediction = patientReport.cuppaReporting().interpretCancerType() + " (" + patientReport.cuppaReporting().interpretLikelihood() + ")";
}
}

Style dataStyleMolecularTissuePrediction =
hasReliablePurity ? ReportResources.dataHighlightStyle() : ReportResources.dataHighlightNaStyle();

Expand Down Expand Up @@ -445,17 +451,15 @@ private void renderGermlineText(@NotNull Document reportDocument) {
String text = "Data concerning cancer predisposition genes may be requested by a clinical geneticist after the patient has "
+ "given informed consent.";

Div div = createSectionStartDiv(contentWidth());
div.add(new Paragraph("Germline results").addStyle(ReportResources.sectionTitleStyle()));
Div div = createSectionStartDiv(contentWidth());
div.add(new Paragraph("Germline results").addStyle(ReportResources.sectionTitleStyle()));

div.add(new Paragraph(text).setWidth(contentWidth()).addStyle(ReportResources.bodyTextStyle()).setFixedLeading(11));
div.add(new Paragraph(text).setWidth(contentWidth()).addStyle(ReportResources.bodyTextStyle()).setFixedLeading(11));

reportDocument.add(div);
reportDocument.add(div);

}



@NotNull
@VisibleForTesting
static Set<String> sortGenes(@NotNull Set<String> driverVariantGenes) {
Expand Down
Loading

0 comments on commit eedf9fd

Please sign in to comment.