From 793a585b1b4915f9e573b507c229a8f3873d3086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Wiewi=C3=B3rka?= Date: Sun, 14 Apr 2019 17:00:51 +0200 Subject: [PATCH] disq support for coverage (#146) * disq support for coverage * added unit tests for disq * disq support for coverage * added unit tests for disq * Bug fixing reading BAMs and CRAMs * Fixing gkl logging * Disable tests in publishing phase * Changing defaut ValidationStringency to LENIENT * Changing defaut ValidationStringency to SILENT * Docs update --- Jenkinsfile | 2 +- build.sbt | 23 +- docs/source/fileformats/fileformats.rst | 2 + docs/source/index.rst | 8 +- docs/source/usecases/usecases.rst | 49 +++ releasing/release.sh | 7 + .../BAM/BDGAlignmentRelation.scala | 63 +++- .../inputformats/BAMBDGInputFormat.java | 1 - .../inputformats/BDGContainer.java | 75 ---- .../inputformats/CRAMBDGInputFormat.java | 2 +- .../inputformats/CRAMBDGIterator.java | 346 ------------------ .../inputformats/CRAMBDGRecordReader.java | 89 ----- .../inputformats/ContainerBDGHeaderIO.java | 96 ----- .../inputformats/ContainerBDGIO.java | 193 ---------- .../inputformats/ContainerBDGParser.java | 157 -------- .../CramBDGContainerIterator.java | 88 ----- .../CramBDGSpanContainerIterator.java | 99 ----- .../coverage/CoverageStrategy.scala | 14 +- .../utils/BDGInternalParams.scala | 8 + .../biodatageeks/utils/BGDTableFuncs.scala | 5 + .../biodatageeks/utils/SequilaRegister.scala | 3 + src/test/resources/cram/test.cram | Bin 0 -> 162954 bytes src/test/resources/cram/test.fa | 91 +++++ src/test/resources/cram/test.fa.fai | 1 + src/test/resources/log4j.properties | 2 +- .../tests/CoverageTestSuite.scala | 279 ++++++-------- 26 files changed, 373 insertions(+), 1330 deletions(-) create mode 100755 releasing/release.sh delete mode 100644 src/main/scala/org/biodatageeks/inputformats/BDGContainer.java delete mode 100644 src/main/scala/org/biodatageeks/inputformats/CRAMBDGIterator.java delete mode 100644 src/main/scala/org/biodatageeks/inputformats/CRAMBDGRecordReader.java delete mode 100644 src/main/scala/org/biodatageeks/inputformats/ContainerBDGHeaderIO.java delete mode 100644 src/main/scala/org/biodatageeks/inputformats/ContainerBDGIO.java delete mode 100644 src/main/scala/org/biodatageeks/inputformats/ContainerBDGParser.java delete mode 100644 src/main/scala/org/biodatageeks/inputformats/CramBDGContainerIterator.java delete mode 100644 src/main/scala/org/biodatageeks/inputformats/CramBDGSpanContainerIterator.java create mode 100644 src/test/resources/cram/test.cram create mode 100644 src/test/resources/cram/test.fa create mode 100644 src/test/resources/cram/test.fa.fai diff --git a/Jenkinsfile b/Jenkinsfile index 2b4918f6..5ab4a641 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -116,7 +116,7 @@ node { echo "branch: ${env.BRANCH_NAME}" echo 'Publishing to ZSI-BIO snapshots repository....' - sh "SBT_OPTS='-XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=2G -Xmx2G' ${tool name: 'sbt-0.13.15', type: 'org.jvnet.hudson.plugins.SbtPluginBuilder$SbtInstallation'}/bin/sbt publish" + sh "SBT_OPTS='-XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=2G -Xmx2G' ${tool name: 'sbt-0.13.15', type: 'org.jvnet.hudson.plugins.SbtPluginBuilder$SbtInstallation'}/bin/sbt 'set test in publish := {}' publish" } diff --git a/build.sbt b/build.sbt index 845be586..d7555c4d 100644 --- a/build.sbt +++ b/build.sbt @@ -1,14 +1,16 @@ +import sbtassembly.AssemblyPlugin.autoImport.ShadeRule + import scala.util.Properties name := """bdg-sequila""" -version := "0.5.3-spark-2.4.0-SNAPSHOT" +version := "0.5.4-spark-2.4.1-SNAPSHOT" organization := "org.biodatageeks" scalaVersion := "2.11.8" -val DEFAULT_SPARK_2_VERSION = "2.4.0" +val DEFAULT_SPARK_2_VERSION = "2.4.1" val DEFAULT_HADOOP_VERSION = "2.6.5" @@ -16,7 +18,7 @@ lazy val sparkVersion = Properties.envOrElse("SPARK_VERSION", DEFAULT_SPARK_2_VE lazy val hadoopVersion = Properties.envOrElse("SPARK_HADOOP_VERSION", DEFAULT_HADOOP_VERSION) - +libraryDependencies += "org.seqdoop" % "hadoop-bam" % "7.10.0" dependencyOverrides += "com.google.guava" % "guava" % "15.0" libraryDependencies += "org.apache.hadoop" % "hadoop-client" % hadoopVersion @@ -39,7 +41,7 @@ libraryDependencies += "org.rogach" %% "scallop" % "3.1.2" libraryDependencies += "org.hammerlab.bdg-utils" %% "cli" % "0.3.0" -libraryDependencies += "com.github.samtools" % "htsjdk" % "2.18.2" +libraryDependencies += "com.github.samtools" % "htsjdk" % "2.19.0" libraryDependencies += "ch.cern.sparkmeasure" %% "spark-measure" % "0.13" excludeAll (ExclusionRule("org.apache.hadoop")) @@ -61,6 +63,8 @@ libraryDependencies += "org.apache.derby" % "derbyclient" % "10.14.2.0" libraryDependencies += "org.biodatageeks" % "bdg-performance_2.11" % "0.2-SNAPSHOT" excludeAll (ExclusionRule("org.apache.hadoop")) +libraryDependencies += "org.disq-bio" % "disq" % "0.3.0" + @@ -94,6 +98,17 @@ resolvers ++= Seq( "Hortonworks" at "http://repo.hortonworks.com/content/repositories/releases/" ) +//logLevel in assembly := Level.Debug + +//fix for hdtsdjk patch in hadoop-bam and disq +assemblyShadeRules in assembly := Seq( + ShadeRule.rename("htsjdk.samtools.SAMRecordHelper" -> "htsjdk.samtools.SAMRecordHelperDisq").inLibrary("org.disq-bio" % "disq" % "0.3.0"), + ShadeRule.rename("htsjdk.samtools.SAMRecordHelper" -> "htsjdk.samtools.SAMRecordHelperHadoopBAM").inLibrary("org.seqdoop" % "hadoop-bam" % "7.10.0") + +) + + + assemblyMergeStrategy in assembly := { case PathList("org", "apache", xs@_*) => MergeStrategy.first diff --git a/docs/source/fileformats/fileformats.rst b/docs/source/fileformats/fileformats.rst index 20b14ed8..8fcae2e1 100644 --- a/docs/source/fileformats/fileformats.rst +++ b/docs/source/fileformats/fileformats.rst @@ -307,6 +307,8 @@ In order to start using optimized Intel inflater library you need simply to set ss.sqlContext.setConf("spark.biodatageeks.bam.useGKLInflate","true") ss.sql(...) +Swappable alignment file reading mechanism +==================================================================== ADAM diff --git a/docs/source/index.rst b/docs/source/index.rst index d1e9f05e..b061dc14 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -32,7 +32,7 @@ SeQuiLa is an ANSI-SQL compliant solution for efficient genomic intervals queryi * SeQuiLa is scalable: - - implemented in Scala in Apache Spark 2.2 environment + - implemented in Scala in Apache Spark 2.4.x environment - can be run on single computer (locally) or Hadoop cluster using YARN @@ -86,6 +86,12 @@ Example.scala .. rubric:: Release notes: +0.5.4 (2019-04-13) + - support for Apache Spark: 2.4.1 and HDP 2.3.2.3.1.0.0-78 + - support for `disq `_ for reading BAM and CRAM files in coverage calculations + - `swappable alignment file read mechanism `_ (``spark.biodatageeks.readAligment.method`` parameter defaults to "hadoopBAM") + - support for `long reads `_ (e.g. Nanopore) using disq library + 0.5 - new result type (fixed lenght windows) for depth of coverage calculations diff --git a/docs/source/usecases/usecases.rst b/docs/source/usecases/usecases.rst index 5b0d29f7..bfc780a4 100644 --- a/docs/source/usecases/usecases.rst +++ b/docs/source/usecases/usecases.rst @@ -707,3 +707,52 @@ Simple Multisample analyses .option("header", "true") .option("delimiter", "\t") .csv("/data/input/fc.txt") + + +Nanopore long reads from WGS analyses +##################################### + +.. code-block:: bash + + imwiewior@cdh00:/data/work/nanopore_bam/minimap> hdfs dfs -du -h /data/granges/nanopore/* | grep sorted + 130.9 G 261.9 G /data/granges/nanopore/NA12878-Albacore2.1.sorted.bam + 126.5 G 253.0 G /data/granges/nanopore/rel5-guppy-0.3.0-chunk10k.sorted.bam + 51.2 M 102.4 M /data/granges/nanopore/rel5-guppy-0.3.0-chunk10k.sorted.bam.bai + + + +.. code-block:: scala + + import org.apache.spark.sql.SequilaSession + import org.biodatageeks.utils.{SequilaRegister, UDFRegister,BDGInternalParams} + + + val ss = SequilaSession(spark) + SequilaRegister.register(ss) + /*enable disq support*/ + ss.sqlContext.setConf("spark.biodatageeks.readAligment.method", "disq") + + /* WGS -bases-blocks*/ + ss.sql(""" + CREATE TABLE IF NOT EXISTS reads_nanopore + USING org.biodatageeks.datasources.BAM.BAMDataSource + OPTIONS(path '/data/granges/nanopore/*sorted*.bam') + """.stripMargin) + + ss.sql("select distinct sampleId from reads_nanopore").show + + +--------------------------------+ + | sampleId| + +--------------------------------+ + | NA12878-Albacore2.1.sorted| + |rel5-guppy-0.3.0-chunk10k.sorted| + +--------------------------------+ + + + /*Albacore mapper*/ + spark.time{ + ss.sql(s"SELECT * FROM bdg_coverage('reads_nanopore','NA12878-Albacore2.1.sorted', 'blocks')").write.format("parquet").save("/tmp/NA12878-Albacore2.1.sorted.parquet")} + + /*guppy mapper*/ + spark.time{ + ss.sql(s"SELECT * FROM bdg_coverage('reads_nanopore','rel5-guppy-0.3.0-chunk10k.sorted', 'blocks')").write.format("parquet").save("/tmp/rel5-guppy-0.3.0-chunk10k.sorted.parquet")} diff --git a/releasing/release.sh b/releasing/release.sh new file mode 100755 index 00000000..24e9d8ae --- /dev/null +++ b/releasing/release.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +#publish +sbt "set test in publish := {}" clean publish + +#assembly +sbt "set test in assembly := {}" clean assembly diff --git a/src/main/scala/org/biodatageeks/datasources/BAM/BDGAlignmentRelation.scala b/src/main/scala/org/biodatageeks/datasources/BAM/BDGAlignmentRelation.scala index 0be99f31..d78e6e9e 100644 --- a/src/main/scala/org/biodatageeks/datasources/BAM/BDGAlignmentRelation.scala +++ b/src/main/scala/org/biodatageeks/datasources/BAM/BDGAlignmentRelation.scala @@ -42,6 +42,7 @@ case class BDGSAMRecord(sampleId: String, trait BDGAlignFileReaderWriter [T <: BDGAlignInputFormat]{ + // val bdgSerialize = new BDGSerializer() //val serializer = new BDGFastSerializer() val confMap = new mutable.HashMap[String,String]() @@ -104,33 +105,67 @@ trait BDGAlignFileReaderWriter [T <: BDGAlignInputFormat]{ spark .sparkContext - .hadoopConfiguration.set(SAMHeaderReader.VALIDATION_STRINGENCY_PROPERTY, ValidationStringency.SILENT.toString) + .hadoopConfiguration.set(SAMHeaderReader.VALIDATION_STRINGENCY_PROPERTY, ValidationStringency.LENIENT.toString) } - def readBAMFile(@transient sqlContext: SQLContext, path: String)(implicit c: ClassTag[T]) = { + def readBAMFile(@transient sqlContext: SQLContext, path: String, refPath: Option[String] = None)(implicit c: ClassTag[T]) = { + val logger = Logger.getLogger(this.getClass.getCanonicalName) setLocalConf(sqlContext) setConf("spark.biodatageeks.bam.intervals","") //FIXME: disabled PP setHadoopConf(sqlContext) + + val spark = sqlContext .sparkSession val resolvedPath = BDGTableFuncs.getExactSamplePath(spark,path) +// val folderPath = BDGTableFuncs.getParentFolderPath(spark,path) + logger.info(s"######## Reading ${resolvedPath} or ${path}") + val alignReadMethod = spark.sqlContext.getConf(BDGInternalParams.IOReadAlignmentMethod,"hadoopBAM").toLowerCase + logger.info(s"######## Using ${alignReadMethod} for reading alignment files.") + + alignReadMethod match { + case "hadoopbam" => { + logger.info(s"Using Intel GKL inflater: ${BDGInternalParams.UseIntelGKL}") + spark.sparkContext + .newAPIHadoopFile[LongWritable, SAMRecordWritable, T](path) + .map(r => r._2.get()) + } + case "sparkbam" => { + import spark_bam._, hammerlab.path._ + val bamPath = Path(resolvedPath) + spark + .sparkContext + .loadReads(bamPath) + } - if(!spark.sqlContext.getConf("spark.biodatageeks.bam.useSparkBAM","false").toBoolean) - spark.sparkContext - .newAPIHadoopFile[LongWritable, SAMRecordWritable, T](path) - .map(r => r._2.get()) - else{ - import spark_bam._, hammerlab.path._ - val bamPath = Path(resolvedPath) - spark - .sparkContext - .loadReads(bamPath) + case "disq" => { + import org.disq_bio.disq.HtsjdkReadsRddStorage + + refPath match { + case Some(ref) => { + HtsjdkReadsRddStorage + .makeDefault(sqlContext.sparkContext) + .validationStringency(ValidationStringency.LENIENT) + .referenceSourcePath(ref) + .read(resolvedPath) + .getReads + .rdd + } + case None => { + HtsjdkReadsRddStorage + .makeDefault(sqlContext.sparkContext) + .validationStringency(ValidationStringency.LENIENT) + .read(resolvedPath) + .getReads + .rdd + } + } + } } - } @@ -275,7 +310,7 @@ class BDGAlignmentRelation[T <:BDGAlignInputFormat](path:String, refPath:Option[ sqlContext .sparkContext .hadoopConfiguration - .set(CRAMInputFormat.REFERENCE_SOURCE_PATH_PROPERTY,p) + .set(CRAMBDGInputFormat.REFERENCE_SOURCE_PATH_PROPERTY,p) } case _ => None } diff --git a/src/main/scala/org/biodatageeks/inputformats/BAMBDGInputFormat.java b/src/main/scala/org/biodatageeks/inputformats/BAMBDGInputFormat.java index 88c1f206..10881481 100644 --- a/src/main/scala/org/biodatageeks/inputformats/BAMBDGInputFormat.java +++ b/src/main/scala/org/biodatageeks/inputformats/BAMBDGInputFormat.java @@ -307,7 +307,6 @@ private List filterByInterval(List splits, Configuration .setOption(SamReaderFactory.Option.EAGERLY_DECODE, false) .setUseAsyncIo(false); if(conf.get(INFLATE_FACTORY) != null && conf.get(INFLATE_FACTORY).equalsIgnoreCase("intel_gkl")){ - System.out.println("Using Intel GKL Inflater"); IntelInflaterFactory intelDeflaterFactory = new IntelInflaterFactory(); readerFactory.inflaterFactory(intelDeflaterFactory); } diff --git a/src/main/scala/org/biodatageeks/inputformats/BDGContainer.java b/src/main/scala/org/biodatageeks/inputformats/BDGContainer.java deleted file mode 100644 index a6f9a342..00000000 --- a/src/main/scala/org/biodatageeks/inputformats/BDGContainer.java +++ /dev/null @@ -1,75 +0,0 @@ -/** - * **************************************************************************** - * Copyright 2013 EMBL-EBI - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * **************************************************************************** - */ -package htsjdk.samtools.cram.structure; - -import htsjdk.samtools.SAMRecord; -import htsjdk.samtools.cram.structure.block.Block; - -public class BDGContainer { - // container header as defined in the specs: - /** - * Byte size of the content excluding header. - */ - public int containerByteSize; - public int sequenceId = SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX; - public int alignmentStart = Slice.NO_ALIGNMENT_START; - public int alignmentSpan = Slice.NO_ALIGNMENT_SPAN; - public int nofRecords = 0; - public long globalRecordCounter = 0; - - public long bases = 0; - public int blockCount = -1; - public int[] landmarks; - public int checksum = 0; - - /** - * Container data - */ - public Block[] blocks; - - public CompressionHeader header; - - // slices found in the container: - public Slice[] slices; - - // for indexing: - /** - * Container start in the stream. - */ - public long offset; - - @Override - public String toString() { - return String - .format("seqID=%d, start=%d, span=%d, records=%d, slices=%d, blocks=%d.", - sequenceId, alignmentStart, alignmentSpan, nofRecords, - slices == null ? -1 : slices.length, blockCount); - } - - public boolean isEOF() { - final boolean v3 = containerByteSize == 15 && sequenceId == -1 - && alignmentStart == 4542278 && blockCount == 1 - && nofRecords == 0 && (slices == null || slices.length == 0); - - final boolean v2 = containerByteSize == 11 && sequenceId == -1 - && alignmentStart == 4542278 && blockCount == 1 - && nofRecords == 0 && (slices == null || slices.length == 0); - - return v3 || v2; - } -} diff --git a/src/main/scala/org/biodatageeks/inputformats/CRAMBDGInputFormat.java b/src/main/scala/org/biodatageeks/inputformats/CRAMBDGInputFormat.java index 0812ac04..868b4c94 100644 --- a/src/main/scala/org/biodatageeks/inputformats/CRAMBDGInputFormat.java +++ b/src/main/scala/org/biodatageeks/inputformats/CRAMBDGInputFormat.java @@ -83,7 +83,7 @@ private static long nextContainerOffset(List containerOffsets, long positi @Override public RecordReader createRecordReader(InputSplit split, TaskAttemptContext context) throws IOException, InterruptedException { - RecordReader rr = new org.seqdoop.hadoop_bam.CRAMBDGRecordReader(); + RecordReader rr = new CRAMRecordReader(); rr.initialize(split, context); return rr; } diff --git a/src/main/scala/org/biodatageeks/inputformats/CRAMBDGIterator.java b/src/main/scala/org/biodatageeks/inputformats/CRAMBDGIterator.java deleted file mode 100644 index a3fef58e..00000000 --- a/src/main/scala/org/biodatageeks/inputformats/CRAMBDGIterator.java +++ /dev/null @@ -1,346 +0,0 @@ -package htsjdk.samtools; - -/******************************************************************************* - * Copyright 2013-2016 EMBL-EBI - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License countingInputStream distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - - -import htsjdk.samtools.*; -import htsjdk.samtools.SAMFileHeader.SortOrder; -import htsjdk.samtools.cram.build.*; -import htsjdk.samtools.cram.build.ContainerBDGParser; -import htsjdk.samtools.cram.build.CramBDGContainerIterator; -import htsjdk.samtools.cram.build.CramBDGSpanContainerIterator; -import htsjdk.samtools.cram.io.CountingInputStream; -import htsjdk.samtools.cram.ref.CRAMReferenceSource; -import htsjdk.samtools.cram.structure.*; -import htsjdk.samtools.cram.structure.BDGContainer; -import htsjdk.samtools.cram.structure.ContainerBDGIO; -import htsjdk.samtools.seekablestream.SeekableStream; -import htsjdk.samtools.util.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.util.*; - -import htsjdk.samtools.cram.CRAMException; - -public class CRAMBDGIterator implements SAMRecordIterator { - private static final Log log = Log.getInstance(htsjdk.samtools.CRAMIterator.class); - private final CountingInputStream countingInputStream; - private final CramHeader cramHeader; - private final ArrayList records; - private SAMRecord nextRecord = null; - private final CramNormalizer normalizer; - private byte[] refs; - private int prevSeqId = SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX; - public htsjdk.samtools.cram.structure.BDGContainer container; - private SamReader mReader; - long firstContainerOffset = 0; - private final Iterator containerIterator; - - private final ContainerBDGParser parser; - private final CRAMReferenceSource referenceSource; - - private Iterator iterator = Collections.emptyList().iterator(); - - private ValidationStringency validationStringency = ValidationStringency.DEFAULT_STRINGENCY; - - public ValidationStringency getValidationStringency() { - return validationStringency; - } - - public void setValidationStringency( - final ValidationStringency validationStringency) { - this.validationStringency = validationStringency; - } - - /** - * `samRecordIndex` only used when validation is not `SILENT` - * (for identification by the validator which records are invalid) - */ - private long samRecordIndex; - private ArrayList cramRecords; - - public CRAMBDGIterator(final InputStream inputStream, final CRAMReferenceSource referenceSource, final ValidationStringency validationStringency) - throws IOException { - if (null == referenceSource) { - throw new CRAMException("A reference source is required for CRAM files"); - } - this.countingInputStream = new CountingInputStream(inputStream); - this.referenceSource = referenceSource; - this.validationStringency = validationStringency; - final CramBDGContainerIterator containerIterator = new CramBDGContainerIterator(this.countingInputStream); - cramHeader = containerIterator.getCramHeader(); - this.containerIterator = containerIterator; - - firstContainerOffset = this.countingInputStream.getCount(); - records = new ArrayList(CRAMContainerStreamWriter.DEFAULT_RECORDS_PER_SLICE); - normalizer = new CramNormalizer(cramHeader.getSamFileHeader(), - referenceSource); - parser = new ContainerBDGParser(cramHeader.getSamFileHeader()); - } - - - public CRAMBDGIterator(final InputStream inputStream, final ValidationStringency validationStringency) - throws IOException { - this.countingInputStream = new CountingInputStream(inputStream); - this.validationStringency = validationStringency; - final CramBDGContainerIterator containerIterator = new CramBDGContainerIterator(this.countingInputStream); - cramHeader = containerIterator.getCramHeader(); - this.containerIterator = containerIterator; - - firstContainerOffset = this.countingInputStream.getCount(); - records = new ArrayList(CRAMContainerStreamWriter.DEFAULT_RECORDS_PER_SLICE); - normalizer = null; - referenceSource = null; - parser = new ContainerBDGParser(cramHeader.getSamFileHeader()); - } - - public CRAMBDGIterator(final SeekableStream seekableStream, final CRAMReferenceSource referenceSource, final long[] coordinates, final ValidationStringency validationStringency) - throws IOException { - if (null == referenceSource) { - throw new CRAMException("A reference source is required for CRAM files"); - } - this.countingInputStream = new CountingInputStream(seekableStream); - this.referenceSource = referenceSource; - this.validationStringency = validationStringency; - final CramBDGSpanContainerIterator containerIterator = CramBDGSpanContainerIterator.fromFileSpan(seekableStream, coordinates); - cramHeader = containerIterator.getCramHeader(); - this.containerIterator = containerIterator; - - firstContainerOffset = containerIterator.getFirstContainerOffset(); - records = new ArrayList(CRAMContainerStreamWriter.DEFAULT_RECORDS_PER_SLICE); - normalizer = new CramNormalizer(cramHeader.getSamFileHeader(), - referenceSource); - parser = new ContainerBDGParser(cramHeader.getSamFileHeader()); - } - - - - public CRAMBDGIterator(final SeekableStream seekableStream, final long[] coordinates, final ValidationStringency validationStringency) - throws IOException { - this.countingInputStream = new CountingInputStream(seekableStream); - this.referenceSource = null; - this.validationStringency = validationStringency; - final CramBDGSpanContainerIterator containerIterator = CramBDGSpanContainerIterator.fromFileSpan(seekableStream, coordinates); - cramHeader = containerIterator.getCramHeader(); - this.containerIterator = containerIterator; - - firstContainerOffset = containerIterator.getFirstContainerOffset(); - records = new ArrayList(CRAMContainerStreamWriter.DEFAULT_RECORDS_PER_SLICE); - normalizer = null; - parser = new ContainerBDGParser(cramHeader.getSamFileHeader()); - } - - @Deprecated - public CRAMBDGIterator(final SeekableStream seekableStream, final CRAMReferenceSource referenceSource, final long[] coordinates) - throws IOException { - this(seekableStream, referenceSource, coordinates, ValidationStringency.DEFAULT_STRINGENCY); - } - - public CramHeader getCramHeader() { - return cramHeader; - } - - void nextContainer() throws IOException, IllegalArgumentException, - IllegalAccessException, CRAMException { - - if (containerIterator != null) { - if (!containerIterator.hasNext()) { - records.clear(); - nextRecord = null; - return; - } - container = containerIterator.next(); - if (container.isEOF()) { - records.clear(); - nextRecord = null; - return; - } - } else { - container = ContainerBDGIO.readContainer(cramHeader.getVersion(), countingInputStream); - if (container.isEOF()) { - records.clear(); - nextRecord = null; - return; - } - } - - records.clear(); - if (cramRecords == null) - cramRecords = new ArrayList(container.nofRecords); - else - cramRecords.clear(); - - parser.getRecords(container, cramRecords, validationStringency); - - if (container.sequenceId == SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX) { - refs = new byte[]{}; - prevSeqId = SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX; - } else if (container.sequenceId == Slice.MULTI_REFERENCE) { - refs = null; - prevSeqId = Slice.MULTI_REFERENCE; - } else if (prevSeqId < 0 || prevSeqId != container.sequenceId) { - final SAMSequenceRecord sequence = cramHeader.getSamFileHeader() - .getSequence(container.sequenceId); -// refs = referenceSource.getReferenceBases(sequence, true); -// if (refs == null) { -// throw new CRAMException(String.format("Contig %s not found in the reference file.", sequence.getSequenceName())); -// } - prevSeqId = container.sequenceId; - } - - for (int i = 0; i < container.slices.length; i++) { - final Slice slice = container.slices[i]; - - if (slice.sequenceId < 0) - continue; - - if (refs != null && !slice.validateRefMD5(refs)) { - final String msg = String.format( - "Reference sequence MD5 mismatch for slice: sequence id %d, start %d, span %d, expected MD5 %s", - slice.sequenceId, - slice.alignmentStart, - slice.alignmentSpan, - String.format("%032x", new BigInteger(1, slice.refMD5))); - throw new CRAMException(msg); - } - } - - if (refs != null) normalizer.normalize(cramRecords, refs, 0, - container.header.substitutionMatrix); - - final Cram2SamRecordFactory cramToSamRecordFactory = new Cram2SamRecordFactory( - cramHeader.getSamFileHeader()); - - for (final CramCompressionRecord cramRecord : cramRecords) { - final SAMRecord samRecord = cramToSamRecordFactory.create(cramRecord); - if (!cramRecord.isSegmentUnmapped()) { - final SAMSequenceRecord sequence = cramHeader.getSamFileHeader() - .getSequence(cramRecord.sequenceId); - //refs = referenceSource.getReferenceBases(sequence, true); - } - - samRecord.setValidationStringency(validationStringency); - - if (mReader != null) { - final long chunkStart = (container.offset << 16) | cramRecord.sliceIndex; - final long chunkEnd = ((container.offset << 16) | cramRecord.sliceIndex) + 1; - nextRecord.setFileSource(new SAMFileSource(mReader, - new BAMFileSpan(new Chunk(chunkStart, chunkEnd)))); - } - - records.add(samRecord); - } - cramRecords.clear(); - iterator = records.iterator(); - } - - /** - * Skip cached records until given alignment start position. - * - * @param refIndex reference sequence index - * @param pos alignment start to skip to - */ - public boolean advanceToAlignmentInContainer(final int refIndex, final int pos) { - if (!hasNext()) return false; - int i = 0; - for (final SAMRecord record : records) { - if (refIndex != SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX && record.getReferenceIndex() != refIndex) continue; - - if (pos <= 0) { - if (record.getAlignmentStart() == SAMRecord.NO_ALIGNMENT_START) { - iterator = records.listIterator(i); - return true; - } - } else { - if (record.getAlignmentStart() >= pos) { - iterator = records.listIterator(i); - return true; - } - } - i++; - } - iterator = Collections.emptyList().iterator(); - return false; - } - - @Override - public boolean hasNext() { - if (container != null && container.isEOF()) return false; - if (!iterator.hasNext()) { - try { - nextContainer(); - } catch (IOException | IllegalAccessException e) { - throw new SAMException(e); - } - } - - return !records.isEmpty(); - } - - @Override - public SAMRecord next() { - if (hasNext()) { - - SAMRecord samRecord = iterator.next(); - - if (validationStringency != ValidationStringency.SILENT) { - SAMUtils.processValidationErrors(samRecord.isValid(), samRecordIndex++, validationStringency); - } - - return samRecord; - - } else { - throw new NoSuchElementException(); - } - } - - @Override - public void remove() { - throw new RuntimeException("Removal of records not implemented."); - } - - @Override - public void close() { - records.clear(); - //noinspection EmptyCatchBlock - try { - if (countingInputStream != null) - countingInputStream.close(); - } catch (final IOException e) { - } - } - - @Override - public SAMRecordIterator assertSorted(final SortOrder sortOrder) { - return SamReader.AssertingIterator.of(this).assertSorted(sortOrder); - } - - public SamReader getFileSource() { - return mReader; - } - - public void setFileSource(final SamReader mReader) { - this.mReader = mReader; - } - - public SAMFileHeader getSAMFileHeader() { - return cramHeader.getSamFileHeader(); - } - -} diff --git a/src/main/scala/org/biodatageeks/inputformats/CRAMBDGRecordReader.java b/src/main/scala/org/biodatageeks/inputformats/CRAMBDGRecordReader.java deleted file mode 100644 index fb69f5ed..00000000 --- a/src/main/scala/org/biodatageeks/inputformats/CRAMBDGRecordReader.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.seqdoop.hadoop_bam; - -import htsjdk.samtools.CRAMBDGIterator; -import htsjdk.samtools.CRAMIterator; -import htsjdk.samtools.SAMRecord; -import htsjdk.samtools.ValidationStringency; -import htsjdk.samtools.cram.ref.ReferenceSource; -import htsjdk.samtools.seekablestream.SeekableStream; -import java.io.IOException; -import java.net.URI; -import java.nio.file.Paths; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.Path; -import org.apache.hadoop.io.LongWritable; -import org.apache.hadoop.mapreduce.InputSplit; -import org.apache.hadoop.mapreduce.RecordReader; -import org.apache.hadoop.mapreduce.TaskAttemptContext; -import org.apache.hadoop.mapreduce.lib.input.FileSplit; -import org.seqdoop.hadoop_bam.util.NIOFileUtil; -import org.seqdoop.hadoop_bam.util.SAMHeaderReader; -import org.seqdoop.hadoop_bam.util.WrapSeekable; - -public class CRAMBDGRecordReader extends RecordReader { - - private final LongWritable key = new LongWritable(); - private final SAMRecordWritable record = new SAMRecordWritable(); - private boolean isInitialized = false; - private SeekableStream seekableStream; - private long start; - private long length; - private CRAMBDGIterator cramIterator; - - @Override - public void initialize(InputSplit split, TaskAttemptContext context) throws IOException { - if(isInitialized) { - close(); - } - isInitialized = true; - - final Configuration conf = context.getConfiguration(); - final FileSplit fileSplit = (FileSplit) split; - final Path file = fileSplit.getPath(); - - String refSourcePath = conf.get(CRAMInputFormat.REFERENCE_SOURCE_PATH_PROPERTY); - ReferenceSource refSource = new ReferenceSource(refSourcePath == null ? null : - NIOFileUtil.asPath(refSourcePath)); - - seekableStream = WrapSeekable.openPath(conf, file); - start = fileSplit.getStart(); - length = fileSplit.getLength(); - long end = start + length; - // CRAMIterator right shifts boundaries by 16 so we do the reverse here - // also subtract one from end since CRAMIterator's boundaries are inclusive - long[] boundaries = new long[] {start << 16, (end - 1) << 16}; - ValidationStringency stringency = SAMHeaderReader.getValidationStringency(conf); - cramIterator = new CRAMBDGIterator(seekableStream, boundaries, stringency); - } - - @Override - public boolean nextKeyValue() { - if (!cramIterator.hasNext()) { - return false; - } - SAMRecord r = cramIterator.next(); - key.set(BAMRecordReader.getKey(r)); - record.set(r); - return true; - } - - @Override - public LongWritable getCurrentKey() { - return key; - } - - @Override - public SAMRecordWritable getCurrentValue() { - return record; - } - - @Override - public float getProgress() throws IOException { - return (float)(seekableStream.position() - start) / length; - } - - @Override - public void close() { - cramIterator.close(); - } -} diff --git a/src/main/scala/org/biodatageeks/inputformats/ContainerBDGHeaderIO.java b/src/main/scala/org/biodatageeks/inputformats/ContainerBDGHeaderIO.java deleted file mode 100644 index e8191e0d..00000000 --- a/src/main/scala/org/biodatageeks/inputformats/ContainerBDGHeaderIO.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * **************************************************************************** - * Copyright 2013 EMBL-EBI - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * **************************************************************************** - */ -package htsjdk.samtools.cram.structure; - -import htsjdk.samtools.cram.io.CRC32OutputStream; -import htsjdk.samtools.cram.io.CramIntArray; -import htsjdk.samtools.cram.io.CramInt; -import htsjdk.samtools.cram.io.ITF8; -import htsjdk.samtools.cram.io.LTF8; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -class ContainerBDGHeaderIO { - - public boolean readContainerHeader(final htsjdk.samtools.cram.structure.BDGContainer container, final InputStream inputStream) - throws IOException { - return readContainerHeader(2, container, inputStream); - } - - public boolean readContainerHeader(final int major, final htsjdk.samtools.cram.structure.BDGContainer container, final InputStream inputStream) - throws IOException { - final byte[] peek = new byte[4]; - int character = inputStream.read(); - if (character == -1) - return false; - - peek[0] = (byte) character; - for (int i = 1; i < peek.length; i++) { - character = inputStream.read(); - if (character == -1) - throw new RuntimeException("Incomplete or broken stream."); - peek[i] = (byte) character; - } - - container.containerByteSize = CramInt.readInt32(peek); - container.sequenceId = ITF8.readUnsignedITF8(inputStream); - container.alignmentStart = ITF8.readUnsignedITF8(inputStream); - container.alignmentSpan = ITF8.readUnsignedITF8(inputStream); - container.nofRecords = ITF8.readUnsignedITF8(inputStream); - container.globalRecordCounter = LTF8.readUnsignedLTF8(inputStream); - container.bases = LTF8.readUnsignedLTF8(inputStream); - container.blockCount = ITF8.readUnsignedITF8(inputStream); - container.landmarks = CramIntArray.array(inputStream); - if (major >= 3) - container.checksum = CramInt.readInt32(inputStream); - - return true; - } - - /** - * Write CRAM {@link Container} out into the given {@link OutputStream}. - * @param major CRAM major version - * @param container container to be written - * @param outputStream the output stream to write the container to - * @return number of bytes written out to the output stream - * @throws IOException as per java IO contract - */ - public int writeContainerHeader(final int major, final htsjdk.samtools.cram.structure.BDGContainer container, final OutputStream outputStream) - throws IOException { - final CRC32OutputStream crc32OutputStream = new CRC32OutputStream(outputStream); - - int length = (CramInt.writeInt32(container.containerByteSize, crc32OutputStream) + 7) / 8; - length += (ITF8.writeUnsignedITF8(container.sequenceId, crc32OutputStream) + 7) / 8; - length += (ITF8.writeUnsignedITF8(container.alignmentStart, crc32OutputStream) + 7) / 8; - length += (ITF8.writeUnsignedITF8(container.alignmentSpan, crc32OutputStream) + 7) / 8; - length += (ITF8.writeUnsignedITF8(container.nofRecords, crc32OutputStream) + 7) / 8; - length += (LTF8.writeUnsignedLTF8(container.globalRecordCounter, crc32OutputStream) + 7) / 8; - length += (LTF8.writeUnsignedLTF8(container.bases, crc32OutputStream) + 7) / 8; - length += (ITF8.writeUnsignedITF8(container.blockCount, crc32OutputStream) + 7) / 8; - length += (CramIntArray.write(container.landmarks, crc32OutputStream) + 7) / 8; - - if (major >= 3) { - outputStream.write(crc32OutputStream.getCrc32_LittleEndian()); - length += 4 ; - } - - return length; - } -} diff --git a/src/main/scala/org/biodatageeks/inputformats/ContainerBDGIO.java b/src/main/scala/org/biodatageeks/inputformats/ContainerBDGIO.java deleted file mode 100644 index fca84552..00000000 --- a/src/main/scala/org/biodatageeks/inputformats/ContainerBDGIO.java +++ /dev/null @@ -1,193 +0,0 @@ -package htsjdk.samtools.cram.structure; - -import htsjdk.samtools.cram.build.CramIO; -import htsjdk.samtools.cram.common.CramVersionPolicies; -import htsjdk.samtools.cram.common.Version; -import htsjdk.samtools.cram.io.ExposedByteArrayOutputStream; -import htsjdk.samtools.cram.structure.block.Block; -import htsjdk.samtools.cram.structure.block.BlockContentType; -import htsjdk.samtools.util.Log; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -/** - * Methods to read and write CRAM containers. - */ -public class ContainerBDGIO { - private static final Log log = Log.getInstance(ContainerIO.class); - - /** - * Reads a CRAM container from the input stream. Returns an EOF container when there is no more data or the EOF marker found. - * - * @param version CRAM version to expect - * @param inputStream the stream to read from - * @return a new container object read from the stream - * @throws IOException as per java IO contract - */ - public static htsjdk.samtools.cram.structure.BDGContainer readContainer(final Version version, final InputStream inputStream) throws IOException { - final htsjdk.samtools.cram.structure.BDGContainer container = readContainer(version.major, inputStream); - if (container == null) { - // this will cause System.exit(1): - CramVersionPolicies.eofNotFound(version); - - return readContainer(version.major, new ByteArrayInputStream(CramIO.ZERO_B_EOF_MARKER)); - } - if (container.isEOF()) log.debug("EOF marker found, file/stream is complete."); - - return container; - } - - /** - * Reads next container from the stream. - * - * @param inputStream the stream to read from - * @return CRAM container or null if no more data - * @throws IOException - */ - private static BDGContainer readContainer(final int major, final InputStream inputStream) throws IOException { - return readContainer(major, inputStream, 0, Integer.MAX_VALUE); - } - - /** - * Reads container header only from a {@link InputStream}. - * - * @param major the CRAM version to assume - * @param inputStream the input stream to read from - * @return a new {@link Container} object with container header values filled out but empty body (no slices and blocks). - * @throws IOException as per java IO contract - */ - public static htsjdk.samtools.cram.structure.BDGContainer readContainerHeader(final int major, final InputStream inputStream) throws IOException { - final htsjdk.samtools.cram.structure.BDGContainer container = new htsjdk.samtools.cram.structure.BDGContainer(); - final htsjdk.samtools.cram.structure.ContainerBDGHeaderIO containerHeaderIO = new htsjdk.samtools.cram.structure.ContainerBDGHeaderIO(); - if (!containerHeaderIO.readContainerHeader(major, container, inputStream)) { - containerHeaderIO.readContainerHeader(container, new ByteArrayInputStream((major >= 3 ? CramIO.ZERO_F_EOF_MARKER : CramIO.ZERO_B_EOF_MARKER))); - return container; - } - return container; - } - - @SuppressWarnings("SameParameterValue") - private static htsjdk.samtools.cram.structure.BDGContainer readContainer(final int major, final InputStream inputStream, final int fromSlice, int howManySlices) throws IOException { - - final htsjdk.samtools.cram.structure.BDGContainer container = readContainerHeader(major, inputStream); - if (container.isEOF()) { - return container; - } - - container.header = CompressionHeader.read(major, inputStream); - - howManySlices = Math.min(container.landmarks.length, howManySlices); - - if (fromSlice > 0) //noinspection ResultOfMethodCallIgnored - inputStream.skip(container.landmarks[fromSlice]); - - final List slices = new ArrayList(); - for (int sliceCount = fromSlice; sliceCount < howManySlices - fromSlice; sliceCount++) { - final Slice slice = new Slice(); - SliceIO.read(major, slice, inputStream); - slice.index = sliceCount; - slices.add(slice); - } - - container.slices = slices.toArray(new Slice[slices.size()]); - - calculateSliceOffsetsAndSizes(container); - - log.debug("READ CONTAINER: " + container.toString()); - - return container; - } - - private static void calculateSliceOffsetsAndSizes(final htsjdk.samtools.cram.structure.BDGContainer container) { - if (container.slices.length == 0) return; - for (int i = 0; i < container.slices.length - 1; i++) { - final Slice slice = container.slices[i]; - slice.offset = container.landmarks[i]; - slice.size = container.landmarks[i + 1] - slice.offset; - slice.containerOffset = container.offset; - slice.index = i; - } - final Slice lastSlice = container.slices[container.slices.length - 1]; - lastSlice.offset = container.landmarks[container.landmarks.length - 1]; - lastSlice.size = container.containerByteSize - lastSlice.offset; - lastSlice.containerOffset = container.offset; - lastSlice.index = container.slices.length - 1; - } - - /** - * Writes a {@link Container} header information to a {@link OutputStream}. - * - * @param major the CRAM version to assume - * @param container the container holding the header to write - * @param outputStream the stream to write to - * @return the number of bytes written - * @throws IOException as per java IO contract - */ - public static int writeContainerHeader(final int major, final htsjdk.samtools.cram.structure.BDGContainer container, final OutputStream outputStream) throws IOException { - return new htsjdk.samtools.cram.structure.ContainerBDGHeaderIO().writeContainerHeader(major, container, outputStream); - } - - /** - * Writes a complete {@link Container} with it's header to a {@link OutputStream}. The method is aware of file header containers and is - * suitable for general purpose use: basically any container is allowed. - * - * @param version the CRAM version to assume - * @param container the container to write - * @param outputStream the stream to write to - * @return the number of bytes written out - * @throws IOException as per java IO contract - */ - public static int writeContainer(final Version version, final htsjdk.samtools.cram.structure.BDGContainer container, final OutputStream outputStream) throws IOException { - { - if (container.blocks != null && container.blocks.length > 0) { - - final Block firstBlock = container.blocks[0]; - final boolean isFileHeaderContainer = firstBlock.getContentType() == BlockContentType.FILE_HEADER; - if (isFileHeaderContainer) { - final ExposedByteArrayOutputStream byteArrayOutputStream = new ExposedByteArrayOutputStream(); - firstBlock.write(version.major, byteArrayOutputStream); - container.containerByteSize = byteArrayOutputStream.size(); - - final int containerHeaderByteSize = new htsjdk.samtools.cram.structure.ContainerBDGHeaderIO().writeContainerHeader(version.major, container, outputStream); - outputStream.write(byteArrayOutputStream.getBuffer(), 0, byteArrayOutputStream.size()); - return containerHeaderByteSize + byteArrayOutputStream.size(); - } - } - } - - final ExposedByteArrayOutputStream byteArrayOutputStream = new ExposedByteArrayOutputStream(); - - container.header.write(version, byteArrayOutputStream); - container.blockCount = 1; - - final List landmarks = new ArrayList<>(); - for (int i = 0; i < container.slices.length; i++) { - final Slice slice = container.slices[i]; - landmarks.add(byteArrayOutputStream.size()); - SliceIO.write(version.major, slice, byteArrayOutputStream); - container.blockCount++; - container.blockCount++; - if (slice.embeddedRefBlock != null) container.blockCount++; - container.blockCount += slice.external.size(); - } - container.landmarks = new int[landmarks.size()]; - for (int i = 0; i < container.landmarks.length; i++) - container.landmarks[i] = landmarks.get(i); - - container.containerByteSize = byteArrayOutputStream.size(); - calculateSliceOffsetsAndSizes(container); - - int length = new htsjdk.samtools.cram.structure.ContainerBDGHeaderIO().writeContainerHeader(version.major, container, outputStream); - outputStream.write(byteArrayOutputStream.getBuffer(), 0, byteArrayOutputStream.size()); - length += byteArrayOutputStream.size(); - - log.debug("CONTAINER WRITTEN: " + container.toString()); - - return length; - } -} diff --git a/src/main/scala/org/biodatageeks/inputformats/ContainerBDGParser.java b/src/main/scala/org/biodatageeks/inputformats/ContainerBDGParser.java deleted file mode 100644 index bdc096de..00000000 --- a/src/main/scala/org/biodatageeks/inputformats/ContainerBDGParser.java +++ /dev/null @@ -1,157 +0,0 @@ -/** - * **************************************************************************** - * Copyright 2013 EMBL-EBI - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * **************************************************************************** - */ -package htsjdk.samtools.cram.build; - -import htsjdk.samtools.SAMFileHeader; -import htsjdk.samtools.SAMRecord; -import htsjdk.samtools.SAMSequenceRecord; -import htsjdk.samtools.ValidationStringency; -import htsjdk.samtools.cram.structure.*; -import htsjdk.samtools.cram.encoding.reader.CramRecordReader; -import htsjdk.samtools.cram.encoding.reader.MultiRefSliceAlignmentSpanReader; -import htsjdk.samtools.cram.structure.BDGContainer; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ContainerBDGParser { - private final SAMFileHeader samFileHeader; - - public ContainerBDGParser(final SAMFileHeader samFileHeader) { - this.samFileHeader = samFileHeader; - } - - public List getRecords(final htsjdk.samtools.cram.structure.BDGContainer container, - ArrayList records, final ValidationStringency validationStringency) throws IllegalArgumentException, - IllegalAccessException { - if (container.isEOF()) { - return Collections.emptyList(); - } - - if (records == null) { - records = new ArrayList<>(container.nofRecords); - } - - for (final Slice slice : container.slices) { - records.addAll(getRecords(slice, container.header, validationStringency)); - } - - return records; - } - - public Map getReferences(final BDGContainer container, final ValidationStringency validationStringency) throws IOException { - final Map containerSpanMap = new HashMap<>(); - for (final Slice slice : container.slices) { - addAllSpans(containerSpanMap, getReferences(slice, container.header, validationStringency)); - } - return containerSpanMap; - } - - private static void addSpan(final int seqId, final int start, final int span, final int count, final Map map) { - if (map.containsKey(seqId)) { - map.get(seqId).add(start, span, count); - } else { - map.put(seqId, new AlignmentSpan(start, span, count)); - } - } - - private static Map addAllSpans(final Map spanMap, final Map addition) { - for (final Map.Entry entry:addition.entrySet()) { - addSpan(entry.getKey(), entry.getValue().getStart(), entry.getValue().getCount(), entry.getValue().getSpan(), spanMap); - } - return spanMap; - } - - Map getReferences(final Slice slice, final CompressionHeader header, final ValidationStringency validationStringency) throws IOException { - final Map spanMap = new HashMap<>(); - switch (slice.sequenceId) { - case SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX: - spanMap.put(SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX, AlignmentSpan.UNMAPPED_SPAN); - break; - case Slice.MULTI_REFERENCE: - final Map spans = slice.getMultiRefAlignmentSpans(header, validationStringency); - addAllSpans(spanMap, spans); - break; - default: - addSpan(slice.sequenceId, slice.alignmentStart, slice.alignmentSpan, slice.nofRecords, spanMap); - break; - } - return spanMap; - } - - ArrayList getRecords(ArrayList records, - final Slice slice, final CompressionHeader header, final ValidationStringency validationStringency) throws IllegalArgumentException { - String seqName = SAMRecord.NO_ALIGNMENT_REFERENCE_NAME; - switch (slice.sequenceId) { - case SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX: - case -2: - break; - - default: - final SAMSequenceRecord sequence = samFileHeader - .getSequence(slice.sequenceId); - seqName = sequence.getSequenceName(); - break; - } - - final CramRecordReader reader = slice.createCramRecordReader(header, validationStringency); - - if (records == null) { - records = new ArrayList<>(slice.nofRecords); - } - - int prevStart = slice.alignmentStart; - for (int i = 0; i < slice.nofRecords; i++) { - final CramCompressionRecord record = new CramCompressionRecord(); - record.sliceIndex = slice.index; - record.index = i; - - reader.read(record); - - if (record.sequenceId == slice.sequenceId) { - record.sequenceName = seqName; - record.sequenceId = slice.sequenceId; - } else { - if (record.sequenceId == SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX) { - record.sequenceName = SAMRecord.NO_ALIGNMENT_REFERENCE_NAME; - } else { - record.sequenceName = samFileHeader.getSequence(record.sequenceId) - .getSequenceName(); - } - } - - records.add(record); - - if (header.APDelta) { - prevStart += record.alignmentDelta; - record.alignmentStart = prevStart; - } - } - - return records; - } - - List getRecords(final Slice slice, final CompressionHeader header, final ValidationStringency validationStringency) - throws IllegalArgumentException, IllegalAccessException { - return getRecords(null, slice, header, validationStringency); - } -} diff --git a/src/main/scala/org/biodatageeks/inputformats/CramBDGContainerIterator.java b/src/main/scala/org/biodatageeks/inputformats/CramBDGContainerIterator.java deleted file mode 100644 index b6654ceb..00000000 --- a/src/main/scala/org/biodatageeks/inputformats/CramBDGContainerIterator.java +++ /dev/null @@ -1,88 +0,0 @@ -package htsjdk.samtools.cram.build; - -import htsjdk.samtools.cram.common.Version; -import htsjdk.samtools.cram.io.CountingInputStream; -import htsjdk.samtools.cram.structure.*; -import htsjdk.samtools.cram.structure.BDGContainer; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Iterator; - -/** - * An iterator of CRAM containers read from an {@link java.io.InputStream}. - */ -public class CramBDGContainerIterator implements Iterator { - private CramHeader cramHeader; - private CountingInputStream countingInputStream; - private BDGContainer nextContainer; - private boolean eof = false; - private long offset = 0; - - public CramBDGContainerIterator(final InputStream inputStream) throws IOException { - this.countingInputStream = new CountingInputStream(inputStream); - cramHeader = CramIO.readCramHeader(countingInputStream); - this.offset = countingInputStream.getCount(); - } - - void readNextContainer() { - try { - nextContainer = containerFromStream(cramHeader.getVersion(), countingInputStream); - final long containerSizeInBytes = countingInputStream.getCount() - offset; - - nextContainer.offset = offset; - offset += containerSizeInBytes; - } catch (final IOException e) { - throw new RuntimeException(e); - } - - if (nextContainer.isEOF()) { - eof = true; - nextContainer = null; - } - } - - /** - * Consume the entirety of the next container from the stream. - * @param cramVersion - * @param countingStream - * @return The next Container from the stream. - * @throws IOException - */ - protected BDGContainer containerFromStream(final Version cramVersion, final CountingInputStream countingStream) throws IOException { - return htsjdk.samtools.cram.structure.ContainerBDGIO.readContainer(cramHeader.getVersion(), countingStream); - } - - @Override - public boolean hasNext() { - if (eof) return false; - if (nextContainer == null) readNextContainer(); - return !eof; - } - - @Override - public BDGContainer next() { - final BDGContainer result = nextContainer; - nextContainer = null; - return result; - } - - @Override - public void remove() { - throw new RuntimeException("Read only iterator."); - } - - public CramHeader getCramHeader() { - return cramHeader; - } - - public void close() { - nextContainer = null; - cramHeader = null; - //noinspection EmptyCatchBlock - try { - countingInputStream.close(); - } catch (final Exception e) { - } - } -} diff --git a/src/main/scala/org/biodatageeks/inputformats/CramBDGSpanContainerIterator.java b/src/main/scala/org/biodatageeks/inputformats/CramBDGSpanContainerIterator.java deleted file mode 100644 index 165c7b12..00000000 --- a/src/main/scala/org/biodatageeks/inputformats/CramBDGSpanContainerIterator.java +++ /dev/null @@ -1,99 +0,0 @@ -package htsjdk.samtools.cram.build; - -import htsjdk.samtools.cram.structure.*; -import htsjdk.samtools.cram.structure.BDGContainer; -import htsjdk.samtools.seekablestream.SeekableStream; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * An iterator of CRAM containers read from locations in {@link htsjdk.samtools.seekablestream.SeekableStream}. The locations are specified with - * pairs of coordinates, they are basically file pointers as returned for example by {@link htsjdk.samtools.SamReader.Indexing#getFilePointerSpanningReads()} - */ -public class CramBDGSpanContainerIterator implements Iterator { - private final CramHeader cramHeader; - private final SeekableStream seekableStream; - private Iterator containerBoundaries; - private Boundary currentBoundary; - private long firstContainerOffset; - - private CramBDGSpanContainerIterator(final SeekableStream seekableStream, final long[] coordinates) throws IOException { - this.seekableStream = seekableStream; - seekableStream.seek(0); - this.cramHeader = CramIO.readCramHeader(seekableStream); - firstContainerOffset = seekableStream.position(); - - final List boundaries = new ArrayList(); - for (int i = 0; i < coordinates.length; i += 2) { - boundaries.add(new Boundary(coordinates[i], coordinates[i + 1])); - } - - containerBoundaries = boundaries.iterator(); - currentBoundary = containerBoundaries.next(); - } - - public static CramBDGSpanContainerIterator fromFileSpan(final SeekableStream seekableStream, final long[] coordinates) throws IOException { - return new CramBDGSpanContainerIterator(seekableStream, coordinates); - } - - @Override - public boolean hasNext() { - try { - if (currentBoundary.hasNext()) return true; - if (!containerBoundaries.hasNext()) return false; - currentBoundary = containerBoundaries.next(); - return currentBoundary.hasNext(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public BDGContainer next() { - try { - return currentBoundary.next(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void remove() { - throw new RuntimeException("Not allowed."); - } - - public CramHeader getCramHeader() { - return cramHeader; - } - - private class Boundary { - final long start; - final long end; - - public Boundary(final long start, final long end) { - this.start = start; - this.end = end; - if (start >= end) throw new RuntimeException("Boundary start is greater than end."); - } - - boolean hasNext() throws IOException { - return seekableStream.position() <= (end >> 16); - } - - BDGContainer next() throws IOException { - if (seekableStream.position() < (start >> 16)) seekableStream.seek(start >> 16); - if (seekableStream.position() > (end >> 16)) throw new RuntimeException("No more containers in this boundary."); - final long offset = seekableStream.position(); - final BDGContainer c = htsjdk.samtools.cram.structure.ContainerBDGIO.readContainer(cramHeader.getVersion(), seekableStream); - c.offset = offset; - return c; - } - } - - public long getFirstContainerOffset() { - return firstContainerOffset; - } -} diff --git a/src/main/scala/org/biodatageeks/preprocessing/coverage/CoverageStrategy.scala b/src/main/scala/org/biodatageeks/preprocessing/coverage/CoverageStrategy.scala index 721bec0b..1495c59b 100644 --- a/src/main/scala/org/biodatageeks/preprocessing/coverage/CoverageStrategy.scala +++ b/src/main/scala/org/biodatageeks/preprocessing/coverage/CoverageStrategy.scala @@ -1,5 +1,6 @@ package org.biodatageeks.preprocessing.coverage +import org.apache.log4j.Logger import org.apache.spark.rdd.RDD import org.apache.spark.sql.catalyst.InternalRow import org.apache.spark.sql.catalyst.expressions.{Attribute, UnsafeProjection} @@ -8,7 +9,7 @@ import org.apache.spark.sql.execution.SparkPlan import org.apache.spark.sql._ import org.apache.spark.storage.StorageLevel import org.apache.spark.unsafe.types.UTF8String -import org.biodatageeks.datasources.BAM.{BDGAlignFileReaderWriter} +import org.biodatageeks.datasources.BAM.BDGAlignFileReaderWriter import org.biodatageeks.datasources.BDGInputDataType import org.biodatageeks.inputformats.BDGAlignInputFormat import org.biodatageeks.utils.{BDGInternalParams, BDGTableFuncs} @@ -87,8 +88,15 @@ case class BDGCoveragePlan [T<:BDGAlignInputFormat](plan: LogicalPlan, spark: Sp .dropRight(1) ++ Array(s"${sampleId}*.${fileExtension}")) .mkString("/") - setLocalConf(spark.sqlContext) - lazy val alignments = readBAMFile(spark.sqlContext, samplePath) + + + val refPath = sqlContext + .sparkContext + .hadoopConfiguration + .get(CRAMBDGInputFormat.REFERENCE_SOURCE_PATH_PROPERTY) + val logger = Logger.getLogger(this.getClass.getCanonicalName) + logger.info(s"Processing ${samplePath} with reference: ${refPath}") + lazy val alignments = readBAMFile(spark.sqlContext, samplePath, if( refPath == null || refPath.length == 0) None else Some(refPath)) val filterFlag = spark.sqlContext.getConf(BDGInternalParams.filterReadsByFlag, "1796").toInt diff --git a/src/main/scala/org/biodatageeks/utils/BDGInternalParams.scala b/src/main/scala/org/biodatageeks/utils/BDGInternalParams.scala index 3d7d5221..e98ca835 100644 --- a/src/main/scala/org/biodatageeks/utils/BDGInternalParams.scala +++ b/src/main/scala/org/biodatageeks/utils/BDGInternalParams.scala @@ -21,4 +21,12 @@ object BDGInternalParams { final val RDDEventsName = "spark.biodatageeks.events" final val InputSplitSize = "spark.biodatageeks.bam.splitSize" + + + /*disq support*/ + final val IOReadAlignmentMethod = "spark.biodatageeks.readAligment.method" + + /*Intel GKL support */ + final val UseIntelGKL = "spark.biodatageeks.bam.useGKLInflate" + } diff --git a/src/main/scala/org/biodatageeks/utils/BGDTableFuncs.scala b/src/main/scala/org/biodatageeks/utils/BGDTableFuncs.scala index ff56f275..41de6b83 100644 --- a/src/main/scala/org/biodatageeks/utils/BGDTableFuncs.scala +++ b/src/main/scala/org/biodatageeks/utils/BGDTableFuncs.scala @@ -26,6 +26,11 @@ object BDGTableFuncs{ statuses.head.getPath.toString } + def getParentFolderPath(spark: SparkSession, path: String): String = { + val fs = FileSystem.get(spark.sparkContext.hadoopConfiguration) + (new org.apache.hadoop.fs.Path(path)).getParent.toString + } + def getAllSamples(spark: SparkSession, path:String) = { val fs = FileSystem.get(spark.sparkContext.hadoopConfiguration) val statuses = fs.globStatus(new org.apache.hadoop.fs.Path(path)) diff --git a/src/main/scala/org/biodatageeks/utils/SequilaRegister.scala b/src/main/scala/org/biodatageeks/utils/SequilaRegister.scala index 236ea0d8..69b40cd3 100644 --- a/src/main/scala/org/biodatageeks/utils/SequilaRegister.scala +++ b/src/main/scala/org/biodatageeks/utils/SequilaRegister.scala @@ -22,6 +22,9 @@ object SequilaRegister { .sparkContext .hadoopConfiguration .setInt("mapred.max.split.size", spark.sqlContext.getConf(BDGInternalParams.InputSplitSize,"134217728").toInt) + spark + .sqlContext + .setConf(BDGInternalParams.IOReadAlignmentMethod,"hadoopBAM") } } diff --git a/src/test/resources/cram/test.cram b/src/test/resources/cram/test.cram new file mode 100644 index 0000000000000000000000000000000000000000..46fba540c6b2540c400860aa8399e40f224ba5ce GIT binary patch literal 162954 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 r1UN7|lH|72+|U@g$jVO|IxZYznOl(T)3{ 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 literal 0 HcmV?d00001 diff --git a/src/test/resources/cram/test.fa b/src/test/resources/cram/test.fa new file mode 100644 index 00000000..ee23432e --- /dev/null +++ b/src/test/resources/cram/test.fa @@ -0,0 +1,91 @@ +>phix-illumina.fa +GAGTTTTATCGCTTCCATGACGCAGAAGTTAACACTTTCGGATATTTCTGATGAGTCGAA +AAATTATCTTGATAAAGCAGGAATTACTACTGCTTGTTTACGAATTAAATCGAAGTGGAC +TGCTGGCGGAAAATGAGAAAATTCGACCTATCCTTGCGCAGCTCGAGAAGCTCTTACTTT +GCGACCTTTCGCCATCAACTAACGATTCTGTCAAAAACTGACGCGTTGGATGAGGAGAAG +TGGCTTAATATGCTTGGCACGTTCGTCAAGGACTGGTTTAGATATGAGTCACATTTTGTT +CATGGTAGAGATTCTCTTGTTGACATTTTAAAAGAGCGTGGATTACTATCTGAGTCCGAT +GCTGTTCAACCACTAATAGGTAAGAAATCATGAGTCAAGTTACTGAACAATCCGTACGTT +TCCAGACCGCTTTGGCCTCTATTAAGCTCATTCAGGCTTCTGCCGTTTTGGATTTAACCG +AAGATGATTTCGATTTTCTGACGAGTAACAAAGTTTGGATTGCTACTGACCGCTCTCGTG +CTCGTCGCTGCGTTGAGGCTTGCGTTTATGGTACGCTGGACTTTGTAGGATACCCTCGCT +TTCCTGCTCCTGTTGAGTTTATTGCTGCCGTCATTGCTTATTATGTTCATCCCGTCAACA +TTCAAACGGCCTGTCTCATCATGGAAGGCGCTGAATTTACGGAAAACATTATTAATGGCG +TCGAGCGTCCGGTTAAAGCCGCTGAATTGTTCGCGTTTACCTTGCGTGTACGCGCAGGAA +ACACTGACGTTCTTACTGACGCAGAAGAAAACGTGCGTCAAAAATTACGTGCAGAAGGAG +TGATGTAATGTCTAAAGGTAAAAAACGTTCTGGCGCTCGCCCTGGTCGTCCGCAGCCGTT +GCGAGGTACTAAAGGCAAGCGTAAAGGCGCTCGTCTTTGGTATGTAGGTGGTCAACAATT +TTAATTGCAGGGGCTTCGGCCCCTTACTTGAGGATAAATTATGTCTAATATTCAAACTGG +CGCCGAGCGTATGCCGCATGACCTTTCCCATCTTGGCTTCCTTGCTGGTCAGATTGGTCG +TCTTATTACCATTTCAACTACTCCGGTTATCGCTGGCGACTCCTTCGAGATGGACGCCGT +TGGCGCTCTCCGTCTTTCTCCATTGCGTCGTGGCCTTGCTATTGACTCTACTGTAGACAT +TTTTACTTTTTATGTCCCTCATCGTCACGTTTATGGTGAACAGTGGATTAAGTTCATGAA +GGATGGTGTTAATGCCACTCCTCTCCCGACTGTTAACACTACTGGTTATATTGACCATGC +CGCTTTTCTTGGCACGATTAACCCTGATACCAATAAAATCCCTAAGCATTTGTTTCAGGG +TTATTTGAATATCTATAACAACTATTTTAAAGCGCCGTGGATGCCTGACCGTACCGAGGC +TAACCCTAATGAGCTTAATCAAGATGATGCTCGTTATGGTTTCCGTTGCTGCCATCTCAA +AAACATTTGGACTGCTCCGCTTCCTCCTGAGACTGAGCTTTCTCGCCAAATGACGACTTC +TACCACATCTATTGACATTATGGGTCTGCAAGCTGCTTATGCTAATTTGCATACTGACCA +AGAACGTGATTACTTCATGCAGCGTTACCATGATGTTATTTCTTCATTTGGAGGTAAAAC +CTCTTATGACGCTGACAACCGTCCTTTACTTGTCATGCGCTCTAATCTCTGGGCATCTGG +CTATGATGTTGATGGAACTGACCAAACGTCGTTAGGCCAGTTTTCTGGTCGTGTTCAACA +GACCTATAAACATTCTGTGCCGCGTTTCTTTGTTCCTGAGCATGGCACTATGTTTACTCT +TGCGCTTGTTCGTTTTCCGCCTACTGCGACTAAAGAGATTCAGTACCTTAACGCTAAAGG +TGCTTTGACTTATACCGATATTGCTGGCGACCCTGTTTTGTATGGCAACTTGCCGCCGCG +TGAAATTTCTATGAAGGATGTTTTCCGTTCTGGTGATTCGTCTAAGAAGTTTAAGATTGC +TGAGGGTCAGTGGTATCGTTATGCGCCTTCGTATGTTTCTCCTGCTTATCACCTTCTTGA +AGGCTTCCCATTCATTCAGGAACCGCCTTCTGGTGATTTGCAAGAACGCGTACTTATTCG +CCACCATGATTATGACCAGTGTTTCCAGTCCGTTCAGTTGTTGCAGTGGAATAGTCAGGT +TAAATTTAATGTGACCGTTTATCGCAATCTGCCGACCACTCGCGATTCAATCATGACTTC +GTGATAAAAGATTGAGTGTGAGGTTATAACGCCGAAGCGGTAAAAATTTTAATTTTTGCC +GCTGAGGGGTTGACCAAGCGAAGCGCGGTAGGTTTTCTGCTTAGGAGTTTAATCATGTTT +CAGACTTTTATTTCTCGCCATAATTCAAACTTTTTTTCTGATAAGCTGGTTCTCACTTCT +GTTACTCCAGCTTCTTCGGCACCTGTTTTACAGACACCTAAAGCTACATCGTCAACGTTA +TATTTTGATAGTTTGACGGTTAATGCTGGTAATGGTGGTTTTCTTCATTGCATTCAGATG +GATACATCTGTCAACGCCGCTAATCAGGTTGTTTCTGTTGGTGCTGATATTGCTTTTGAT +GCCGACCCTAAATTTTTTGCCTGTTTGGTTCGCTTTGAGTCTTCTTCGGTTCCGACTACC +CTCCCGACTGCCTATGATGTTTATCCTTTGGATGGTCGCCATGATGGTGGTTATTATACC +GTCAAGGACTGTGTGACTATTGACGTCCTTCCTCGTACGCCGGGCAATAATGTTTATGTT +GGTTTCATGGTTTGGTCTAACTTTACCGCTACTAAATGCCGCGGATTGGTTTCGCTGAAT +CAGGTTATTAAAGAGATTATTTGTCTCCAGCCACTTAAGTGAGGTGATTTATGTTTGGTG +CTATTGCTGGCGGTATTGCTTCTGCTCTTGCTGGTGGCGCCATGTCTAAATTGTTTGGAG +GCGGTCAAAAAGCCGCCTCCGGTGGCATTCAAGGTGATGTGCTTGCTACCGATAACAATA +CTGTAGGCATGGGTGATGCTGGTATTAAATCTGCCATTCAAGGCTCTAATGTTCCTAACC +CTGATGAGGCCGCCCCTAGTTTTGTTTCTGGTGCTATGGCTAAAGCTGGTAAAGGACTTC +TTGAAGGTACGTTGCAGGCTGGCACTTCTGCCGTTTCTGATAAGTTGCTTGATTTGGTTG +GACTTGGTGGCAAGTCTGCCGCTGATAAAGGAAAGGATACTCGTGATTATCTTGCTGCTG +CATTTCCTGAGCTTAATGCTTGGGAGCGTGCTGGTGCTGATGCTTCCTCTGCTGGTATGG +TTGACGCCGGATTTGAGAATCAAAAAGAGCTTACTAAAATGCAACTGGACAATCAGAAAG +AGATTGCCGAGATGCAAAATGAGACTCAAAAAGAGATTGCTGGCATTCAGTCGGCGACTT +CACGCCAGAATACGAAAGACCAGGTATATGCACAAAATGAGATGCTTGCTTATCAACAGA +AGGAGTCTACTGCTCGCGTTGCGTCTATTATGGAAAACACCAATCTTTCCAAGCAACAGC +AGGTTTCCGAGATTATGCGCCAAATGCTTACTCAAGCTCAAACGGCTGGTCAGTATTTTA +CCAATGACCAAATCAAAGAAATGACTCGCAAGGTTAGTGCTGAGGTTGACTTAGTTCATC +AGCAAACGCAGAATCAGCGGTATGGCTCTTCTCATATTGGCGCTACTGCAAAGGATATTT +CTAATGTCGTCACTGATGCTGCTTCTGGTGTGGTTGATATTTTTCATGGTATTGATAAAG +CTGTTGCCGATACTTGGAACAATTTCTGGAAAGACGGTAAAGCTGATGGTATTGGCTCTA +ATTTGTCTAGGAAATAACCGTCAGGATTGACACCCTCCCAATTGTATGTTTTCATGCCTC +CAAATCTTGGAGGCTTTTTTATGGTTCGTTCTTATTACCCTTCTGAATGTCACGCTGATT +ATTTTGACTTTGAGCGTATCGAGGCTCTTAAACCTGCTATTGAGGCTTGTGGCATTTCTA +CTCTTTCTCAATCCCCAATGCTTGGCTTCCATAAGCAGATGGATAACCGCATCAAGCTCT +TGGAAGAGATTCTGTCTTTTCGTATGCAGGGCGTTGAGTTCGATAATGGTGATATGTATG +TTGACGGCCATAAGGCTGCTTCTGACGTTCGTGATGAGTTTGTATCTGTTACTGAGAAGT +TAATGGATGAATTGGCACAATGCTACAATGTGCTCCCCCAACTTGATATTAATAACACTA +TAGACCACCGCCCCGAAGGGGACGAAAAATGGTTTTTAGAGAACGAGAAGACGGTTACGC +AGTTTTGCCGCAAGCTGGCTGCTGAACGCCCTCTTAAGGATATTCGCGATGAGTATAATT +ACCCCAAAAAGAAAGGTATTAAGGATGAGTGTTCAAGATTGCTGGAGGCCTCCACTATGA +AATCGCGTAGAGGCTTTGCTATTCAGCGTTTGATGAATGCAATGCGACAGGCTCATGCTG +ATGGTTGGTTTATCGTTTTTGACACTCTCACGTTGGCTGACGACCGATTAGAGGCGTTTT +ATGATAATCCCAATGCTTTGCGTGACTATTTTCGTGATATTGGTCGTATGGTTCTTGCTG +CCGAGGGTCGCAAGGCTAATGATTCACACGCCGACTGCTATCAGTATTTTTGTGTGCCTG +AGTATGGTACAGCTAATGGCCGTCTTCATTTCCATGCGGTGCACTTTATGCGGACACTTC +CTACAGGTAGCGTTGACCCTAATTTTGGTCGTCGGGTACGCAATCGCCGCCAGTTAAATA +GCTTGCAAAATACGTGGCCTTATGGTTACAGTATGCCCATCGCAGTTCGCTACACGCAGG +ACGCTTTTTCACGTTCTGGTTGGTTGTGGCCTGTTGATGCTAAAGGTGAGCCGCTTAAAG +CTACCAGTTATATGGCTGTTGGTTTCTATGTGGCTAAATACGTTAACAAAAAGTCAGATA +TGGACCTTGCTGCTAAAGGTCTAGGAGCTAAAGAATGGAACAACTCACTAAAAACCAAGC +TGTCGCTACTTCCCAAGAAGCTGTTCAGAATCAGAATGAGCCGCAACTTCGGGATGAAAA +TGCTCACAATGACAAATCTGTCCACGGAGTGCTTAATCCAACTTACCAAGCTGGGTTACG +ACGCGACGCCGTTCAACCAGATATTGAAGCAGAACGCAAAAAGAGAGATGAGATTGAGGC +TGGGAAAAGTTACTGTAGCCGACGTTTTGGCGGCGCAACCTGTGACGACAAATCTGCTCA +AATTTATGCGCGCTTCGATAAAAATGATTGGCGTATCCAACCTGCA \ No newline at end of file diff --git a/src/test/resources/cram/test.fa.fai b/src/test/resources/cram/test.fa.fai new file mode 100644 index 00000000..5dab71b3 --- /dev/null +++ b/src/test/resources/cram/test.fa.fai @@ -0,0 +1 @@ +phix-illumina.fa 5386 18 60 61 diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties index 65ef1894..adebc577 100644 --- a/src/test/resources/log4j.properties +++ b/src/test/resources/log4j.properties @@ -25,7 +25,7 @@ log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: # Set the default spark-shell log level to WARN. When running the spark-shell, the # log level for this class is used to overwrite the root logger's log level, so that # the user can have different defaults for the shell and regular Spark apps. -log4j.logger.org.apache.spark.repl.Main=WARN +log4j.logger.org.apache.spark.repl.Main=INFO # Settings to quiet third party logs that are too verbose log4j.logger.org.spark_project.jetty=WARN diff --git a/src/test/scala/pl/edu/pw/ii/biodatageeks/tests/CoverageTestSuite.scala b/src/test/scala/pl/edu/pw/ii/biodatageeks/tests/CoverageTestSuite.scala index a751d265..edaa6f53 100644 --- a/src/test/scala/pl/edu/pw/ii/biodatageeks/tests/CoverageTestSuite.scala +++ b/src/test/scala/pl/edu/pw/ii/biodatageeks/tests/CoverageTestSuite.scala @@ -11,63 +11,64 @@ import org.scalatest.{BeforeAndAfter, FunSuite} class CoverageTestSuite extends FunSuite with DataFrameSuiteBase with BeforeAndAfter with SharedSparkContext{ - val bamPath = getClass.getResource("/NA12878.slice.bam").getPath - val bamMultiPath = getClass.getResource("/multichrom/bam/NA12878.multichrom.bam").getPath - val cramMultiPath = getClass.getResource("/multichrom/cram/NA12878.multichrom.cram").getPath - val refMultiPath = getClass.getResource("/multichrom/NA12878.multichrom.fasta").getPath - val adamPath = getClass.getResource("/NA12878.slice.adam").getPath - val metricsListener = new MetricsListener(new RecordedMetrics()) - val writer = new PrintWriter(new OutputStreamWriter(System.out)) - val tableNameBAM = "reads" - val tableNameMultiBAM = "readsBAMMulti" - val tableNameMultiCRAM = "readsCRAMMulti" - val tableNameADAM = "readsADAM" - val tableNameCRAM = "readsCRAM" - val splitSize = "1000000" - - before{ - - Metrics.initialize(sc) - sc.addSparkListener(metricsListener) - System.setSecurityManager(null) - spark.sql(s"DROP TABLE IF EXISTS ${tableNameBAM}") - spark.sql( - s""" - |CREATE TABLE ${tableNameBAM} - |USING org.biodatageeks.datasources.BAM.BAMDataSource - |OPTIONS(path "${bamPath}") - | + val bamPath = getClass.getResource("/NA12878.slice.bam").getPath + val bamMultiPath = getClass.getResource("/multichrom/bam/NA12878.multichrom.bam").getPath + val adamPath = getClass.getResource("/NA12878.slice.adam").getPath + val metricsListener = new MetricsListener(new RecordedMetrics()) + val writer = new PrintWriter(new OutputStreamWriter(System.out)) + val cramPath = getClass.getResource("/cram/test.cram").getPath + val refPath = getClass.getResource("/cram/test.fa").getPath + val tableNameBAM = "reads" + val tableNameMultiBAM = "readsMulti" + val tableNameADAM = "readsADAM" + val tableNameCRAM = "readsCRAM" + val splitSize = "1000000" + + val alignReadMethods = Array("disq","hadoopBAM") + + before{ + + + Metrics.initialize(sc) + sc.addSparkListener(metricsListener) + System.setSecurityManager(null) + spark.sql(s"DROP TABLE IF EXISTS ${tableNameBAM}") + spark.sql( + s""" + |CREATE TABLE ${tableNameBAM} + |USING org.biodatageeks.datasources.BAM.BAMDataSource + |OPTIONS(path "${bamPath}") + | """.stripMargin) - spark.sql(s"DROP TABLE IF EXISTS ${tableNameMultiBAM}") - spark.sql( - s""" - |CREATE TABLE ${tableNameMultiBAM} - |USING org.biodatageeks.datasources.BAM.BAMDataSource - |OPTIONS(path "${bamMultiPath}") - | + spark.sql(s"DROP TABLE IF EXISTS ${tableNameMultiBAM}") + spark.sql( + s""" + |CREATE TABLE ${tableNameMultiBAM} + |USING org.biodatageeks.datasources.BAM.BAMDataSource + |OPTIONS(path "${bamMultiPath}") + | """.stripMargin) - spark.sql(s"DROP TABLE IF EXISTS ${tableNameMultiCRAM}") - spark.sql( - s""" - |CREATE TABLE ${tableNameMultiCRAM} - |USING org.biodatageeks.datasources.BAM.CRAMDataSource - |OPTIONS(path "${cramMultiPath}", refPath "${refMultiPath}") - | + spark.sql(s"DROP TABLE IF EXISTS ${tableNameCRAM}") + spark.sql( + s""" + |CREATE TABLE ${tableNameCRAM} + |USING org.biodatageeks.datasources.BAM.CRAMDataSource + |OPTIONS(path "${cramPath}", refPath "${refPath}") + | """.stripMargin) - - spark.sql(s"DROP TABLE IF EXISTS ${tableNameADAM}") - spark.sql( - s""" - |CREATE TABLE ${tableNameADAM} - |USING org.biodatageeks.datasources.ADAM.ADAMDataSource - |OPTIONS(path "${adamPath}") - | + spark.sql(s"DROP TABLE IF EXISTS ${tableNameADAM}") + spark.sql( + s""" + |CREATE TABLE ${tableNameADAM} + |USING org.biodatageeks.datasources.ADAM.ADAMDataSource + |OPTIONS(path "${adamPath}") + | """.stripMargin) - } + } /* @@ -87,18 +88,21 @@ class CoverageTestSuite extends FunSuite with DataFrameSuiteBase with BeforeAndA val session: SparkSession = SequilaSession(spark) SequilaRegister.register(session) - val windowLength = 100 - val bdg = session.sql(s"SELECT * FROM bdg_coverage('${tableNameMultiBAM}','NA12878', 'blocks', '${windowLength}')") - - assert (bdg.count == 267) - assert (bdg.first().getInt(1) % windowLength == 0) // check for fixed window start position - assert (bdg.first().getInt(2) % windowLength == windowLength - 1) // // check for fixed window end position - assert(bdg.where("contigName == 'chr1' and start == 2700").first().getFloat(3)==4.65.toFloat) - assert(bdg.where("contigName == 'chr1' and start == 3200").first().getFloat(3)== 166.79.toFloat) - assert(bdg.where("contigName == 'chr1' and start == 10000").first().getFloat(3)== 1.5522388.toFloat) //value check [partition boundary] - assert(bdg.where("contigName == 'chrM' and start == 7800").first().getFloat(3)== 253.03001.toFloat) //value check [partition boundary] - assert(bdg.where("contigName == 'chrM' and start == 14400").first().getFloat(3)== 134.7.toFloat) //value check [partition boundary] - assert(bdg.groupBy("contigName", "start").count().where("count != 1").count == 0) // no duplicates check + alignReadMethods.foreach { m=> + spark.sqlContext.setConf(BDGInternalParams.IOReadAlignmentMethod,m) + val windowLength = 100 + val bdg = session.sql(s"SELECT * FROM bdg_coverage('${tableNameMultiBAM}','NA12878', 'blocks', '${windowLength}')") + + assert(bdg.count == 267) + assert(bdg.first().getInt(1) % windowLength == 0) // check for fixed window start position + assert(bdg.first().getInt(2) % windowLength == windowLength - 1) // // check for fixed window end position + assert(bdg.where("contigName == 'chr1' and start == 2700").first().getFloat(3) == 4.65.toFloat) + assert(bdg.where("contigName == 'chr1' and start == 3200").first().getFloat(3) == 166.79.toFloat) + assert(bdg.where("contigName == 'chr1' and start == 10000").first().getFloat(3) == 1.5522388.toFloat) //value check [partition boundary] + assert(bdg.where("contigName == 'chrM' and start == 7800").first().getFloat(3) == 253.03001.toFloat) //value check [partition boundary] + assert(bdg.where("contigName == 'chrM' and start == 14400").first().getFloat(3) == 134.7.toFloat) //value check [partition boundary] + assert(bdg.groupBy("contigName", "start").count().where("count != 1").count == 0) // no duplicates check + } } test("BAM - bdg_coverage - blocks - allPositions"){ @@ -106,123 +110,63 @@ class CoverageTestSuite extends FunSuite with DataFrameSuiteBase with BeforeAndA val session: SparkSession = SequilaSession(spark) SequilaRegister.register(session) - session.experimental.extraStrategies = new CoverageStrategy(session) :: Nil - - session.sqlContext.setConf(BDGInternalParams.ShowAllPositions,"true") - - val bdg = session.sql(s"SELECT * FROM bdg_coverage('${tableNameMultiBAM}','NA12878', 'blocks')") - - assert(bdg.count() == 12865) - assert(bdg.first().get(1) == 1) // first position check (should start from 1 with ShowAllPositions = true) - assert(bdg.where("contigName='chr1' and start == 35").first().getShort(3) == 2) // value check - assert(bdg.where("contigName='chrM' and start == 7").first().getShort(3) == 1) // value check [partition boundary] - assert(bdg.where("contigName='chrM' and start == 7881").first().getShort(3) == 248) // value check [partition boundary] - assert(bdg.where("contigName='chrM' and start == 7882").first().getShort(3) == 247) // value check [partition boundary] - assert(bdg.where("contigName='chrM' and start == 7883").first().getShort(3) == 246) // value check [partition boundary] - assert(bdg.where("contigName='chrM' and start == 14402").first().getShort(3) == 182) // value check [partition boundary] - assert(bdg.groupBy("contigName").max("end").where("contigName == 'chr1'").first().get(1) == 247249719) // max value check - assert(bdg.groupBy("contigName").max("end").where("contigName == 'chrM'").first().get(1) == 16571) // max value check - assert(bdg.groupBy("contigName", "start").count().where("count != 1").count == 0) // no duplicates check - } + alignReadMethods.foreach { m => + spark.sqlContext.setConf(BDGInternalParams.IOReadAlignmentMethod, m) + session.experimental.extraStrategies = new CoverageStrategy(session) :: Nil - test("BAM - bdg_coverage - blocks notAllPositions"){ - spark.sqlContext.setConf(BDGInternalParams.InputSplitSize, splitSize) - val session: SparkSession = SequilaSession(spark) - SequilaRegister.register(session) + session.sqlContext.setConf(BDGInternalParams.ShowAllPositions, "true") - session.sqlContext.setConf(BDGInternalParams.ShowAllPositions,"false") + val bdg = session.sql(s"SELECT * FROM bdg_coverage('${tableNameMultiBAM}','NA12878', 'blocks')") - val bdg = session.sql(s"SELECT * FROM bdg_coverage('${tableNameMultiBAM}','NA12878', 'blocks')") - - assert(bdg.count() == 12861) // total count check - assert(bdg.first().get(1) != 1) // first position check (should not start from 1 with ShowAllPositions = false) - assert(bdg.where("contigName='chr1' and start == 35").first().getShort(3) == 2) // value check - assert(bdg.where("contigName='chrM' and start == 7").first().getShort(3) == 1) // value check [partition boundary] - assert(bdg.where("contigName='chrM' and start == 7881").first().getShort(3) == 248) // value check [partition boundary] - assert(bdg.where("contigName='chrM' and start == 7882").first().getShort(3) == 247) // value check [partition boundary] - assert(bdg.where("contigName='chrM' and start == 7883").first().getShort(3) == 246) // value check [partition boundary] - assert(bdg.where("contigName='chrM' and start == 14402").first().getShort(3) == 182) // value check [partition boundary] - assert(bdg.groupBy("contigName").max("end").where("contigName == 'chr1'").first().get(1) == 10066) // max value check - assert(bdg.groupBy("contigName").max("end").where("contigName == 'chrM'").first().get(1) == 16571) // max value check - assert(bdg.groupBy("contigName", "start").count().where("count != 1").count == 0) // no duplicates check + assert(bdg.count() == 12865) + assert(bdg.first().get(1) == 1) // first position check (should start from 1 with ShowAllPositions = true) + assert(bdg.where("contigName='chr1' and start == 35").first().getShort(3) == 2) // value check + assert(bdg.where("contigName='chrM' and start == 7").first().getShort(3) == 1) // value check [partition boundary] + assert(bdg.where("contigName='chrM' and start == 7881").first().getShort(3) == 248) // value check [partition boundary] + assert(bdg.where("contigName='chrM' and start == 7882").first().getShort(3) == 247) // value check [partition boundary] + assert(bdg.where("contigName='chrM' and start == 7883").first().getShort(3) == 246) // value check [partition boundary] + assert(bdg.where("contigName='chrM' and start == 14402").first().getShort(3) == 182) // value check [partition boundary] + assert(bdg.groupBy("contigName").max("end").where("contigName == 'chr1'").first().get(1) == 247249719) // max value check + assert(bdg.groupBy("contigName").max("end").where("contigName == 'chrM'").first().get(1) == 16571) // max value check + assert(bdg.groupBy("contigName", "start").count().where("count != 1").count == 0) // no duplicates check + } } - test("BAM - bdg_coverage - bases - notAllPositions"){ + test("BAM - bdg_coverage - blocks notAllPositions"){ spark.sqlContext.setConf(BDGInternalParams.InputSplitSize, splitSize) val session: SparkSession = SequilaSession(spark) SequilaRegister.register(session) session.sqlContext.setConf(BDGInternalParams.ShowAllPositions,"false") - val bdg = session.sql(s"SELECT contigName, start, end, coverage FROM bdg_coverage('${tableNameMultiBAM}','NA12878', 'bases')") - - assert(bdg.count() == 26598) // total count check // was 26598 - assert(bdg.first().get(1) != 1) // first position check (should not start from 1 with ShowAllPositions = false) - assert(bdg.where("contigName='chr1' and start == 35").first().getShort(3) == 2) // value check - assert(bdg.where("contigName='chr1' and start == 88").first().getShort(3) == 7) - assert(bdg.where("contigName='chrM' and start == 7").first().getShort(3) == 1) // value check [partition boundary] - assert(bdg.where("contigName='chrM' and start == 7881").first().getShort(3) == 248) // value check [partition boundary] - assert(bdg.where("contigName='chrM' and start == 7882").first().getShort(3) == 247) // value check [partition boundary] - assert(bdg.where("contigName='chrM' and start == 7883").first().getShort(3) == 246) // value check [partition boundary] - assert(bdg.where("contigName='chrM' and start == 14402").first().getShort(3) == 182) // value check [partition boundary] - assert(bdg.groupBy("contigName").max("end").where("contigName == 'chr1'").first().get(1) == 10066) // max value check - assert(bdg.groupBy("contigName").max("end").where("contigName == 'chrM'").first().get(1) == 16571) // max value check - assert(bdg.groupBy("contigName", "start").count().where("count != 1").count == 0) // no duplicates check - - } - test("CRAM - bdg_coverage - windows"){ + alignReadMethods.foreach { m => + spark.sqlContext.setConf(BDGInternalParams.IOReadAlignmentMethod, m) - spark.sqlContext.setConf(BDGInternalParams.InputSplitSize, splitSize) - - val session: SparkSession = SequilaSession(spark) - SequilaRegister.register(session) + val bdg = session.sql(s"SELECT * FROM bdg_coverage('${tableNameMultiBAM}','NA12878', 'blocks')") - session.sql(s"desc formatted ${tableNameMultiCRAM}").show(100,false) - val windowLength = 100 - val bdg = session.sql(s"SELECT * FROM bdg_coverage('${tableNameMultiCRAM}','NA12878', 'blocks', '${windowLength}')") - - assert (bdg.count == 267) - assert (bdg.first().getInt(1) % windowLength == 0) // check for fixed window start position - assert (bdg.first().getInt(2) % windowLength == windowLength - 1) // // check for fixed window end position - assert(bdg.where("contigName == 'chr1' and start == 2700").first().getFloat(3)==4.65.toFloat) - assert(bdg.where("contigName == 'chr1' and start == 3200").first().getFloat(3)== 166.79.toFloat) - assert(bdg.where("contigName == 'chr1' and start == 10000").first().getFloat(3)== 1.5522388.toFloat) //value check [partition boundary] - assert(bdg.where("contigName == 'chrM' and start == 7800").first().getFloat(3)== 253.03.toFloat) //value check [partition boundary] - assert(bdg.where("contigName == 'chrM' and start == 14400").first().getFloat(3)== 134.7.toFloat) //value check [partition boundary] - assert(bdg.groupBy("contigName", "start").count().where("count != 1").count == 0) // no duplicates check - } - - test("CRAM - bdg_coverage - blocks - allPositions"){ - spark.sqlContext.setConf(BDGInternalParams.InputSplitSize, splitSize) - - val session: SparkSession = SequilaSession(spark) - SequilaRegister.register(session) - session.experimental.extraStrategies = new CoverageStrategy(session) :: Nil - - session.sqlContext.setConf(BDGInternalParams.ShowAllPositions,"true") - - val bdg = session.sql(s"SELECT * FROM bdg_coverage('${tableNameMultiCRAM}','NA12878', 'blocks')") - - assert(bdg.count() == 12865) - assert(bdg.first().get(1) == 1) // first position check (should start from 1 with ShowAllPositions = true) + assert(bdg.count() == 12861) // total count check + assert(bdg.first().get(1) != 1) // first position check (should not start from 1 with ShowAllPositions = false) assert(bdg.where("contigName='chr1' and start == 35").first().getShort(3) == 2) // value check assert(bdg.where("contigName='chrM' and start == 7").first().getShort(3) == 1) // value check [partition boundary] assert(bdg.where("contigName='chrM' and start == 7881").first().getShort(3) == 248) // value check [partition boundary] assert(bdg.where("contigName='chrM' and start == 7882").first().getShort(3) == 247) // value check [partition boundary] assert(bdg.where("contigName='chrM' and start == 7883").first().getShort(3) == 246) // value check [partition boundary] assert(bdg.where("contigName='chrM' and start == 14402").first().getShort(3) == 182) // value check [partition boundary] - assert(bdg.groupBy("contigName").max("end").where("contigName == 'chr1'").first().get(1) == 247249719) // max value check + assert(bdg.groupBy("contigName").max("end").where("contigName == 'chr1'").first().get(1) == 10066) // max value check assert(bdg.groupBy("contigName").max("end").where("contigName == 'chrM'").first().get(1) == 16571) // max value check assert(bdg.groupBy("contigName", "start").count().where("count != 1").count == 0) // no duplicates check } + } - test("CRAM - bdg_coverage - bases - notAllPositions"){ - spark.sqlContext.setConf(BDGInternalParams.InputSplitSize, splitSize) - val session: SparkSession = SequilaSession(spark) - SequilaRegister.register(session) + test("BAM - bdg_coverage - bases - notAllPositions"){ + spark.sqlContext.setConf(BDGInternalParams.InputSplitSize, splitSize) + val session: SparkSession = SequilaSession(spark) + SequilaRegister.register(session) - session.sqlContext.setConf(BDGInternalParams.ShowAllPositions,"false") - val bdg = session.sql(s"SELECT contigName, start, end, coverage FROM bdg_coverage('${tableNameMultiCRAM}','NA12878', 'bases')") + session.sqlContext.setConf(BDGInternalParams.ShowAllPositions,"false") + alignReadMethods.foreach { m => + spark.sqlContext.setConf(BDGInternalParams.IOReadAlignmentMethod, m) + val bdg = session.sql(s"SELECT contigName, start, end, coverage FROM bdg_coverage('${tableNameMultiBAM}','NA12878', 'bases')") assert(bdg.count() == 26598) // total count check // was 26598 assert(bdg.first().get(1) != 1) // first position check (should not start from 1 with ShowAllPositions = false) @@ -236,18 +180,31 @@ class CoverageTestSuite extends FunSuite with DataFrameSuiteBase with BeforeAndA assert(bdg.groupBy("contigName").max("end").where("contigName == 'chr1'").first().get(1) == 10066) // max value check assert(bdg.groupBy("contigName").max("end").where("contigName == 'chrM'").first().get(1) == 16571) // max value check assert(bdg.groupBy("contigName", "start").count().where("count != 1").count == 0) // no duplicates check - } + } - test("BAM - bdg_coverage - wrong param, Exception should be thrown") { - val session: SparkSession = SequilaSession(spark) - SequilaRegister.register(session) + test("CRAM - bdg_coverage - show"){ + val session: SparkSession = SequilaSession(spark) + SequilaRegister.register(session) - assertThrows[Exception]( - session.sql(s"SELECT * FROM bdg_coverage('${tableNameMultiBAM}','NA12878', 'blaaaaaah')").show()) + alignReadMethods.foreach { m => + spark.sqlContext.setConf(BDGInternalParams.IOReadAlignmentMethod, m) + val bdg = session.sql(s"SELECT * FROM bdg_coverage('${tableNameCRAM}','test', 'blocks') ") + assert(bdg.count() == 49) + assert(bdg.where("start == 107").first().getShort(3) == 459) } + } + + test("BAM - bdg_coverage - wrong param, Exception should be thrown") { + val session: SparkSession = SequilaSession(spark) + SequilaRegister.register(session) + + assertThrows[Exception]( + session.sql(s"SELECT * FROM bdg_coverage('${tableNameMultiBAM}','NA12878', 'blaaaaaah')").show()) + + } after{ @@ -257,4 +214,4 @@ class CoverageTestSuite extends FunSuite with DataFrameSuiteBase with BeforeAndA } -} +} \ No newline at end of file