diff --git a/build.gradle b/build.gradle index c9a174dc825..184dec2632c 100644 --- a/build.gradle +++ b/build.gradle @@ -69,10 +69,10 @@ final genomicsdbVersion = System.getProperty('genomicsdb.version','1.5.4') final bigQueryVersion = System.getProperty('bigQuery.version', '2.35.0') final bigQueryStorageVersion = System.getProperty('bigQueryStorage.version', '2.47.0') final guavaVersion = System.getProperty('guava.version', '32.1.3-jre') -final log4j2Version = System.getProperty('log4j2Version', '2.17.1') -final testNGVersion = '7.7.0' - -final googleCloudNioDependency = 'com.google.cloud:google-cloud-nio:0.127.8' +final log4j2Version = System.getProperty('log4j2Version', '2.24.1') +final testNGVersion = System.getProperty('testNGVersion', '7.7.0') +final googleCloudNioVersion = System.getProperty('googleCloudNioVersion','0.127.8') +final gklVersion = System.getProperty('gklVersion', '0.8.11') final baseJarName = 'gatk' final secondaryBaseJarName = 'hellbender' @@ -166,27 +166,12 @@ if (versionOverridden) { } configurations.configureEach { - resolutionStrategy { - // the snapshot folder contains a dev version of guava, we don't want to use that. - force 'com.google.guava:guava:' + guavaVersion - // force the htsjdk version so we don't get a different one transitively - force 'com.github.samtools:htsjdk:' + htsjdkVersion - force 'com.google.protobuf:protobuf-java:3.25.5' - // force testng dependency so we don't pick up a different version via GenomicsDB - force 'org.testng:testng:' + testNGVersion - force 'org.broadinstitute:barclay:' + barclayVersion - force 'com.twitter:chill_2.12:0.10.0' - force 'org.apache.commons:commons-math3:3.5' - - // make sure we don't pick up an incorrect version of the GATK variant of the google-nio library - // via Picard, etc. - force googleCloudNioDependency - - force 'com.esotericsoftware:kryo:4.0.0' - } configurations*.exclude group: 'org.slf4j', module: 'slf4j-jdk14' //exclude this to prevent slf4j complaining about to many slf4j bindings configurations*.exclude group: 'com.google.guava', module: 'guava-jdk5' configurations*.exclude group: 'junit', module: 'junit' + + //this is excluded and replaced below with a dependency on bcprof-jdk18on which fixes known vulnerabilities + //configurations*.exclude group: 'org.bouncycastle', module: 'bcprov-jdk15on' } tasks.withType(JavaCompile).configureEach { @@ -221,13 +206,13 @@ configurations { // exclude Hadoop and Spark dependencies, since they are provided when running with Spark // (ref: http://unethicalblogger.com/2015/07/15/gradle-goodness-excluding-depends-from-shadow.html) exclude group: 'org.apache.hadoop' - exclude module: 'spark-core_2.12' + exclude module: 'spark-core_2.13' exclude group: 'org.slf4j' exclude module: 'jul-to-slf4j' exclude module: 'javax.servlet' exclude module: 'servlet-api' exclude group: 'com.esotericsoftware.kryo' - exclude module: 'spark-mllib_2.12.15' + exclude module: 'spark-mllib_2.13.15' exclude group: 'org.scala-lang' exclude module: 'kryo' } @@ -235,23 +220,33 @@ configurations { dependencies { - implementation ('org.freemarker:freemarker:2.3.30') - implementation 'org.broadinstitute:barclay:' + barclayVersion + implementation 'org.freemarker:freemarker:2.3.30' + implementation ('org.broadinstitute:barclay'){ + version { + strictly barclayVersion + } + } // Library for configuration: implementation 'org.aeonbits.owner:owner:1.0.9' implementation 'com.github.broadinstitute:picard:' + picardVersion externalSourceConfiguration 'com.github.broadinstitute:picard:' + picardVersion + ':sources' - implementation ('org.genomicsdb:genomicsdb:' + genomicsdbVersion) { - exclude module: 'log4j-api' - exclude module: 'log4j-core' - exclude module: 'htsjdk' - exclude module: 'protobuf-java' - } + + implementation 'org.genomicsdb:genomicsdb:' + genomicsdbVersion implementation 'com.opencsv:opencsv:3.4' implementation 'com.google.guava:guava:' + guavaVersion - implementation 'com.github.samtools:htsjdk:'+ htsjdkVersion - implementation(googleCloudNioDependency) + + implementation ('com.github.samtools:htsjdk'){ + version { + strictly htsjdkVersion + } + } + + implementation ('com.google.cloud:google-cloud-nio'){ + version { + strictly googleCloudNioVersion + } + } implementation 'com.google.cloud:google-cloud-bigquery:' + bigQueryVersion implementation 'com.google.cloud:google-cloud-bigquerystorage:' + bigQueryStorageVersion @@ -263,27 +258,32 @@ dependencies { // should we want to) implementation 'com.google.cloud.bigdataoss:gcs-connector:1.9.4-hadoop3' - implementation 'org.apache.logging.log4j:log4j-api:' + log4j2Version - implementation 'org.apache.logging.log4j:log4j-core:' + log4j2Version + implementation platform('org.apache.logging.log4j:log4j-bom:' + log4j2Version) + implementation 'org.apache.logging.log4j:log4j-api' + implementation 'org.apache.logging.log4j:log4j-core' // include the apache commons-logging bridge that matches the log4j version we use so // messages that originate with dependencies that use commons-logging (such as jexl) // are routed to log4j - implementation 'org.apache.logging.log4j:log4j-jcl:' + log4j2Version + implementation 'org.apache.logging.log4j:log4j-jcl' + // these two annotation dependencies + // are needed because log4j-core isn't meant to be included + // at compile time so it doesn't include its own annotations + // https://github.com/apache/logging-log4j2/issues/3110 + implementation 'biz.aQute.bnd:biz.aQute.bnd.annotation' + implementation 'org.osgi:org.osgi.annotation.bundle' + implementation 'org.apache.commons:commons-lang3:3.14.0' - implementation 'org.apache.commons:commons-math3:3.6.1' + implementation('org.apache.commons:commons-math3'){ + version { + strictly '3.5' // changing this breaks ModelSegmentsIntegrationTests, they're quite brittle + } + because "updating this breaks ModelSegmentsIntegrationTests, they're quite brittle" + } implementation 'org.hipparchus:hipparchus-stat:2.0' implementation 'org.apache.commons:commons-collections4:4.4' implementation 'org.apache.commons:commons-vfs2:2.9.0' implementation 'org.apache.commons:commons-configuration2:2.10.1' - constraints { - implementation('org.apache.commons:commons-text') { - version { - strictly '1.10.0' - } - because 'previous versions have a nasty vulnerability: https://nvd.nist.gov/vuln/detail/CVE-2022-42889' - } - } implementation 'org.apache.httpcomponents:httpclient:4.5.13' implementation 'commons-beanutils:commons-beanutils:1.9.4' @@ -296,12 +296,11 @@ dependencies { implementation 'org.broadinstitute:gatk-native-bindings:1.0.0' implementation 'org.ojalgo:ojalgo:44.0.0' - implementation ('org.ojalgo:ojalgo-commons-math3:1.0.0') { + implementation('org.ojalgo:ojalgo-commons-math3:1.0.0'){ exclude group: 'org.apache.commons' } - // TODO: migrate to mllib_2.12.15? - implementation ('org.apache.spark:spark-mllib_2.12:' + sparkVersion) { + implementation ('org.apache.spark:spark-mllib_2.13:' + sparkVersion) { // JUL is used by Google Dataflow as the backend logger, so exclude jul-to-slf4j to avoid a loop exclude module: 'jul-to-slf4j' exclude module: 'javax.servlet' @@ -312,28 +311,29 @@ dependencies { implementation 'org.jgrapht:jgrapht-core:1.1.0' implementation 'org.jgrapht:jgrapht-io:1.1.0' - implementation('org.disq-bio:disq:' + disqVersion) - implementation('org.apache.hadoop:hadoop-client:' + hadoopVersion) // should be a 'provided' dependency - implementation('com.github.jsr203hadoop:jsr203hadoop:1.0.3') + implementation 'org.disq-bio:disq:' + disqVersion + implementation 'org.apache.hadoop:hadoop-client:' + hadoopVersion // should be a 'provided' dependency + implementation 'com.github.jsr203hadoop:jsr203hadoop:1.0.3' - implementation('org.apache.orc:orc:1.6.5') - implementation('de.javakaffee:kryo-serializers:0.45') { - exclude module: 'kryo' // use Spark's version + implementation 'org.apache.orc:orc:1.6.5' + implementation 'de.javakaffee:kryo-serializers:0.45' + implementation ('com.esotericsoftware:kryo'){ + version { + strictly '[4,5)' // we're not compatible with kryo 5+ + } } // Dependency change for including MLLib - implementation('org.objenesis:objenesis:1.2') - testImplementation('org.objenesis:objenesis:2.1') + implementation 'org.objenesis:objenesis:1.2' + testImplementation 'org.objenesis:objenesis:2.1' // Comment the next lines to disable native code proxies in Spark MLLib - implementation('com.github.fommil.netlib:netlib-native_ref-osx-x86_64:1.1:natives') - implementation('com.github.fommil.netlib:netlib-native_ref-linux-x86_64:1.1:natives') - implementation('com.github.fommil.netlib:netlib-native_system-linux-x86_64:1.1:natives') - implementation('com.github.fommil.netlib:netlib-native_system-osx-x86_64:1.1:natives') + implementation 'com.github.fommil.netlib:netlib-native_ref-osx-x86_64:1.1:natives' + implementation 'com.github.fommil.netlib:netlib-native_ref-linux-x86_64:1.1:natives' + implementation 'com.github.fommil.netlib:netlib-native_system-linux-x86_64:1.1:natives' + implementation 'com.github.fommil.netlib:netlib-native_system-osx-x86_64:1.1:natives' - implementation('com.intel.gkl:gkl:0.8.11') { - exclude module: 'htsjdk' - } + implementation 'com.intel.gkl:gkl:' + gklVersion implementation 'org.broadinstitute:gatk-bwamem-jni:1.0.4' implementation 'org.broadinstitute:gatk-fermilite-jni:1.2.0' @@ -344,12 +344,50 @@ dependencies { implementation 'org.xerial:sqlite-jdbc:3.44.1.0' // natural sort - implementation('net.grey-panther:natural-comparator:1.1') - implementation('com.fasterxml.jackson.module:jackson-module-scala_2.12:2.9.8') + implementation 'net.grey-panther:natural-comparator:1.1' + implementation 'com.fasterxml.jackson.module:jackson-module-scala_2.13:2.9.8' + + /********* Update transitive dependencies that have known vulnerabilities in this section *******/ + constraints { + // all of these constraints are here to force upgrades from lower versions of these libraries which are included + // as transitive dependencies + // once the libraries that make use of these move forward we can remove these constraints + + implementation 'com.google.protobuf:protobuf-java:3.25.5' + implementation 'dnsjava:dnsjava:3.6.0' + implementation 'org.apache.commons:commons-compress:1.26.0' + implementation 'org.apache.ivy:ivy:2.5.2' + implementation 'org.apache.commons:commons-text:1.10.0' because 'of https://nvd.nist.gov/vuln/detail/CVE-2022-42889' + implementation 'ch.qos.logback:logback-classic:1.4.14' + implementation 'ch.qos.logback:logback-core:1.4.14' + implementation 'org.apache.avro:avro:1.12.0' + implementation 'io.airlift:aircompressor:0.27' + implementation 'org.scala-lang:scala-library:2.13.14' + implementation 'com.nimbusds:nimbus-jose-jwt:9.41.2' + implementation 'org.codehaus.janino:janino:3.1.12' + implementation 'org.apache.zookeeper:zookeeper:3.9.2' + implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.9.25' + implementation 'com.squareup.okio:okio:3.9.1' + implementation 'org.codehaus.jettison:jettison:1.5.4' + implementation 'org.xerial.snappy:snappy-java:1.1.10.4' + } + + //use netty bom to enforce same netty version + //this upgrades all transitive netty dependencies without adding a direct dependency on netty + implementation platform('io.netty:netty-bom:4.1.114.Final') + + implementation platform('org.eclipse.jetty:jetty-bom:9.4.56.v20240826') + /************************************************************************************************/ + testUtilsImplementation sourceSets.main.output testUtilsImplementation 'org.testng:testng:' + testNGVersion testUtilsImplementation 'org.apache.hadoop:hadoop-minicluster:' + hadoopVersion + //this is a replacement for the transitive dependency of minicluster: bcprov-jdk15on:1.70.0 + // which is excluded for security purposes + //this causes this to act as direct dependency of ours but we don't actually rely on it except as a transitive + testUtilsImplementation 'org.bouncycastle:bcprov-jdk18on:1.78.1' // + testImplementation sourceSets.testUtils.output diff --git a/src/main/java/org/broadinstitute/hellbender/engine/spark/RangePartitionCoalescer.java b/src/main/java/org/broadinstitute/hellbender/engine/spark/RangePartitionCoalescer.java index fc1105c7d14..a3691154367 100644 --- a/src/main/java/org/broadinstitute/hellbender/engine/spark/RangePartitionCoalescer.java +++ b/src/main/java/org/broadinstitute/hellbender/engine/spark/RangePartitionCoalescer.java @@ -4,9 +4,9 @@ import org.apache.spark.rdd.PartitionCoalescer; import org.apache.spark.rdd.PartitionGroup; import org.apache.spark.rdd.RDD; -import scala.collection.JavaConversions; import scala.collection.Seq; - +import scala.jdk.javaapi.CollectionConverters; +import java.io.Serial; import java.io.Serializable; import java.util.Arrays; import java.util.List; @@ -14,8 +14,9 @@ /** * A {@link PartitionCoalescer} that allows a range of partitions to be coalesced into groups. */ -class RangePartitionCoalescer implements PartitionCoalescer, Serializable, scala.Serializable { +class RangePartitionCoalescer implements PartitionCoalescer, Serializable { + @Serial private static final long serialVersionUID = 1L; private List maxEndPartitionIndexes; @@ -45,7 +46,7 @@ public PartitionGroup[] coalesce(int maxPartitions, RDD parent) { PartitionGroup group = new PartitionGroup(preferredLocation); List partitionsInGroup = partitions.subList(i, maxEndPartitionIndexes.get(i) + 1); - group.partitions().append(JavaConversions.asScalaBuffer(partitionsInGroup)); + group.partitions().addAll(CollectionConverters.asScala(partitionsInGroup).toList()); groups[i] = group; } return groups; diff --git a/src/main/java/org/broadinstitute/hellbender/tools/funcotator/BaseFuncotatorArgumentCollection.java b/src/main/java/org/broadinstitute/hellbender/tools/funcotator/BaseFuncotatorArgumentCollection.java index afe0b5d6676..cf283d44008 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/funcotator/BaseFuncotatorArgumentCollection.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/funcotator/BaseFuncotatorArgumentCollection.java @@ -80,6 +80,14 @@ public abstract class BaseFuncotatorArgumentCollection implements Serializable { ) public TranscriptSelectionMode transcriptSelectionMode = FuncotatorArgumentDefinitions.TRANSCRIPT_SELECTION_MODE_DEFAULT_VALUE; + @Advanced + @Argument( + fullName = FuncotatorArgumentDefinitions.PREFER_MANE_TRANSCRIPT_MODE, + optional = true, + doc = "If this flag is set, Funcotator will prefer 'MANE_Plus_Clinical' followed by 'MANE_select' transcripts (including those not tagged 'basic') if one is present for a given variant. If neither tag is present it use the default behavior (only base transcripts)." + ) + public boolean MANETranscriptMode = false; + @Argument( fullName = FuncotatorArgumentDefinitions.TRANSCRIPT_LIST_LONG_NAME, optional = true, diff --git a/src/main/java/org/broadinstitute/hellbender/tools/funcotator/FuncotateSegments.java b/src/main/java/org/broadinstitute/hellbender/tools/funcotator/FuncotateSegments.java index 15f4e1dc41b..beba85c3d54 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/funcotator/FuncotateSegments.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/funcotator/FuncotateSegments.java @@ -147,7 +147,8 @@ public void onTraversalStart() { new FlankSettings(0,0), true, funcotatorArgs.minNumBasesForValidSegment, - funcotatorArgs.spliceSiteWindow + funcotatorArgs.spliceSiteWindow, + funcotatorArgs.MANETranscriptMode ).stream() .filter(DataSourceFuncotationFactory::isSupportingSegmentFuncotation) .collect(Collectors.toList()); diff --git a/src/main/java/org/broadinstitute/hellbender/tools/funcotator/Funcotator.java b/src/main/java/org/broadinstitute/hellbender/tools/funcotator/Funcotator.java index 12843950a48..e8a74603fc1 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/funcotator/Funcotator.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/funcotator/Funcotator.java @@ -794,7 +794,8 @@ public void onTraversalStart() { new FlankSettings(funcotatorArgs.fivePrimeFlankSize, funcotatorArgs.threePrimeFlankSize), false, funcotatorArgs.minNumBasesForValidSegment, - funcotatorArgs.spliceSiteWindow + funcotatorArgs.spliceSiteWindow, + funcotatorArgs.MANETranscriptMode ); logger.info("Initializing Funcotator Engine..."); diff --git a/src/main/java/org/broadinstitute/hellbender/tools/funcotator/FuncotatorArgumentDefinitions.java b/src/main/java/org/broadinstitute/hellbender/tools/funcotator/FuncotatorArgumentDefinitions.java index 09ec1e3ada8..bf04ea3aa9e 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/funcotator/FuncotatorArgumentDefinitions.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/funcotator/FuncotatorArgumentDefinitions.java @@ -36,6 +36,8 @@ public class FuncotatorArgumentDefinitions { public static final String TRANSCRIPT_SELECTION_MODE_LONG_NAME = "transcript-selection-mode"; public static final TranscriptSelectionMode TRANSCRIPT_SELECTION_MODE_DEFAULT_VALUE = TranscriptSelectionMode.CANONICAL; + public static final String PREFER_MANE_TRANSCRIPT_MODE = "prefer-mane-transcripts"; + /** * Do not give this a static default value or the integration tests will get hosed. */ diff --git a/src/main/java/org/broadinstitute/hellbender/tools/funcotator/dataSources/DataSourceUtils.java b/src/main/java/org/broadinstitute/hellbender/tools/funcotator/dataSources/DataSourceUtils.java index 01791264a01..fcc39124ca8 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/funcotator/dataSources/DataSourceUtils.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/funcotator/dataSources/DataSourceUtils.java @@ -329,6 +329,7 @@ private static boolean isValidDirectory(final Path p) { * ignored for those that don't. * @param minBasesForValidSegment The minimum number of bases for a segment to be considered valid. * @param spliceSiteWindowSize The number of bases on either side of a splice site for a variant to be a {@link org.broadinstitute.hellbender.tools.funcotator.dataSources.gencode.GencodeFuncotation.VariantClassification#SPLICE_SITE} variant. + * @param preferMANETranscriptsWhereApplicable If this is set, in {@link GencodeFuncotationFactory}, we will only emit MANE transcripts if any are availible for a given variant, otherwise behaves as normal. * @return A {@link List} of {@link DataSourceFuncotationFactory} given the data source metadata, overrides, and transcript reporting priority information. */ public static List createDataSourceFuncotationFactoriesForDataSources(final Map dataSourceMetaData, @@ -340,7 +341,8 @@ public static List createDataSourceFuncotationFact final FlankSettings flankSettings, final boolean doAttemptSegmentFuncotationForTranscriptDatasources, final int minBasesForValidSegment, - final int spliceSiteWindowSize) { + final int spliceSiteWindowSize, + final boolean preferMANETranscriptsWhereApplicable) { Utils.nonNull(dataSourceMetaData); Utils.nonNull(annotationOverridesMap); Utils.nonNull(transcriptSelectionMode); @@ -379,7 +381,7 @@ public static List createDataSourceFuncotationFact case GENCODE: featureInput = createAndRegisterFeatureInputs(path, properties, gatkToolInstance, lookaheadFeatureCachingInBp, GencodeGtfFeature.class, false); funcotationFactory = DataSourceUtils.createGencodeDataSource(path, properties, annotationOverridesMap, transcriptSelectionMode, - userTranscriptIdSet, featureInput, flankSettings, doAttemptSegmentFuncotationForTranscriptDatasources, minBasesForValidSegment, spliceSiteWindowSize); + userTranscriptIdSet, featureInput, flankSettings, doAttemptSegmentFuncotationForTranscriptDatasources, minBasesForValidSegment, spliceSiteWindowSize, preferMANETranscriptsWhereApplicable); break; case VCF: featureInput = createAndRegisterFeatureInputs(path, properties, gatkToolInstance, lookaheadFeatureCachingInBp, VariantContext.class, false); @@ -596,7 +598,8 @@ private static GencodeFuncotationFactory createGencodeDataSource(final Path data final FlankSettings flankSettings, final boolean isSegmentFuncotationEnabled, final int minBasesForValidSegment, - final int spliceSiteWindowSize) { + final int spliceSiteWindowSize, + final boolean onlyUseMANETranscriptsWhenApplicable) { Utils.nonNull(dataSourceFile); Utils.nonNull(dataSourceProperties); Utils.nonNull(annotationOverridesMap); @@ -626,7 +629,8 @@ private static GencodeFuncotationFactory createGencodeDataSource(final Path data ncbiBuildVersion, isSegmentFuncotationEnabled, minBasesForValidSegment, - spliceSiteWindowSize + spliceSiteWindowSize, + onlyUseMANETranscriptsWhenApplicable ); } diff --git a/src/main/java/org/broadinstitute/hellbender/tools/funcotator/dataSources/gencode/GencodeFuncotationFactory.java b/src/main/java/org/broadinstitute/hellbender/tools/funcotator/dataSources/gencode/GencodeFuncotationFactory.java index ec65f35c2b0..0565ca6ce4c 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/funcotator/dataSources/gencode/GencodeFuncotationFactory.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/funcotator/dataSources/gencode/GencodeFuncotationFactory.java @@ -242,6 +242,11 @@ public class GencodeFuncotationFactory extends DataSourceFuncotationFactory { */ private boolean isSegmentFuncotationEnabled; + /** + * If this is true, only MANE transcripts will be used for funcotation creation when at least one is present. + */ + private boolean preferMANETranscripts; + //================================================================================================================== // Constructors: @@ -354,7 +359,7 @@ public GencodeFuncotationFactory(final Path gencodeTranscriptFastaFilePath, this(gencodeTranscriptFastaFilePath, version, name, transcriptSelectionMode, userRequestedTranscripts, annotationOverrides, mainFeatureInput, flankSettings, isDataSourceB37, ncbiBuildVersion, - isSegmentFuncotationEnabled, minBasesForValidSegment, FuncotatorUtils.DEFAULT_SPLICE_SITE_WINDOW_SIZE); + isSegmentFuncotationEnabled, minBasesForValidSegment, FuncotatorUtils.DEFAULT_SPLICE_SITE_WINDOW_SIZE, false); } /** @@ -385,7 +390,8 @@ public GencodeFuncotationFactory(final Path gencodeTranscriptFastaFilePath, final String ncbiBuildVersion, final boolean isSegmentFuncotationEnabled, final int minBasesForValidSegment, - final int spliceSiteWindowSize) { + final int spliceSiteWindowSize, + final boolean preferMANETranscriptsWhereApplicable) { super(mainFeatureInput, minBasesForValidSegment); @@ -429,6 +435,8 @@ public GencodeFuncotationFactory(final Path gencodeTranscriptFastaFilePath, // Initialize overrides / defaults: initializeAnnotationOverrides( annotationOverrides ); + + this.preferMANETranscripts = preferMANETranscriptsWhereApplicable; } private Path localizeGencodeTranscriptFastaFile( final Path gencodeTranscriptFastaFilePath ) { @@ -622,6 +630,28 @@ private static List convertFeaturesToGencodeGtfGeneFeatur .collect(Collectors.toList()); } + /** + * If MANE_Plus_Clinical transcripts are avalible, only return them, followed by MANE_Select transcripts, followed by only the basic transcripts if none were MANE_Plus_Clinical or MANE_Select. + * @param transcripts of gencode transcripts to possibly filter + * @return + */ + @VisibleForTesting + static List retreiveMANESelectModeTranscriptsCriteria(final List transcripts) { + final List plusClincal = transcripts.stream() + .filter(g -> hasTag(g, MANE_PLUS_CLINICAL)).toList(); + if (plusClincal.size() > 0) { + return plusClincal; + } + + final List maneSelectTranscripts = transcripts.stream() + .filter(g -> hasTag(g, MANE_SELECT)).toList(); + + if (maneSelectTranscripts.size() > 0) { + return maneSelectTranscripts; + } + + return transcripts.stream().filter(GencodeFuncotationFactory::isBasic).collect(Collectors.toList()); + } /** * {@inheritDoc} @@ -853,16 +883,21 @@ static boolean isVariantInCodingRegion(final GencodeFuncotation.VariantClassific */ private List createFuncotationsHelper(final VariantContext variant, final Allele altAllele, final GencodeGtfGeneFeature gtfFeature, final ReferenceContext reference) { - final List transcriptList; + List transcriptList; // Only get basic transcripts if we're using data from Gencode: if ( gtfFeature.getGtfSourceFileType().equals(GencodeGtfCodec.GTF_FILE_TYPE_STRING) ) { - transcriptList = retrieveBasicTranscripts(gtfFeature); - } - else { + if (preferMANETranscripts) { + // Filter out the non-MANE_Select/Mane_Plus_Clinical transcripts if we're only using MANE transcripts: + transcriptList = retreiveMANESelectModeTranscriptsCriteria(gtfFeature.getTranscripts()); + } else { + transcriptList = retrieveBasicTranscripts(gtfFeature); + } + } else { transcriptList = gtfFeature.getTranscripts(); } + return createFuncotationsHelper(variant, altAllele, reference, transcriptList); } @@ -979,9 +1014,14 @@ static final GencodeFuncotation createDefaultFuncotationsOnProblemVariant( final private static boolean isBasic(final GencodeGtfTranscriptFeature transcript) { // Check if this transcript has the `basic` tag: + return hasTag(transcript, GencodeGTFFieldConstants.FeatureTag.BASIC); + } + + private static boolean hasTag(final GencodeGtfTranscriptFeature transcript, final GencodeGTFFieldConstants.FeatureTag tag) { + // Check if this transcript has the given tag: return transcript.getOptionalFields().stream() .filter( f -> f.getName().equals("tag") ) - .filter( f -> f.getValue().equals(GencodeGTFFieldConstants.FeatureTag.BASIC.toString()) ) + .filter( f -> f.getValue().equals(tag.toString()) ) .count() > 0; } diff --git a/src/main/java/org/broadinstitute/hellbender/tools/spark/pathseq/PSBuildReferenceTaxonomyUtils.java b/src/main/java/org/broadinstitute/hellbender/tools/spark/pathseq/PSBuildReferenceTaxonomyUtils.java index eb4a7687080..43e57b6fd78 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/spark/pathseq/PSBuildReferenceTaxonomyUtils.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/spark/pathseq/PSBuildReferenceTaxonomyUtils.java @@ -313,13 +313,13 @@ public static BufferedReader getBufferedReaderTarGz(final String tarPath, final try { InputStream result = null; final TarArchiveInputStream tarStream = new TarArchiveInputStream(new GZIPInputStream(new FileInputStream(tarPath))); - TarArchiveEntry entry = tarStream.getNextTarEntry(); + TarArchiveEntry entry = tarStream.getNextEntry(); while (entry != null) { if (entry.getName().equals(fileName)) { result = tarStream; break; } - entry = tarStream.getNextTarEntry(); + entry = tarStream.getNextEntry(); } if (result == null) { throw new UserException.BadInput("Could not find file " + fileName + " in tarball " + tarPath); diff --git a/src/main/java/org/broadinstitute/hellbender/tools/spark/sv/StructuralVariationDiscoveryPipelineSpark.java b/src/main/java/org/broadinstitute/hellbender/tools/spark/sv/StructuralVariationDiscoveryPipelineSpark.java index 1ac964daeac..716e256d620 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/spark/sv/StructuralVariationDiscoveryPipelineSpark.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/spark/sv/StructuralVariationDiscoveryPipelineSpark.java @@ -41,9 +41,10 @@ import org.broadinstitute.hellbender.utils.io.IOUtils; import org.broadinstitute.hellbender.utils.read.GATKRead; import org.broadinstitute.hellbender.utils.read.SAMRecordToGATKReadAdapter; -import scala.Serializable; import java.io.IOException; +import java.io.Serial; +import java.io.Serializable; import java.nio.file.Paths; import java.util.List; import java.util.Set; @@ -364,6 +365,7 @@ private static List processEvidenceTargetLinks(List i = new TarArchiveInputStream(new GzipCompressorInputStream(new FileInputStream(fastaTarGz)))) { ArchiveEntry entry = null; while ((entry = i.getNextEntry()) != null) { if (!i.canReadEntryData(entry)) { diff --git a/src/test/java/org/broadinstitute/hellbender/tools/funcotator/FuncotatorEngineUnitTest.java b/src/test/java/org/broadinstitute/hellbender/tools/funcotator/FuncotatorEngineUnitTest.java index 6b637072805..86ecef8e337 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/funcotator/FuncotatorEngineUnitTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/funcotator/FuncotatorEngineUnitTest.java @@ -65,7 +65,8 @@ public void testGetFuncotationFactoriesAndCreateFuncotationMapForVariant(final F new FlankSettings(0, 0), false, FuncotatorUtils.DEFAULT_MIN_NUM_BASES_FOR_VALID_SEGMENT, - FuncotatorUtils.DEFAULT_SPLICE_SITE_WINDOW_SIZE) + FuncotatorUtils.DEFAULT_SPLICE_SITE_WINDOW_SIZE, + false) ); for (int i = 0; i < entireVcf.getRight().size(); i++) { diff --git a/src/test/java/org/broadinstitute/hellbender/tools/funcotator/FuncotatorIntegrationTest.java b/src/test/java/org/broadinstitute/hellbender/tools/funcotator/FuncotatorIntegrationTest.java index 8d9c9e1eff3..ff0c47a26e5 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/funcotator/FuncotatorIntegrationTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/funcotator/FuncotatorIntegrationTest.java @@ -33,6 +33,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import javax.validation.constraints.AssertFalse; +import javax.validation.constraints.AssertTrue; import java.io.*; import java.nio.file.Files; import java.nio.file.Paths; @@ -80,6 +82,7 @@ public class FuncotatorIntegrationTest extends CommandLineProgramTest { // TODO: Get rid of this variable and use the general data sources path (issue #5350 - https://github.com/broadinstitute/gatk/issues/5350): private static final String DS_PIK3CA_DIR = largeFileTestDir + "funcotator" + File.separator + "small_ds_pik3ca" + File.separator; + private static final String DS_PIK3CA_DIR_v43_MANE = largeFileTestDir + "funcotator" + File.separator + "ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST" + File.separator; private static final String MEDIUM_DATASOURCES_DIR = largeFileTestDir + "funcotator" + File.separator + "funcotator_dataSources" + File.separator; @@ -104,7 +107,10 @@ public class FuncotatorIntegrationTest extends CommandLineProgramTest { private static final List VCF_FIELDS_GENCODE_28_DS = Arrays.asList("Gencode_28_hugoSymbol","Gencode_28_ncbiBuild","Gencode_28_chromosome","Gencode_28_start","Gencode_28_end","Gencode_28_variantClassification","Gencode_28_variantType","Gencode_28_refAllele","Gencode_28_tumorSeqAllele1","Gencode_28_tumorSeqAllele2","Gencode_28_genomeChange","Gencode_28_annotationTranscript","Gencode_28_transcriptStrand","Gencode_28_transcriptExon","Gencode_28_transcriptPos","Gencode_28_cDnaChange","Gencode_28_codonChange","Gencode_28_proteinChange","Gencode_28_gcContent","Gencode_28_referenceContext","Gencode_28_otherTranscripts");//,"Achilles_Top_Genes","CGC_Name","CGC_GeneID","CGC_Chr","CGC_Chr_Band","CGC_Cancer_Somatic_Mut","CGC_Cancer_Germline_Mut","CGC_Tumour_Types__(Somatic_Mutations)","CGC_Tumour_Types_(Germline_Mutations)","CGC_Cancer_Syndrome","CGC_Tissue_Type","CGC_Cancer_Molecular_Genetics","CGC_Mutation_Type","CGC_Translocation_Partner","CGC_Other_Germline_Mut","CGC_Other_Syndrome/Disease","ClinVar_HGMD_ID","ClinVar_SYM","ClinVar_TYPE","ClinVar_ASSEMBLY","ClinVar_rs","Cosmic_overlapping_mutations","CosmicFusion_fusion_genes","CosmicFusion_fusion_id","CosmicTissue_total_alterations_in_gene","CosmicTissue_tissue_types_affected","DNARepairGenes_Activity_linked_to_OMIM","DNARepairGenes_Chromosome_location_linked_to_NCBI_MapView","DNARepairGenes_Accession_number_linked_to_NCBI_Entrez","Familial_Cancer_Genes_Syndrome","Familial_Cancer_Genes_Synonym","Familial_Cancer_Genes_Reference","Gencode_XHGNC_hgnc_id","Gencode_XRefSeq_mRNA_id","Gencode_XRefSeq_prot_acc","HGNC_HGNC_ID","HGNC_Approved_Name","HGNC_Status","HGNC_Locus_Type","HGNC_Locus_Group","HGNC_Previous_Symbols","HGNC_Previous_Name","HGNC_Synonyms","HGNC_Name_Synonyms","HGNC_Chromosome","HGNC_Date_Modified","HGNC_Date_Symbol_Changed","HGNC_Date_Name_Changed","HGNC_Accession_Numbers","HGNC_Enzyme_IDs","HGNC_Entrez_Gene_ID","HGNC_Ensembl_Gene_ID","HGNC_Pubmed_IDs","HGNC_RefSeq_IDs","HGNC_Gene_Family_ID","HGNC_Gene_Family_Name","HGNC_CCDS_IDs","HGNC_Vega_ID","HGNC_Entrez_Gene_ID(supplied_by_NCBI)","HGNC_OMIM_ID(supplied_by_OMIM)","HGNC_RefSeq(supplied_by_NCBI)","HGNC_UniProt_ID(supplied_by_UniProt)","HGNC_Ensembl_ID(supplied_by_Ensembl)","HGNC_UCSC_ID(supplied_by_UCSC)","Oreganno_Build","Oreganno_ID","Oreganno_Values","Simple_Uniprot_uniprot_entry_name","Simple_Uniprot_DrugBank","Simple_Uniprot_alt_uniprot_accessions","Simple_Uniprot_uniprot_accession","Simple_Uniprot_GO_Biological_Process","Simple_Uniprot_GO_Cellular_Component","Simple_Uniprot_GO_Molecular_Function","dbSNP_ASP","dbSNP_ASS","dbSNP_CAF","dbSNP_CDA","dbSNP_CFL","dbSNP_COMMON","dbSNP_DSS","dbSNP_G5","dbSNP_G5A","dbSNP_GENEINFO","dbSNP_GNO","dbSNP_HD","dbSNP_INT","dbSNP_KGPhase1","dbSNP_KGPhase3","dbSNP_LSD","dbSNP_MTP","dbSNP_MUT","dbSNP_NOC","dbSNP_NOV","dbSNP_NSF","dbSNP_NSM","dbSNP_NSN","dbSNP_OM","dbSNP_OTH","dbSNP_PM","dbSNP_PMC","dbSNP_R3","dbSNP_R5","dbSNP_REF","dbSNP_RS","dbSNP_RSPOS","dbSNP_RV","dbSNP_S3D","dbSNP_SAO","dbSNP_SLO","dbSNP_SSR","dbSNP_SYN","dbSNP_TOPMED","dbSNP_TPA","dbSNP_U3","dbSNP_U5","dbSNP_VC","dbSNP_VLD","dbSNP_VP","dbSNP_WGT","dbSNP_WTD","dbSNP_dbSNPBuildID"); private static final List MAF_FIELDS_GENCODE_DS = Arrays.asList(MafOutputRendererConstants.FieldName_Hugo_Symbol, MafOutputRendererConstants.FieldName_NCBI_Build, MafOutputRendererConstants.FieldName_Chromosome, MafOutputRendererConstants.FieldName_Start_Position, MafOutputRendererConstants.FieldName_End_Position, MafOutputRendererConstants.FieldName_Variant_Classification, MafOutputRendererConstants.FieldName_Variant_Type, - MafOutputRendererConstants.FieldName_Reference_Allele, MafOutputRendererConstants.FieldName_Tumor_Seq_Allele1, MafOutputRendererConstants.FieldName_Tumor_Seq_Allele2, MafOutputRendererConstants.FieldName_Genome_Change, MafOutputRendererConstants.FieldName_Annotation_Transcript, MafOutputRendererConstants.FieldName_Transcript_Strand, MafOutputRendererConstants.FieldName_Transcript_Exon, MafOutputRendererConstants.FieldName_Transcript_Position, MafOutputRendererConstants.FieldName_cDNA_Change, MafOutputRendererConstants.FieldName_Codon_Change, MafOutputRendererConstants.FieldName_Protein_Change, MafOutputRendererConstants.FieldName_gc_content, MafOutputRendererConstants.FieldName_ref_context, MafOutputRendererConstants.FieldName_Other_Transcripts); + MafOutputRendererConstants.FieldName_Reference_Allele, MafOutputRendererConstants.FieldName_Tumor_Seq_Allele1, MafOutputRendererConstants.FieldName_Tumor_Seq_Allele2, MafOutputRendererConstants.FieldName_Genome_Change, + MafOutputRendererConstants.FieldName_Annotation_Transcript, MafOutputRendererConstants.FieldName_Transcript_Strand, MafOutputRendererConstants.FieldName_Transcript_Exon, MafOutputRendererConstants.FieldName_Transcript_Position, + MafOutputRendererConstants.FieldName_cDNA_Change, MafOutputRendererConstants.FieldName_Codon_Change, MafOutputRendererConstants.FieldName_Protein_Change, MafOutputRendererConstants.FieldName_gc_content, + MafOutputRendererConstants.FieldName_ref_context, MafOutputRendererConstants.FieldName_Other_Transcripts); private static String hg38Chr3Ref; private static String b37Chr3Ref; @@ -951,6 +957,77 @@ public void testCanAnnotateHg38ClinvarAndGencodeV28() { .count(), NUM_CLINVAR_HITS); } + @Test + public void testMANESelectAnnotationDifferencesAndGencodeV43() { + // Clinvar datasource did go through one round of preprocessing to make contig names "1" --> "chr1" (for example). This is an issue with ClinVar, not GATK. + final FuncotatorArgumentDefinitions.OutputFormatType outputFormatType = FuncotatorArgumentDefinitions.OutputFormatType.VCF; + final File outputFileMANESelectMode = getOutputFile(outputFormatType); + final File outputFileDefaultMode = getOutputFile(outputFormatType); + + // Run the tool twice with FuncotatorArgumentDefinitions.PREFER_MANE_TRANSCRIPT_MODE on and off and compare the results + final ArgumentsBuilder arguments1 = createBaselineArgumentsForFuncotator( + PIK3CA_VCF_HG38, + outputFileMANESelectMode, + hg38Chr3Ref, + DS_PIK3CA_DIR_v43_MANE, + FuncotatorTestConstants.REFERENCE_VERSION_HG38, + outputFormatType, + false); + arguments1.add(FuncotatorArgumentDefinitions.PREFER_MANE_TRANSCRIPT_MODE, "true"); + arguments1.add("intervals", "chr3:179148357-179235107"); + runCommandLine(arguments1); + + final ArgumentsBuilder arguments2 = createBaselineArgumentsForFuncotator( + PIK3CA_VCF_HG38, + outputFileDefaultMode, + hg38Chr3Ref, + DS_PIK3CA_DIR_v43_MANE, + FuncotatorTestConstants.REFERENCE_VERSION_HG38, + outputFormatType, + false); + arguments2.add("intervals", "chr3:179148357-179235107"); + runCommandLine(arguments2); + + // Assert that we NEVER seen the lower priority transcript when we are in MANE select mode + try (final FeatureDataSource featureDataSourceMANE = new FeatureDataSource<>(outputFileMANESelectMode); + final FeatureDataSource featureDataSourceDefault = new FeatureDataSource<>(outputFileDefaultMode)) { + boolean hasSeenENST00000435560 = false; + for (final VariantContext vc : featureDataSourceMANE) { + if (vc.getAttributeAsString("FUNCOTATION", null) != null) { + final String funcotationMANE = vc.getAttributeAsString("FUNCOTATION", ""); + Assert.assertFalse(funcotationMANE.contains("ENST00000263967.4")); // this transcript is MANE_SELECT not MANE_PLUS_CLINICAL so should never be selected for these variants + Assert.assertTrue(funcotationMANE.contains("ENST00000643187.1") || funcotationMANE.contains("ENST00000435560.1")); + if (funcotationMANE.contains("ENST00000435560.1")) { + hasSeenENST00000435560 = true; + } + } + } + Assert.assertTrue(hasSeenENST00000435560); // ENST00000435560.1 is a basic annotation with no MANE_SELECT transcripts overlapping it, so it should still be emitted + hasSeenENST00000435560 = false; + // Assert that we see a mix of transcripts when we are in MANE select mode + boolean hasSeenMANESelect = false; + boolean hasSeenMANEPlusClinical = false; + for (final VariantContext vc : featureDataSourceDefault) { + if (vc.getAttributeAsString("FUNCOTATION", null) != null) { + final String funcotationDefault = vc.getAttributeAsString("FUNCOTATION", ""); + if (funcotationDefault.contains("ENST00000643187.1")) { + hasSeenMANESelect = true; + } + if (funcotationDefault.contains("ENST00000643187.1")) { + hasSeenMANEPlusClinical = true; + } + if (funcotationDefault.contains("ENST00000435560.1")) { + hasSeenENST00000435560 = true; + } + } + } + // assert that we have seen both versions of the transcript in the default case + Assert.assertTrue(hasSeenENST00000435560); // ENST00000435560.1 is a basic annotation with no MANE_SELECT transcripts overlapping it, so it should still be emitted + Assert.assertTrue(hasSeenMANESelect); + Assert.assertTrue(hasSeenMANEPlusClinical); + } + } + //Test for https://github.com/broadinstitute/gatk/issues/6173 @Test public void testVCFColumnsArentShuffled() { diff --git a/src/test/java/org/broadinstitute/hellbender/tools/funcotator/dataSources/gencode/GencodeFuncotationFactoryUnitTest.java b/src/test/java/org/broadinstitute/hellbender/tools/funcotator/dataSources/gencode/GencodeFuncotationFactoryUnitTest.java index 59b9d69299a..62377b937c9 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/funcotator/dataSources/gencode/GencodeFuncotationFactoryUnitTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/funcotator/dataSources/gencode/GencodeFuncotationFactoryUnitTest.java @@ -364,10 +364,90 @@ private GencodeGtfStartCodonFeature provideForTestIs5PrimeUtrStartCodonHelper(fi return (GencodeGtfStartCodonFeature)GencodeGtfStartCodonFeature.create(baseData); } + private GencodeGtfTranscriptFeature provideArtificialTranscriptForTestMANEExtractMode(final SimpleInterval interval, + final boolean isBasic, + final boolean isMANESelect, + final boolean isMANEPlusClinical ) { + List> optionalFields = new ArrayList<>(); + if ( isBasic ) { + optionalFields.add(new GencodeGtfFeature.OptionalField("tag", GencodeGTFFieldConstants.FeatureTag.BASIC.toString())); + } + if ( isMANEPlusClinical ) { + optionalFields.add(new GencodeGtfFeature.OptionalField("tag", GencodeGTFFieldConstants.FeatureTag.MANE_PLUS_CLINICAL.toString())); + } + if ( isMANESelect ) { + optionalFields.add(new GencodeGtfFeature.OptionalField("tag", GencodeGTFFieldConstants.FeatureTag.MANE_SELECT.toString())); + } + + final GencodeGtfTranscriptFeature baseData = (GencodeGtfTranscriptFeature) GencodeGtfTranscriptFeature.create( new GencodeGtfFeatureBaseData(GencodeGtfCodec.GTF_FILE_TYPE_STRING, + 1, + interval.getContig(), + GencodeGtfFeature.ANNOTATION_SOURCE_HAVANA, + GencodeGtfFeature.FeatureType.GENE, + interval.getStart(), + interval.getEnd(), + Strand.POSITIVE, + GencodeGtfFeature.GenomicPhase.DOT, + "TEST-GENE-ID", + "TEST-TX-ID-"+Math.random(), // Randomize the transcript ID to ensure uniqueness for later comparisons + GencodeGTFFieldConstants.KnownGeneBiotype.PROTEIN_CODING.toString(), + GencodeGTFFieldConstants.GeneTranscriptStatus.PUTATIVE.toString(), + "TEST-GENE", + GencodeGTFFieldConstants.KnownGeneBiotype.PROTEIN_CODING.toString(), + GencodeGTFFieldConstants.GeneTranscriptStatus.PUTATIVE.toString(), + "TEST-TX", + 1, + "", + GencodeGTFFieldConstants.LocusLevel.AUTOMATICALLY_ANNOTATED.toString(), + optionalFields.isEmpty() ? null : optionalFields + )); + return baseData; + } + //================================================================================================================== // Data Providers: + @DataProvider + Object[][] provideTestForMANESelectMode() { + final GencodeGtfTranscriptFeature NONBASIC_A = provideArtificialTranscriptForTestMANEExtractMode(new SimpleInterval("chr1", 99, 101), false, false, false); + final GencodeGtfTranscriptFeature BASIC_A = provideArtificialTranscriptForTestMANEExtractMode(new SimpleInterval("chr1", 99, 101), true, false, false); + final GencodeGtfTranscriptFeature BASIC_B = provideArtificialTranscriptForTestMANEExtractMode(new SimpleInterval("chr1", 99, 102), true, false, false); + final GencodeGtfTranscriptFeature BASIC_MANESELECT_A = provideArtificialTranscriptForTestMANEExtractMode(new SimpleInterval("chr1", 99, 101), true, true, false); + final GencodeGtfTranscriptFeature BASIC_MANESELECT_B = provideArtificialTranscriptForTestMANEExtractMode(new SimpleInterval("chr1", 99, 102), true, true, false); + final GencodeGtfTranscriptFeature BASIC_MANEPLUSCLINICAL_A = provideArtificialTranscriptForTestMANEExtractMode(new SimpleInterval("chr1", 99, 101), true, false, true); + final GencodeGtfTranscriptFeature BASIC_MANEPLUSCLINICAL_B = provideArtificialTranscriptForTestMANEExtractMode(new SimpleInterval("chr1", 99, 102), true, false, true); + final GencodeGtfTranscriptFeature BASIC_MANESELECT_MANEPLUSCLINICAL = provideArtificialTranscriptForTestMANEExtractMode(new SimpleInterval("chr1", 99, 101), true, true, true); + final GencodeGtfTranscriptFeature NONBASIC_MANESELECT = provideArtificialTranscriptForTestMANEExtractMode(new SimpleInterval("chr1", 99, 101), false, true, false); + final GencodeGtfTranscriptFeature NONBASIC_MANEPLUSCLINICAL = provideArtificialTranscriptForTestMANEExtractMode(new SimpleInterval("chr1", 99, 101), false, false, true); + + return new Object[][]{ + // trivial cases where only one transcript is present + {List.of(NONBASIC_A), List.of()}, + {List.of(BASIC_A), List.of(BASIC_A)}, + {List.of(BASIC_MANESELECT_A), List.of(BASIC_MANESELECT_A)}, + {List.of(BASIC_MANEPLUSCLINICAL_A), List.of(BASIC_MANEPLUSCLINICAL_A)}, + {List.of(BASIC_MANESELECT_MANEPLUSCLINICAL), List.of(BASIC_MANESELECT_MANEPLUSCLINICAL)}, + // NOTE that these are (NOT BASIC TRANSCRIPTS), we still return them in MANE select mode + {List.of(NONBASIC_MANESELECT), List.of(NONBASIC_MANESELECT)}, + {List.of(NONBASIC_MANESELECT), List.of(NONBASIC_MANESELECT)}, + + // More complicated cases with multiple transcripts + {List.of(NONBASIC_A, BASIC_B), List.of(BASIC_B)}, // filter out non-basic transcripts + {List.of(BASIC_A, BASIC_B), List.of(BASIC_A, BASIC_B)}, // return all basic transcripts + {List.of(BASIC_A, BASIC_MANESELECT_A), List.of(BASIC_MANESELECT_A)}, // return only MANE select transcript + {List.of(BASIC_A, BASIC_MANESELECT_A, BASIC_MANESELECT_B), List.of(BASIC_MANESELECT_A, BASIC_MANESELECT_B)}, // return ALL MANE_SELECT transcripts present + {List.of(BASIC_A, BASIC_MANESELECT_A, NONBASIC_MANESELECT), List.of(BASIC_MANESELECT_A, NONBASIC_MANESELECT)}, // return ALL MANE_SELECT transcripts present, even if one is non-basic + {List.of(BASIC_A, BASIC_MANEPLUSCLINICAL_B), List.of(BASIC_MANEPLUSCLINICAL_B)}, // return only MANE+Clinical transcript + {List.of(BASIC_A, BASIC_MANEPLUSCLINICAL_A, BASIC_MANEPLUSCLINICAL_B), List.of(BASIC_MANEPLUSCLINICAL_A, BASIC_MANEPLUSCLINICAL_B)}, // return multiple MANE+Clinical transcripts + {List.of(BASIC_A, BASIC_MANESELECT_A, BASIC_MANEPLUSCLINICAL_B), List.of(BASIC_MANEPLUSCLINICAL_B)}, // MANE+Clinical Overrides MANE select + + //edge cases + {List.of(BASIC_A, BASIC_MANESELECT_A, NONBASIC_MANEPLUSCLINICAL), List.of(NONBASIC_MANEPLUSCLINICAL)}, // MANE+Clinical Overrides MANE select EVEN if it is non-basic and MANE select is basic (probably doesn't happen in practice) + {List.of(BASIC_A, BASIC_MANESELECT_A, BASIC_MANESELECT_B, BASIC_MANESELECT_MANEPLUSCLINICAL), List.of(BASIC_MANESELECT_MANEPLUSCLINICAL)}, // MANE+Clinical trumps MANE_Select if both are present (should not happen in practice) + }; + } + @DataProvider Object[][] provideTranscriptForGetSortedCdsAndStartStopPositions() { return new Object[][] { @@ -1268,6 +1348,15 @@ Object[][] provideDataForTestCalculateGcContent() { //================================================================================================================== // Tests: + @Test ( dataProvider = "provideTestForMANESelectMode" ) + void testMANESelectTranscriptSelectionCriteria(final List inputTranscripts, final List expectedTranscripts) { + final List selectedTranscripts = GencodeFuncotationFactory.retreiveMANESelectModeTranscriptsCriteria(inputTranscripts); + Assert.assertEquals(selectedTranscripts.size(), expectedTranscripts.size()); + for (int i = 0; i < selectedTranscripts.size(); i++) { + Assert.assertEquals(selectedTranscripts.get(i), expectedTranscripts.get(i)); + } + } + @Test ( dataProvider = "provideTranscriptForGetSortedCdsAndStartStopPositions") void testGetSortedExonAndStartStopPositions(final GencodeGtfTranscriptFeature transcript, final List expected) { diff --git a/src/test/java/org/broadinstitute/hellbender/tools/funcotator/mafOutput/MafOutputRendererUnitTest.java b/src/test/java/org/broadinstitute/hellbender/tools/funcotator/mafOutput/MafOutputRendererUnitTest.java index 6f9bea3e279..1d3ec9d8b74 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/funcotator/mafOutput/MafOutputRendererUnitTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/funcotator/mafOutput/MafOutputRendererUnitTest.java @@ -124,7 +124,8 @@ private MafOutputRenderer createMafOutputRenderer(final File outputFile, final S new FlankSettings(0, 0), false, FuncotatorUtils.DEFAULT_MIN_NUM_BASES_FOR_VALID_SEGMENT, - FuncotatorUtils.DEFAULT_SPLICE_SITE_WINDOW_SIZE + FuncotatorUtils.DEFAULT_SPLICE_SITE_WINDOW_SIZE, + false ); // Sort the datasources to ensure the same order every time: diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg19/dummy_clinvar_hg19_pik3ca.vcf b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg19/dummy_clinvar_hg19_pik3ca.vcf new file mode 100755 index 00000000000..0cfed940df1 --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg19/dummy_clinvar_hg19_pik3ca.vcf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b00b13d5903fa283d5aa2e041699d282fc5790767d08e3ae70b645cce551ff1 +size 135686 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg19/dummy_clinvar_hg19_pik3ca.vcf.idx b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg19/dummy_clinvar_hg19_pik3ca.vcf.idx new file mode 100644 index 00000000000..d27bc5c17af --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg19/dummy_clinvar_hg19_pik3ca.vcf.idx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c206317ba24f60b5fb1104639172be9eed5870e931332636f87a64492afd02f9 +size 89844 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg19/dummy_clinvar_pik3ca.config b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg19/dummy_clinvar_pik3ca.config new file mode 100755 index 00000000000..d0092bcf9fa --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg19/dummy_clinvar_pik3ca.config @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93740f3491cb32e0a401144573bed0637fe0fd5c16c393f4457e454ea59b04da +size 1549 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg38/dummy_clinvar_hg38_pik3ca.vcf b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg38/dummy_clinvar_hg38_pik3ca.vcf new file mode 100755 index 00000000000..c617d6956da --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg38/dummy_clinvar_hg38_pik3ca.vcf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75cfbbf6c5c8d349ff8bd00ff3418198c1944c13e289e699626921162002edc6 +size 429200 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg38/dummy_clinvar_hg38_pik3ca.vcf.idx b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg38/dummy_clinvar_hg38_pik3ca.vcf.idx new file mode 100755 index 00000000000..0ba51fabd65 --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg38/dummy_clinvar_hg38_pik3ca.vcf.idx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:038ec0ca0a7ddb3f6630af85e164f58eabd319a882aeaeeb6c7cea5f536727c1 +size 89924 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg38/dummy_clinvar_pik3ca.config b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg38/dummy_clinvar_pik3ca.config new file mode 100755 index 00000000000..c5b804a0ec6 --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/dummy_clinvar_pik3ca/hg38/dummy_clinvar_pik3ca.config @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5542a28d5e3eb3d26a041296cf90baf0a767c3486fff51e139325dfc4d2e95b9 +size 1549 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.config b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.config new file mode 100755 index 00000000000..f3629f1d61a --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.config @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb92e5bea0e75a93df9e96da3cdf6b135700f90544f5c32c8af859317d74b8bb +size 1763 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA.gtf b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA.gtf new file mode 100644 index 00000000000..ce87c954a55 --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA.gtf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7c09d309121a8664c3f465ca169fadbfe539a188ab541052c4e6719aa209a15 +size 23214 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA.gtf.idx b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA.gtf.idx new file mode 100644 index 00000000000..10817a1e3a6 --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA.gtf.idx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd2aa8475b77a6c8e2c782a2de47c7ec8070bfd541303e548e96f787a8920c1d +size 312 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA_transcript.dict b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA_transcript.dict new file mode 100644 index 00000000000..a22de84a368 --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA_transcript.dict @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74883af09a5772034d53f2df884a82e34df415951081e5754bedf1517ee9faa9 +size 968 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA_transcript.fasta b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA_transcript.fasta new file mode 100644 index 00000000000..1ca5bf20690 --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA_transcript.fasta @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d3f582d1ca1ed259c77e4a82f4bfed8e9253b4b5c3aba9a63eb08f75f5cc68d +size 10353 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA_transcript.fasta.fai b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA_transcript.fasta.fai new file mode 100644 index 00000000000..47e29d36fdd --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg19/gencode.v19.PIK3CA_transcript.fasta.fai @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4e49f4d57d32943e1663cf9902460ff7a2e2c03dfaf0bd3c5fc7ad9f01c2d47 +size 441 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/WARNING.txt b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/WARNING.txt new file mode 100644 index 00000000000..76e4d761b0e --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/WARNING.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b421273c3e2b24bec59dc6b88537201a5f815c0f80b2871104e4a4f7b709ddc +size 250 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA.gtf b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA.gtf new file mode 100644 index 00000000000..714699066d9 --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA.gtf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4b785058cf09d2c8d7d08bc7c27ab178732ea3eb52320343dee7f693fe20482 +size 109269 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA.gtf.idx b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA.gtf.idx new file mode 100644 index 00000000000..b195e3b51d4 --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA.gtf.idx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c88f684230eb6032bdb9de22ea0f85a134469c4afe51b2818150984f04a1fbc +size 1728 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA_transcript.dict b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA_transcript.dict new file mode 100644 index 00000000000..36af840df26 --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA_transcript.dict @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a4b5398803aa8914f728441dc2f1e655a9dcd9bb508b3f76c2100c195f8712a +size 1974 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA_transcript.fasta b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA_transcript.fasta new file mode 100644 index 00000000000..8badb3d7ed6 --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA_transcript.fasta @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ad176587035d99bad676ec290d47fbfc9b7efd360312db83bb9c34a5463f62d +size 21865 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA_transcript.fasta.fai b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA_transcript.fasta.fai new file mode 100644 index 00000000000..493928742ce --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode.v43.PIK3CA_transcript.fasta.fai @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0cfafe686ee63dff4ece7f66eca9ce079e84cca5f7b62488f2f5195f5ceb5cb +size 855 diff --git a/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode_pik3ca.config b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode_pik3ca.config new file mode 100755 index 00000000000..b8003231715 --- /dev/null +++ b/src/test/resources/large/funcotator/ds_pik3ca_v43_WITH_MANE_SELECT_PLUS_CLINICAL_ANNOTATIONS_FOR_TEST/gencode_pik3ca/hg38/gencode_pik3ca.config @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61175f185cbf1df5769e37e2933e14923049c5bcaa6a9c44f7742cbddc6358df +size 1630