[med-svn] [picard-tools] 01/01: Imported Upstream version 2.1.1+dfsg
Andreas Tille
tille at debian.org
Sun Mar 13 06:48:05 UTC 2016
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch upstream
in repository picard-tools.
commit 115543bd046ef93efa75c1d16e9f6af3baa8c94b
Author: Andreas Tille <tille at debian.org>
Date: Sun Mar 13 07:44:27 2016 +0100
Imported Upstream version 2.1.1+dfsg
---
build.sbt | 4 +-
build.xml | 155 +++++++++++---------
src/java/picard/Test.java | 6 +-
src/java/picard/analysis/CollectGcBiasMetrics.java | 4 +-
.../picard/analysis/CollectMultipleMetrics.java | 44 +++---
src/java/picard/analysis/CollectRrbsMetrics.java | 4 +-
.../picard/analysis/GcBiasMetricsCollector.java | 6 +-
src/java/picard/analysis/MeanQualityByCycle.java | 2 +-
.../CollectSequencingArtifactMetrics.java | 16 +-
.../analysis/directed/TargetMetricsCollector.java | 4 +-
src/java/picard/cmdline/CommandLineParser.java | 147 ++++++++++++-------
.../CrosscheckReadGroupFingerprints.java | 2 +-
src/java/picard/fingerprint/HaplotypeMap.java | 4 +-
...lotypeProbabilitiesFromGenotypeLikelihoods.java | 2 +-
.../picard/illumina/ClusterDataToSamConverter.java | 6 +-
.../picard/illumina/ExtractIlluminaBarcodes.java | 10 +-
.../picard/illumina/IlluminaBasecallsToFastq.java | 6 +-
.../picard/illumina/IlluminaBasecallsToSam.java | 10 +-
src/java/picard/illumina/MarkIlluminaAdapters.java | 2 +-
src/java/picard/illumina/parser/BarcodeParser.java | 2 +-
.../illumina/parser/FourChannelIntensityData.java | 8 +-
.../parser/IlluminaDataProviderFactory.java | 4 +-
.../picard/illumina/parser/IlluminaFileUtil.java | 4 +-
.../illumina/parser/MultiTileBclFileUtil.java | 2 +-
.../picard/illumina/parser/PerTileFileUtil.java | 2 +-
src/java/picard/illumina/parser/ReadStructure.java | 4 +-
src/java/picard/illumina/parser/TileIndex.java | 2 +-
.../illumina/parser/fakers/BarcodeFileFaker.java | 8 +-
.../illumina/parser/fakers/PosFileFaker.java | 8 +-
.../readers/BclQualityEvaluationStrategy.java | 2 +-
.../illumina/parser/readers/FilterFileReader.java | 2 +-
.../parser/readers/MMapBackedIteratorFactory.java | 4 +-
.../quality/CollectHiSeqXPfFailMetrics.java | 2 +-
src/java/picard/sam/FastqToSam.java | 2 +-
src/java/picard/sam/FilterSamReads.java | 52 +++++--
src/java/picard/sam/MergeBamAlignment.java | 6 +-
src/java/picard/sam/RevertSam.java | 2 +-
src/java/picard/sam/SamAlignmentMerger.java | 10 +-
src/java/picard/sam/SamToFastq.java | 4 +-
src/java/picard/sam/SplitSamByLibrary.java | 2 +-
.../markduplicates/EstimateLibraryComplexity.java | 4 +-
...ctOpticalDuplicateFinderCommandLineProgram.java | 6 +-
.../MemoryBasedReadEndsForMarkDuplicatesMap.java | 2 +-
src/java/picard/sam/util/PhysicalLocation.java | 2 +-
src/java/picard/util/AdapterMarker.java | 2 +-
src/java/picard/util/BaitDesigner.java | 2 +-
src/java/picard/util/BasicInputParser.java | 8 +-
src/java/picard/util/DbSnpBitSetUtil.java | 71 ++++++---
src/java/picard/util/IlluminaUtil.java | 10 +-
src/java/picard/util/IntervalListTools.java | 2 +-
src/java/picard/util/MathUtil.java | 2 +-
.../picard/vcf/CollectVariantCallingMetrics.java | 13 +-
src/java/picard/vcf/GenotypeConcordance.java | 4 +-
.../picard/vcf/filter/AlleleBalanceFilter.java | 2 +-
src/java/picard/vcf/filter/FilterVcf.java | 131 ++++++++++++-----
src/java/picard/vcf/processor/VcfFileSegment.java | 2 +-
.../vcf/processor/VcfFileSegmentGenerator.java | 4 +-
.../CollectAlignmentSummaryMetricsTest.java | 6 +-
.../java/picard/cmdline/CommandLineParserTest.java | 162 +++++++++++++++++++++
.../illumina/CheckIlluminaDirectoryTest.java | 2 +-
src/tests/java/picard/sam/FilterSamReadsTest.java | 77 ++++++++++
.../java/picard/util/BedToIntervalListTest.java | 2 +-
.../java/picard/util/IntervalListToBedTest.java | 2 +-
src/tests/java/picard/vcf/SortVcfsTest.java | 1 -
.../vcf/UpdateVcfSequenceDictionaryTest.java | 5 -
.../picard/vcf/{ => filter}/TestFilterVcf.java | 41 ++++++
.../vcf/processor/VcfFileSegmentGeneratorTest.java | 2 +-
.../picard/sam/FilterSamReads/filterOddStarts.js | 2 +
.../filterReadsWithout5primeSoftClip.js | 10 ++
.../sam/summary_alignment_stats_test_chimeras.sam | 22 +--
70 files changed, 821 insertions(+), 346 deletions(-)
diff --git a/build.sbt b/build.sbt
index a2a67bf..e66a6e7 100644
--- a/build.sbt
+++ b/build.sbt
@@ -4,7 +4,7 @@ import sbt.Package.ManifestAttributes
name := "picard"
-version := "2.1.0"
+version := "2.1.1"
organization := "com.github.broadinstitute"
@@ -15,7 +15,7 @@ javaSource in Test := baseDirectory.value / "src/tests"
unmanagedResourceDirectories in Test := Seq(baseDirectory.value / "src/scripts", baseDirectory.value / "testdata", baseDirectory.value / "src/tests/scripts")
libraryDependencies ++= Seq(
- "com.github.samtools" % "htsjdk" % "2.1.0",
+ "com.github.samtools" % "htsjdk" % "2.1.1",
("com.google.cloud.genomics" % "gatk-tools-java" % "1.1" % "picardopt").
exclude("org.mortbay.jetty", "servlet-api"),
"org.testng" % "testng" % "6.8.8" % Test
diff --git a/build.xml b/build.xml
index 9568f5c..b985cd9 100755
--- a/build.xml
+++ b/build.xml
@@ -53,7 +53,7 @@
<arg value="--pretty=format:%H_%at"/>
</exec>
<property name="repository.revision" value=""/>
- <property name="picard-version" value="2.1.0"/>
+ <property name="picard-version" value="2.1.1"/>
<property name="command-line-html-dir" value="${dist}/html"/>
<property name="testng.verbosity" value="2"/>
<property name="test.debug.port" value="5005"/>
@@ -93,8 +93,8 @@
<include name="**/*.jar"/>
</fileset>
<fileset dir="${lib}">
- <include name="**/*.jar"/>
- </fileset>
+ <include name="**/*.jar"/>
+ </fileset>
</path>
<path id="metrics.classpath">
<pathelement path="${classpath}"/>
@@ -199,20 +199,20 @@
<target name="test" depends="compile, set_excluded_test_groups" description="Run unit tests">
<taskdef resource="testngtasks" classpathref="classpath"/>
<jacoco:coverage destfile="jacoco.data" xmlns:jacoco="antlib:org.jacoco.ant">
- <testng suitename="picard-tests" classpathref="classpath" outputdir="${test.output}"
- failureproperty="tests.failed" excludedgroups="${excludedTestGroups}" workingDir="${basedir}"
- verbose="${testng.verbosity}">
- <classpath>
- <pathelement path="${classes}"/>
- <pathelement path="${classes.test}"/>
- <pathelement path="${scripts}"/>
- </classpath>
- <classfileset dir="${classes.test}">
- <include name="**/Test*.class"/>
- <include name="**/*Test.class"/>
- </classfileset>
- <jvmarg value="-Xmx2G"/>
- </testng>
+ <testng suitename="picard-tests" classpathref="classpath" outputdir="${test.output}"
+ failureproperty="tests.failed" excludedgroups="${excludedTestGroups}" workingDir="${basedir}"
+ verbose="${testng.verbosity}">
+ <classpath>
+ <pathelement path="${classes}"/>
+ <pathelement path="${classes.test}"/>
+ <pathelement path="${scripts}"/>
+ </classpath>
+ <classfileset dir="${classes.test}">
+ <include name="**/Test*.class"/>
+ <include name="**/*Test.class"/>
+ </classfileset>
+ <jvmarg value="-Xmx2G"/>
+ </testng>
</jacoco:coverage>
<junitreport todir="${dist}/test">
@@ -227,18 +227,18 @@
<target name="test-coverage-report" depends="test" description="Runs tests and creates an HTML code coverage report">
<jacoco:report xmlns:jacoco="antlib:org.jacoco.ant">
- <executiondata>
- <file file="jacoco.data"/>
- </executiondata>
- <structure name="Picard">
- <classfiles>
- <fileset dir="classes"/>
- </classfiles>
- <sourcefiles encoding="UTF-8">
- <fileset dir="src"/>
- </sourcefiles>
- </structure>
- <html destdir="report"/>
+ <executiondata>
+ <file file="jacoco.data"/>
+ </executiondata>
+ <structure name="Picard">
+ <classfiles>
+ <fileset dir="classes"/>
+ </classfiles>
+ <sourcefiles encoding="UTF-8">
+ <fileset dir="src"/>
+ </sourcefiles>
+ </structure>
+ <html destdir="report"/>
</jacoco:report>
</target>
@@ -269,40 +269,40 @@
<target name="process-external-jars" depends="clean-jar-opt, maybe-add-gatk-tools-java">
</target>
-
- <target name="clean-jar-opt">
- <delete dir="${jar_opt}"/>
- <mkdir dir="${jar_opt}"/>
+
+ <target name="clean-jar-opt">
+ <delete dir="${jar_opt}"/>
+ <mkdir dir="${jar_opt}"/>
</target>
-
- <target name="maybe-add-gatk-tools-java" if="addGATKToolsJava">
- <mkdir dir="${jar_opt}"/>
- <unzip dest="${jar_opt}">
- <fileset dir="${lib}/gatk-tools-java">
- <include name="*.jar"/>
- </fileset>
- </unzip>
+
+ <target name="maybe-add-gatk-tools-java" if="addGATKToolsJava">
+ <mkdir dir="${jar_opt}"/>
+ <unzip dest="${jar_opt}">
+ <fileset dir="${lib}/gatk-tools-java">
+ <include name="*.jar"/>
+ </fileset>
+ </unzip>
</target>
-
+
<target name="picard-jar" depends="compile, process-external-jars"
- description="Builds the main executable picard.jar">
- <mkdir dir="${dist}"/>
- <mkdir dir="${dist.tmp}"/>
- <unjar dest="${dist.tmp}">
- <fileset dir="${lib}">
- <exclude name="**/jacocoant.jar"/> <!-- must exclude this jar from packing into picard - this is only used for testing -->
- </fileset>
- <fileset dir="${htsjdk_lib_dir}">
- <include name="*.jar"/>
- </fileset>
- </unjar>
+ description="Builds the main executable picard.jar">
+ <mkdir dir="${dist}"/>
+ <mkdir dir="${dist.tmp}"/>
+ <unjar dest="${dist.tmp}">
+ <fileset dir="${lib}">
+ <exclude name="**/jacocoant.jar"/> <!-- must exclude this jar from packing into picard - this is only used for testing -->
+ </fileset>
+ <fileset dir="${htsjdk_lib_dir}">
+ <include name="*.jar"/>
+ </fileset>
+ </unjar>
<jar destfile="${dist}/picard.jar" compress="no">
<fileset dir="${classes}" includes="picard/**/*.*, META-INF/**/*"/>
<fileset dir="${src.scripts}" includes="**/*.R"/>
<fileset dir="${htsjdk-classes}" includes ="${htsjdk}/*/**/*.*"/>
<fileset dir="${dist.tmp}" includes="**/*"/>
- <fileset dir="${jar_opt}" includes="**/*"/>
+ <fileset dir="${jar_opt}" includes="**/*"/>
<manifest>
<attribute name="Implementation-Version" value="${picard-version}(${repository.revision})"/>
@@ -317,7 +317,7 @@
</target>
<target name="picard-lib-jar" depends="compile"
- description="Builds the library: picard-lib.jar">
+ description="Builds the library: picard-lib.jar">
<mkdir dir="${dist}"/>
<jar destfile="${dist}/picard-lib.jar" compress="no">
<fileset dir="${classes}" includes="picard/**/*.*"/>
@@ -409,33 +409,49 @@
</target>
<target name="add-ga4gh-support">
- <property name="addGATKToolsJava" value="1"/>
+ <property name="addGATKToolsJava" value="1"/>
</target>
- <target name="package-commands-ga4gh" depends="add-ga4gh-support, compile, picard-jar" />
-
+ <target name="package-commands-ga4gh" depends="add-ga4gh-support, compile, picard-jar" />
+
<target name="package-commands" depends="compile, picard-jar">
<delete dir="${command-line-html-dir}"/>
<!-- If you don't want to generate on-line doc for a command, use package-command instead of document-command -->
<document-command title="AddCommentsToBam" main-class="picard.sam.AddCommentsToBam"/>
<document-command title="AddOrReplaceReadGroups" main-class="picard.sam.AddOrReplaceReadGroups"/>
+ <document-command title="BaitDesigner" main-class="picard.util.BaitDesigner"/>
<document-command title="BamToBfq" main-class="picard.fastq.BamToBfq"/>
<document-command title="BamIndexStats" main-class="picard.sam.BamIndexStats"/>
<document-command title="BedToIntervalList" main-class="picard.util.BedToIntervalList"/>
<document-command title="BuildBamIndex" main-class="picard.sam.BuildBamIndex"/>
<document-command title="CalculateHsMetrics" main-class="picard.analysis.directed.CalculateHsMetrics"/>
+ <document-command title="CollectHsMetrics" main-class="picard.analysis.directed.CollectHsMetrics"/>
+ <document-command title="CalculateReadGroupChecksum" main-class="picard.sam.CalculateReadGroupChecksum"/>
<document-command title="CleanSam" main-class="picard.sam.CleanSam"/>
<document-command title="CollectAlignmentSummaryMetrics" main-class="picard.analysis.CollectAlignmentSummaryMetrics"/>
<document-command title="CollectBaseDistributionByCycle" main-class="picard.analysis.CollectBaseDistributionByCycle"/>
<document-command title="CollectGcBiasMetrics" main-class="picard.analysis.CollectGcBiasMetrics"/>
+ <document-command title="CollectHiSeqXPfFailMetrics" main-class="picard.illumina.quality.CollectHiSeqXPfFailMetrics"/>
<document-command title="CollectHsMetrics" main-class="picard.analysis.directed.CollectHsMetrics"/>
+ <document-command title="CollectIlluminaBasecallingMetrics" main-class="picard.illumina.CollectIlluminaBasecallingMetrics"/>
+ <document-command title="CollectIlluminaLaneMetrics" main-class="picard.illumina.CollectIlluminaLaneMetrics"/>
<document-command title="CollectInsertSizeMetrics" main-class="picard.analysis.CollectInsertSizeMetrics"/>
+ <document-command title="CollectJumpingLibraryMetrics" main-class="picard.analysis.CollectJumpingLibraryMetrics"/>
<document-command title="CollectMultipleMetrics" main-class="picard.analysis.CollectMultipleMetrics"/>
+ <document-command title="CollectOxoGMetrics" main-class="picard.analysis.CollectOxoGMetrics"/>
+ <document-command title="CollectQualityYieldMetrics" main-class="picard.analysis.CollectQualityYieldMetrics"/>
+ <document-command title="CollectRawWgsMetrics" main-class="picard.analysis.CollectRawWgsMetrics"/>
<document-command title="CollectTargetedPcrMetrics" main-class="picard.analysis.directed.CollectTargetedPcrMetrics"/>
<document-command title="CollectRnaSeqMetrics" main-class="picard.analysis.CollectRnaSeqMetrics"/>
+ <document-command title="CollectRrbsMetrics" main-class="picard.analysis.CollectRrbsMetrics"/>
+ <document-command title="CollectSequencingArtifactMetrics" main-class="picard.analysis.artifacts.CollectSequencingArtifactMetrics"/>
<document-command title="CollectVariantCallingMetrics" main-class="picard.vcf.CollectVariantCallingMetrics"/>
<document-command title="CollectWgsMetrics" main-class="picard.analysis.CollectWgsMetrics"/>
+ <document-command title="CollectWgsMetricsFromQuerySorted" main-class="picard.analysis.CollectWgsMetricsFromQuerySorted"/>
+ <document-command title="CollectWgsMetricsFromSampledSites" main-class="picard.analysis.CollectWgsMetricsFromSampledSites"/>
+ <document-command title="CompareMetrics" main-class="picard.analysis.CompareMetrics"/>
<document-command title="CompareSAMs" main-class="picard.sam.CompareSAMs"/>
+ <document-command title="ConvertSequencingArtifactToOxoG" main-class="picard.analysis.artifacts.ConvertSequencingArtifactToOxoG"/>
<document-command title="CreateSequenceDictionary" main-class="picard.sam.CreateSequenceDictionary"/>
<document-command title="DownsampleSam" main-class="picard.sam.DownsampleSam"/>
<document-command title="ExtractIlluminaBarcodes" main-class="picard.illumina.ExtractIlluminaBarcodes"/>
@@ -451,7 +467,9 @@
<document-command title="IlluminaBasecallsToFastq" main-class="picard.illumina.IlluminaBasecallsToFastq"/>
<document-command title="IlluminaBasecallsToSam" main-class="picard.illumina.IlluminaBasecallsToSam"/>
<document-command title="CheckIlluminaDirectory" main-class="picard.illumina.CheckIlluminaDirectory"/>
+ <document-command title="CheckTerminatorBlock" main-class="picard.sam.CheckTerminatorBlock"/>
<document-command title="IntervalListTools" main-class="picard.util.IntervalListTools"/>
+ <document-command title="LiftOverIntervalList" main-class="picard.util.LiftOverIntervalList"/>
<document-command title="LiftoverVcf" main-class="picard.vcf.LiftoverVcf"/>
<document-command title="MakeSitesOnlyVcf" main-class="picard.vcf.MakeSitesOnlyVcf"/>
<document-command title="MarkDuplicates" main-class="picard.sam.markduplicates.MarkDuplicates"/>
@@ -461,17 +479,20 @@
<document-command title="MergeSamFiles" main-class="picard.sam.MergeSamFiles"/>
<document-command title="MergeVcfs" main-class="picard.vcf.MergeVcfs"/>
<document-command title="NormalizeFasta" main-class="picard.reference.NormalizeFasta"/>
+ <document-command title="PositionBasedDownsampleSam" main-class="picard.sam.PositionBasedDownsampleSam"/>
<document-command title="ExtractSequences" main-class="picard.reference.ExtractSequences"/>
<document-command title="QualityScoreDistribution" main-class="picard.analysis.QualityScoreDistribution"/>
+ <document-command title="RenameSampleInVcf" main-class="picard.vcf.RenameSampleInVcf"/>
<document-command title="ReorderSam" main-class="picard.sam.ReorderSam"/>
<document-command title="ReplaceSamHeader" main-class="picard.sam.ReplaceSamHeader"/>
<document-command title="RevertSam" main-class="picard.sam.RevertSam"/>
- <document-command title="RevertOriginalBaseQualitiesAndAddMateCigar"
- main-class="picard.sam.RevertOriginalBaseQualitiesAndAddMateCigar"/>
+ <document-command title="RevertOriginalBaseQualitiesAndAddMateCigar" main-class="picard.sam.RevertOriginalBaseQualitiesAndAddMateCigar"/>
<document-command title="SamFormatConverter" main-class="picard.sam.SamFormatConverter"/>
<document-command title="SamToFastq" main-class="picard.sam.SamToFastq"/>
+ <document-command title="ScatterIntervalsByNs" main-class="picard.util.ScatterIntervalsByNs"/>
<document-command title="SortSam" main-class="picard.sam.SortSam"/>
<document-command title="SortVcf" main-class="picard.vcf.SortVcf"/>
+ <document-command title="SplitSamByLibrary" main-class="picard.sam.SplitSamByLibrary"/>
<document-command title="UpdateVcfSequenceDictionary" main-class="picard.vcf.UpdateVcfSequenceDictionary"/>
<document-command title="VcfFormatConverter" main-class="picard.vcf.VcfFormatConverter"/>
<document-command title="MarkIlluminaAdapters" main-class="picard.illumina.MarkIlluminaAdapters"/>
@@ -508,9 +529,10 @@
<java classname="picard.cmdline.CreateHtmlDocForStandardOptions"
output="${command-line-html-dir}/program_usage/standard-options.html"
failonerror="true">
- <classpath>
- <pathelement location="${dist}/picard.jar"/>
- </classpath>
+ <classpath>
+ <path refid="classpath"/>
+ <pathelement location="${classes}"/>
+ </classpath>
</java>
</sequential>
</target>
@@ -529,9 +551,10 @@
<java classname="picard.cmdline.CreateHtmlDocForProgram"
output="${command-line-html-dir}/program_usage/@{title}.html"
failonerror="true">
- <classpath>
- <pathelement location="${dist}/picard.jar"/>
- </classpath>
+ <classpath>
+ <path refid="classpath"/>
+ <pathelement location="${classes}"/>
+ </classpath>
<arg value="@{main-class}"/>
</java>
diff --git a/src/java/picard/Test.java b/src/java/picard/Test.java
index c0ac40e..ab82c64 100644
--- a/src/java/picard/Test.java
+++ b/src/java/picard/Test.java
@@ -9,7 +9,7 @@ import java.util.StringTokenizer;
*
*/
public class Test {
- private final String text = "C0A69ACXX111213:6:1101:10000:144257\t83\t5\t128984606\t60\t76M\t=\t128984542\t-140\tAGTGTTAGAACTTCCTCCCCAAAGCATATACTTCAGTGGCAAGCTGTCCTGGATGAAGGTATGACCAACCAGATCA\t at FFFEECC>EFHBJIGIFGIEIJJJIHED<IEHIGIIJIIIGJIGJIIIIIJGGCJIIGIHHHBHGHFFDFFFC@@\tXT:A:U\tNM:i:0\tSM:i:37\tAM:i:37\tX0:i:1\tX1:i:0\tXM:i:0\tXO:i:0\tXG:i:0\tMD:Z:76";
+ private static final String TEXT = "C0A69ACXX111213:6:1101:10000:144257\t83\t5\t128984606\t60\t76M\t=\t128984542\t-140\tAGTGTTAGAACTTCCTCCCCAAAGCATATACTTCAGTGGCAAGCTGTCCTGGATGAAGGTATGACCAACCAGATCA\t at FFFEECC>EFHBJIGIFGIEIJJJIHED<IEHIGIIJIIIGJIGJIIIIIJGGCJIIGIHHHBHGHFFDFFFC@@\tXT:A:U\tNM:i:0\tSM:i:37\tAM:i:37\tX0:i:1\tX1:i:0\tXM:i:0\tXO:i:0\tXG:i:0\tMD:Z:76";
public static void main(String[] args) {
new Test().run();
@@ -22,7 +22,7 @@ public class Test {
watch.start();
for (int i=0; i<ITERATIONS; ++i) {
- if (StringUtil.split(text, fields, '\t') > 100) {
+ if (StringUtil.split(TEXT, fields, '\t') > 100) {
System.out.println("Mama Mia that's a lot of tokens!!");
}
}
@@ -32,7 +32,7 @@ public class Test {
watch.start();
for (int i=0; i<ITERATIONS; ++i) {
- if (split(text, fields, "\t") > 100) {
+ if (split(TEXT, fields, "\t") > 100) {
System.out.println("Mama Mia that's a lot of tokens!!");
}
}
diff --git a/src/java/picard/analysis/CollectGcBiasMetrics.java b/src/java/picard/analysis/CollectGcBiasMetrics.java
index a122731..46008bb 100644
--- a/src/java/picard/analysis/CollectGcBiasMetrics.java
+++ b/src/java/picard/analysis/CollectGcBiasMetrics.java
@@ -63,7 +63,7 @@ public class CollectGcBiasMetrics extends SinglePassSamProgram {
" nucleotides in a sample. Regions of high and low G + C content have been shown to interfere with mapping/aligning," +
" ultimately leading to fragmented genome assemblies and poor coverage in a phenomenon known as \"GC bias\". " +
"Detailed information on the effects of GC bias on the collection and analysis of sequencing data can be found at " +
- "DOI: 10.1371/journal.pone.0062856/.<br /><br />." +
+ "DOI: 10.1371/journal.pone.0062856/.<br /><br />" +
"" +
"The GC bias statistics are always output in a detailed long-form version, but a summary can also be produced. Both the " +
"detailed metrics and the summary metrics are output as tables (\".txt\" files) and an accompanying chart that plots the " +
@@ -85,7 +85,7 @@ public class CollectGcBiasMetrics extends SinglePassSamProgram {
"AT_DROPOUT, and GC_DROPOUT. While WINDOW_SIZE refers to the numbers of bases used for the distribution (see above), the " +
"ALIGNED_READS and TOTAL_CLUSTERS are the total number of aligned reads and the total number of reads (after filtering) " +
"produced in a run. In addition, the tool produces both AT_DROPOUT and GC_DROPOUT metrics, which indicate the percentage of " +
- "misaligned reads that correlate with low (%-GC is < 50%) or high (%-GC is > 50%) GC content respectively. <br /><br />" +
+ "misaligned reads that correlate with low (%-GC is < 50%) or high (%-GC is > 50%) GC content respectively. <br /><br />" +
"" +
"The percentage of \"coverage\" or depth in a GC bin is calculated by dividing the number of reads of a particular GC content " +
"by the mean number of reads of all GC bins. A number of 1 represents mean coverage, a number less than 1 represents lower " +
diff --git a/src/java/picard/analysis/CollectMultipleMetrics.java b/src/java/picard/analysis/CollectMultipleMetrics.java
index c0694f4..ab7fd11 100644
--- a/src/java/picard/analysis/CollectMultipleMetrics.java
+++ b/src/java/picard/analysis/CollectMultipleMetrics.java
@@ -86,7 +86,7 @@ public class CollectMultipleMetrics extends CommandLineProgram {
"</pre>" +
"<hr />";
public static interface ProgramInterface {
- SinglePassSamProgram makeInstance(final String outbase, final File input, final File reference,
+ SinglePassSamProgram makeInstance(final String outbase, final String outext, final File input, final File reference,
final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals);
public boolean needsReferenceSequence();
public boolean supportsMetricAccumulationLevel();
@@ -103,9 +103,9 @@ public class CollectMultipleMetrics extends CommandLineProgram {
return true;
}
@Override
- public SinglePassSamProgram makeInstance(final String outbase, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
+ public SinglePassSamProgram makeInstance(final String outbase, final String outext, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
final CollectAlignmentSummaryMetrics program = new CollectAlignmentSummaryMetrics();
- program.OUTPUT = new File(outbase + ".alignment_summary_metrics");
+ program.OUTPUT = new File(outbase + ".alignment_summary_metrics" + outext);
// Generally programs should not be accessing these directly but it might make things smoother
// to just set them anyway. These are set here to make sure that in case of a the derived class
@@ -127,9 +127,9 @@ public class CollectMultipleMetrics extends CommandLineProgram {
return true;
}
@Override
- public SinglePassSamProgram makeInstance(final String outbase, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
+ public SinglePassSamProgram makeInstance(final String outbase, final String outext, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
final CollectInsertSizeMetrics program = new CollectInsertSizeMetrics();
- program.OUTPUT = new File(outbase + ".insert_size_metrics");
+ program.OUTPUT = new File(outbase + ".insert_size_metrics" + outext);
program.Histogram_FILE = new File(outbase + ".insert_size_histogram.pdf");
// Generally programs should not be accessing these directly but it might make things smoother
// to just set them anyway. These are set here to make sure that in case of a the derived class
@@ -151,9 +151,9 @@ public class CollectMultipleMetrics extends CommandLineProgram {
return false;
}
@Override
- public SinglePassSamProgram makeInstance(final String outbase, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
+ public SinglePassSamProgram makeInstance(final String outbase, final String outext, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
final QualityScoreDistribution program = new QualityScoreDistribution();
- program.OUTPUT = new File(outbase + ".quality_distribution_metrics");
+ program.OUTPUT = new File(outbase + ".quality_distribution_metrics" + outext);
program.CHART_OUTPUT = new File(outbase + ".quality_distribution.pdf");
// Generally programs should not be accessing these directly but it might make things smoother
// to just set them anyway. These are set here to make sure that in case of a the derived class
@@ -174,9 +174,9 @@ public class CollectMultipleMetrics extends CommandLineProgram {
return false;
}
@Override
- public SinglePassSamProgram makeInstance(final String outbase, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
+ public SinglePassSamProgram makeInstance(final String outbase, final String outext, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
final MeanQualityByCycle program = new MeanQualityByCycle();
- program.OUTPUT = new File(outbase + ".quality_by_cycle_metrics");
+ program.OUTPUT = new File(outbase + ".quality_by_cycle_metrics" + outext);
program.CHART_OUTPUT = new File(outbase + ".quality_by_cycle.pdf");
// Generally programs should not be accessing these directly but it might make things smoother
// to just set them anyway. These are set here to make sure that in case of a the derived class
@@ -197,9 +197,9 @@ public class CollectMultipleMetrics extends CommandLineProgram {
return false;
}
@Override
- public SinglePassSamProgram makeInstance(final String outbase, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
+ public SinglePassSamProgram makeInstance(final String outbase, final String outext, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
final CollectBaseDistributionByCycle program = new CollectBaseDistributionByCycle();
- program.OUTPUT = new File(outbase + ".base_distribution_by_cycle_metrics");
+ program.OUTPUT = new File(outbase + ".base_distribution_by_cycle_metrics" + outext);
program.CHART_OUTPUT = new File(outbase + ".base_distribution_by_cycle.pdf");
// Generally programs should not be accessing these directly but it might make things smoother
// to just set them anyway. These are set here to make sure that in case of a the derived class
@@ -220,10 +220,10 @@ public class CollectMultipleMetrics extends CommandLineProgram {
return true;
}
@Override
- public SinglePassSamProgram makeInstance(final String outbase, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
+ public SinglePassSamProgram makeInstance(final String outbase, final String outext, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
final CollectGcBiasMetrics program = new CollectGcBiasMetrics();
- program.OUTPUT = new File(outbase + ".gc_bias.detail_metrics");
- program.SUMMARY_OUTPUT = new File(outbase + ".gc_bias.summary_metrics");
+ program.OUTPUT = new File(outbase + ".gc_bias.detail_metrics" + outext);
+ program.SUMMARY_OUTPUT = new File(outbase + ".gc_bias.summary_metrics" + outext);
program.CHART_OUTPUT = new File(outbase + ".gc_bias.pdf");
program.INPUT = input;
@@ -250,9 +250,9 @@ public class CollectMultipleMetrics extends CommandLineProgram {
return true;
}
@Override
- public SinglePassSamProgram makeInstance(final String outbase, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
+ public SinglePassSamProgram makeInstance(final String outbase, final String outext, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
final CollectRnaSeqMetrics program = new CollectRnaSeqMetrics();
- program.OUTPUT = new File(outbase + ".rna_metrics");
+ program.OUTPUT = new File(outbase + ".rna_metrics" + outext);
program.CHART_OUTPUT = new File(outbase + ".rna_coverage.pdf");
// Generally programs should not be accessing these directly but it might make things smoother
// to just set them anyway. These are set here to make sure that in case of a the derived class
@@ -272,9 +272,10 @@ public class CollectMultipleMetrics extends CommandLineProgram {
@Override
public boolean supportsMetricAccumulationLevel() { return false; }
@Override
- public SinglePassSamProgram makeInstance(final String outbase, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
+ public SinglePassSamProgram makeInstance(final String outbase, final String outext, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
final CollectSequencingArtifactMetrics program = new CollectSequencingArtifactMetrics();
program.OUTPUT = new File(outbase);
+ program.FILE_EXTENSION = outext;
program.DB_SNP = dbSnp;
program.INTERVALS = intervals;
// Generally programs should not be accessing these directly but it might make things smoother
@@ -295,9 +296,9 @@ public class CollectMultipleMetrics extends CommandLineProgram {
return false;
}
@Override
- public SinglePassSamProgram makeInstance(final String outbase, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
+ public SinglePassSamProgram makeInstance(final String outbase, final String outext, final File input, final File reference, final Set<MetricAccumulationLevel> metricAccumulationLevel, final File dbSnp, final File intervals) {
final CollectQualityYieldMetrics program = new CollectQualityYieldMetrics();
- program.OUTPUT = new File(outbase + ".quality_yield_metrics");
+ program.OUTPUT = new File(outbase + ".quality_yield_metrics" + outext);
// Generally programs should not be accessing these directly but it might make things smoother
// to just set them anyway. These are set here to make sure that in case of a the derived class
// overrides
@@ -387,10 +388,9 @@ public class CollectMultipleMetrics extends CommandLineProgram {
log.warn("The " + program.toString() + " program does not support a metric accumulation level, but METRIC_ACCUMULATION_LEVEL" +
" was overridden in the command line. " + program.toString() + " will be run against the entire input.");
}
- final SinglePassSamProgram instance = program.makeInstance(OUTPUT, INPUT, REFERENCE_SEQUENCE, METRIC_ACCUMULATION_LEVEL, DB_SNP, INTERVALS);
- // Add a file extension if desired
- if (null != FILE_EXTENSION && !FILE_EXTENSION.isEmpty()) instance.OUTPUT = new File(instance.OUTPUT.getAbsolutePath() + FILE_EXTENSION);
+ final String outext = (null != FILE_EXTENSION) ? FILE_EXTENSION : ""; // Add a file extension if desired
+ final SinglePassSamProgram instance = program.makeInstance(OUTPUT, outext, INPUT, REFERENCE_SEQUENCE, METRIC_ACCUMULATION_LEVEL, DB_SNP, INTERVALS);
// Generally programs should not be accessing these directly but it might make things smoother
// to just set them anyway
diff --git a/src/java/picard/analysis/CollectRrbsMetrics.java b/src/java/picard/analysis/CollectRrbsMetrics.java
index f99bc0c..db175c5 100644
--- a/src/java/picard/analysis/CollectRrbsMetrics.java
+++ b/src/java/picard/analysis/CollectRrbsMetrics.java
@@ -186,7 +186,7 @@ private static final String R_SCRIPT = "picard/analysis/rrbsQc.R";
}
private boolean isSequenceFiltered(final String sequenceName) {
- return (SEQUENCE_NAMES != null) && (SEQUENCE_NAMES.size() > 0) && (!SEQUENCE_NAMES.contains(sequenceName));
+ return (SEQUENCE_NAMES != null) && (!SEQUENCE_NAMES.isEmpty()) && (!SEQUENCE_NAMES.contains(sequenceName));
}
private void assertIoFiles(final File summaryFile, final File detailsFile, final File plotsFile) {
@@ -216,6 +216,6 @@ private static final String R_SCRIPT = "picard/analysis/rrbsQc.R";
errorMsgs.add("MINIMUM_READ_LENGTH must be > 0");
}
- return errorMsgs.size() == 0 ? null : errorMsgs.toArray(new String[errorMsgs.size()]);
+ return errorMsgs.isEmpty() ? null : errorMsgs.toArray(new String[errorMsgs.size()]);
}
}
diff --git a/src/java/picard/analysis/GcBiasMetricsCollector.java b/src/java/picard/analysis/GcBiasMetricsCollector.java
index 79659b2..e372da6 100644
--- a/src/java/picard/analysis/GcBiasMetricsCollector.java
+++ b/src/java/picard/analysis/GcBiasMetricsCollector.java
@@ -89,9 +89,9 @@ public class GcBiasMetricsCollector extends MultiLevelCollector<GcBiasMetrics, I
/////////////////////////////////////////////////////////////////////////////
public class PerUnitGcBiasMetricsCollector implements PerUnitMetricCollector<GcBiasMetrics, Integer, GcBiasCollectorArgs> {
Map<String, GcObject> gcData = new HashMap<String, GcObject>();
- private String sample = null;
- private String library = null;
- private String readGroup = null;
+ private final String sample;
+ private final String library;
+ private final String readGroup;
private static final String allReads = "All_Reads";
/////////////////////////////////////////////////////////////////////////////
diff --git a/src/java/picard/analysis/MeanQualityByCycle.java b/src/java/picard/analysis/MeanQualityByCycle.java
index 13c67c2..15872b9 100644
--- a/src/java/picard/analysis/MeanQualityByCycle.java
+++ b/src/java/picard/analysis/MeanQualityByCycle.java
@@ -97,7 +97,7 @@ public class MeanQualityByCycle extends SinglePassSamProgram {
System.exit(new MeanQualityByCycle().instanceMain(args));
}
- private static class HistogramGenerator {
+ private static final class HistogramGenerator {
final boolean useOriginalQualities;
int maxLengthSoFar = 0;
double[] firstReadTotalsByCycle = new double[maxLengthSoFar];
diff --git a/src/java/picard/analysis/artifacts/CollectSequencingArtifactMetrics.java b/src/java/picard/analysis/artifacts/CollectSequencingArtifactMetrics.java
index 59451e5..58dd32b 100644
--- a/src/java/picard/analysis/artifacts/CollectSequencingArtifactMetrics.java
+++ b/src/java/picard/analysis/artifacts/CollectSequencingArtifactMetrics.java
@@ -120,6 +120,9 @@ public class CollectSequencingArtifactMetrics extends SinglePassSamProgram {
"However, the summary metrics output will still take all contexts into consideration.")
public Set<String> CONTEXTS_TO_PRINT = new HashSet<String>();
+ @Option(shortName = "EXT", doc="Append the given file extension to all metric file names (ex. OUTPUT.pre_adapter_summary_metrics.EXT). None if null", optional=true)
+ public String FILE_EXTENSION = null;
+
private static final String UNKNOWN_LIBRARY = "UnknownLibrary";
private static final String UNKNOWN_SAMPLE = "UnknownSample";
@@ -166,10 +169,11 @@ public class CollectSequencingArtifactMetrics extends SinglePassSamProgram {
@Override
protected void setup(final SAMFileHeader header, final File samFile) {
- preAdapterSummaryOut = new File(OUTPUT + SequencingArtifactMetrics.PRE_ADAPTER_SUMMARY_EXT);
- preAdapterDetailsOut = new File(OUTPUT + SequencingArtifactMetrics.PRE_ADAPTER_DETAILS_EXT);
- baitBiasSummaryOut = new File(OUTPUT + SequencingArtifactMetrics.BAIT_BIAS_SUMMARY_EXT);
- baitBiasDetailsOut = new File(OUTPUT + SequencingArtifactMetrics.BAIT_BIAS_DETAILS_EXT);
+ final String outext = (null != FILE_EXTENSION) ? FILE_EXTENSION : ""; // Add a file extension if desired
+ preAdapterSummaryOut = new File(OUTPUT + SequencingArtifactMetrics.PRE_ADAPTER_SUMMARY_EXT + outext);
+ preAdapterDetailsOut = new File(OUTPUT + SequencingArtifactMetrics.PRE_ADAPTER_DETAILS_EXT + outext);
+ baitBiasSummaryOut = new File(OUTPUT + SequencingArtifactMetrics.BAIT_BIAS_SUMMARY_EXT + outext);
+ baitBiasDetailsOut = new File(OUTPUT + SequencingArtifactMetrics.BAIT_BIAS_DETAILS_EXT + outext);
IOUtil.assertFileIsWritable(preAdapterSummaryOut);
IOUtil.assertFileIsWritable(preAdapterDetailsOut);
@@ -302,12 +306,12 @@ public class CollectSequencingArtifactMetrics extends SinglePassSamProgram {
baitBiasSummaryMetricsFile.addAllMetrics(counter.getBaitBiasSummaryMetrics());
for (final PreAdapterDetailMetrics preAdapterDetailMetrics : counter.getPreAdapterDetailMetrics()) {
- if (CONTEXTS_TO_PRINT.size() == 0 || CONTEXTS_TO_PRINT.contains(preAdapterDetailMetrics.CONTEXT)) {
+ if (CONTEXTS_TO_PRINT.isEmpty() || CONTEXTS_TO_PRINT.contains(preAdapterDetailMetrics.CONTEXT)) {
preAdapterDetailMetricsFile.addMetric(preAdapterDetailMetrics);
}
}
for (final BaitBiasDetailMetrics baitBiasDetailMetrics : counter.getBaitBiasDetailMetrics()) {
- if (CONTEXTS_TO_PRINT.size() == 0 || CONTEXTS_TO_PRINT.contains(baitBiasDetailMetrics.CONTEXT)) {
+ if (CONTEXTS_TO_PRINT.isEmpty() || CONTEXTS_TO_PRINT.contains(baitBiasDetailMetrics.CONTEXT)) {
baitBiasDetailMetricsFile.addMetric(baitBiasDetailMetrics);
}
}
diff --git a/src/java/picard/analysis/directed/TargetMetricsCollector.java b/src/java/picard/analysis/directed/TargetMetricsCollector.java
index 9e7d5c6..e318784 100644
--- a/src/java/picard/analysis/directed/TargetMetricsCollector.java
+++ b/src/java/picard/analysis/directed/TargetMetricsCollector.java
@@ -604,8 +604,8 @@ public abstract class TargetMetricsCollector<METRIC_TYPE extends MultilevelMetri
double totalCoverage = 0;
// The "how many bases at at-least X" calculations.
- final int targetBasesDepth[] = {0, 1, 2, 10, 20, 30, 40, 50, 100}; // NB: this should be in ascending order
- final int targetBases[] = new int[targetBasesDepth.length]; // counts for how many target bases are at at least X coverage, where X corresponds to the value at the same offset in targetBasesDepth
+ final int[] targetBasesDepth = {0, 1, 2, 10, 20, 30, 40, 50, 100}; // NB: this should be in ascending order
+ final int[] targetBases = new int[targetBasesDepth.length]; // counts for how many target bases are at at least X coverage, where X corresponds to the value at the same offset in targetBasesDepth
// consider all bases in calculating the mean, median etc.
for (final Coverage c : this.coverageByTarget.values()) {
diff --git a/src/java/picard/cmdline/CommandLineParser.java b/src/java/picard/cmdline/CommandLineParser.java
index 964cdb8..ee90b44 100644
--- a/src/java/picard/cmdline/CommandLineParser.java
+++ b/src/java/picard/cmdline/CommandLineParser.java
@@ -23,9 +23,11 @@
*/
package picard.cmdline;
+import com.google.common.base.CharMatcher;
import htsjdk.samtools.util.CloserUtil;
import htsjdk.samtools.util.CollectionUtil.MultiMap;
import htsjdk.samtools.util.StringUtil;
+import picard.PicardException;
import java.io.BufferedReader;
import java.io.File;
@@ -48,8 +50,8 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
-
-import picard.PicardException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Annotation-driven utility for parsing command-line arguments, checking for errors, and producing usage message.
@@ -177,19 +179,19 @@ public class CommandLineParser {
private int maxPositionalArguments;
// List of all the data members with @Option annotation
- private final List<OptionDefinition> optionDefinitions = new ArrayList<OptionDefinition>();
+ private final List<OptionDefinition> optionDefinitions = new ArrayList<>();
// Maps long name, and short name, if present, to an option definition that is
// also in the optionDefinitions list.
- private final Map<String, OptionDefinition> optionMap = new HashMap<String, OptionDefinition>();
+ private final Map<String, OptionDefinition> optionMap = new HashMap<>();
// Maps child options prefix to CommandLineParser for the child object.
// Key: option prefix.
- private final Map<String, CommandLineParser> childOptionsMap = new LinkedHashMap<String, CommandLineParser>();
+ private final Map<String, CommandLineParser> childOptionsMap = new LinkedHashMap<>();
// Holds the command-line arguments for a child option parser.
// Key: option prefix. Value: List of arguments for child corresponding to that prefix (with prefix stripped).
- private final MultiMap<String, ChildOptionArg> childOptionArguments = new MultiMap<String, ChildOptionArg>();
+ private final MultiMap<String, ChildOptionArg> childOptionArguments = new MultiMap<>();
// For printing error messages when parsing command line.
private PrintStream messageStream;
@@ -230,9 +232,12 @@ public class CommandLineParser {
} else {
usagePreamble += defaultUsagePreambleWithPositionalArguments;
}
+
if (null != this.programVersion && 0 < this.programVersion.length()) {
usagePreamble += "Version: " + getVersion() + "\n";
}
+ //checkForNonASCII(usagePreamble, "preamble");
+
return usagePreamble;
}
@@ -281,7 +286,7 @@ public class CommandLineParser {
}
private static List<Field> getAllFields(Class clazz) {
- final List<Field> ret = new ArrayList<Field>();
+ final List<Field> ret = new ArrayList<>();
do {
ret.addAll(Arrays.asList(clazz.getDeclaredFields()));
clazz = clazz.getSuperclass();
@@ -299,8 +304,11 @@ public class CommandLineParser {
* @param stream Where to write the usage message.
*/
public void usage(final PrintStream stream, final boolean printCommon) {
+
if (prefix.isEmpty()) {
- stream.print(getStandardUsagePreamble(callerOptions.getClass()) + getUsagePreamble());
+ final String preamble = htmlUnescape(convertFromHtml(getStandardUsagePreamble(callerOptions.getClass()) + getUsagePreamble()));
+ checkForNonASCII(preamble, "Tool description");
+ stream.print(preamble);
stream.println("\nVersion: " + getVersion());
stream.println("\n\nOptions:\n");
@@ -310,9 +318,7 @@ public class CommandLineParser {
}
if (!optionDefinitions.isEmpty()) {
- for (final OptionDefinition optionDefinition : optionDefinitions) {
- if (printCommon || !optionDefinition.isCommon) printOptionUsage(stream, optionDefinition);
- }
+ optionDefinitions.stream().filter(optionDefinition -> printCommon || !optionDefinition.isCommon).forEach(optionDefinition -> printOptionUsage(stream, optionDefinition));
}
if (printCommon) {
@@ -333,17 +339,43 @@ public class CommandLineParser {
}
// Generate usage for child parsers.
- final Collection<CommandLineParser> childClps;
- childClps = getChildParsersForHelp();
- for (final CommandLineParser childClp : childClps) {
- childClp.usage(stream, printCommon);
+ getChildParsersForHelp()
+ .stream()
+ .forEach(childClp -> childClp.usage(stream, printCommon));
+ }
+
+ static void checkForNonASCII(String documentationText, String location) {
+ if (!CharMatcher.ASCII.matchesAllOf(documentationText)) {
+ throw new AssertionError("Non-ASCII character used in documentation ("+location+"). Only ASCII characters are allowed.");
+ }
+ //make sure that html-encoded non-ascii characters are found as well
+ if ( Pattern.compile(".*&[a-zA-Z]*?;.*",Pattern.MULTILINE).matcher(documentationText).find()) {
+ throw new AssertionError("Non-ASCII character used in documentation ("+location+"). Only ASCII characters are allowed.");
}
}
+ // package local for testing
+ static String convertFromHtml(final String textToConvert) {
+
+ //LinkedHashmap since the order matters
+ final Map<String, String> regexps = new LinkedHashMap<>();
+
+ regexps.put("< *a *href=[\'\"](.*?)[\'\"] *>(.*?)</ *a *>","$2 ($1)");
+ regexps.put("< *a *href=[\'\"](.*?)[\'\"] *>(.*?)< *a */>","$2 ($1)");
+ regexps.put("</ *(br|p|table|h[1-4]|pre|hr|li|ul) *>","\n");
+ regexps.put("< *(br|p|table|h[1-4]|pre|hr|li|ul) */>","\n");
+ regexps.put("< *(p|table|h[1-4]|ul|pre) *>","\n");
+ regexps.put("<li>", " - ");
+ regexps.put("</th>", "\t");
+ regexps.put("<\\w*?>", "");
+
+ return regexps.entrySet().stream().sequential()
+ .reduce(textToConvert, (string, entrySet) -> string.replaceAll(entrySet.getKey(), entrySet.getValue()), (a, b) -> b);
+ }
private Collection<CommandLineParser> getChildParsersForHelp() {
final Collection<CommandLineParser> childClps;
if (isCommandLineProgram()) {
- childClps = new ArrayList<CommandLineParser>();
+ childClps = new ArrayList<>();
for (final Map.Entry<String, Object> entry :
((CommandLineProgram) callerOptions).getNestedOptionsForHelp().entrySet()) {
if (entry.getKey().contains(".")) {
@@ -360,8 +392,7 @@ public class CommandLineParser {
public void htmlUsage(final PrintStream stream, final String programName, final boolean printCommon) {
// TODO: Should HTML escape usage preamble and option usage, including line breaks
- stream.println("<a id=\"" + programName + "\"/>");
- stream.println("<h3>" + programName + "</h3>");
+ stream.println("<h3 id=\"" + programName + "\">" + programName + "</h3>");
stream.println("<section>");
stream.println("<p>" + getUsagePreamble() + "</p>");
boolean hasOptions = false;
@@ -383,7 +414,7 @@ public class CommandLineParser {
if (printCommon) {
for (final String[] optionDoc : FRAMEWORK_OPTION_DOC) {
stream.println("<tr><td>" + optionDoc[0] + "</td><td>" +
- htmlEscape(optionDoc[2]) + "</td></tr>");
+ optionDoc[2] + "</td></tr>");
}
}
htmlPrintOptionTableRows(stream, printCommon);
@@ -393,11 +424,14 @@ public class CommandLineParser {
/**
* Prints options as rows in an HTML table.
*
- * @param stream
- * @param printCommon
+ * @param stream stream into which to write the output
+ * @param printCommon whether or not to print the common information
*/
private void htmlPrintOptionTableRows(final PrintStream stream, final boolean printCommon) {
for (final OptionDefinition optionDefinition : optionDefinitions) {
+
+ checkForNonASCII(optionDefinition.doc, optionDefinition.name);
+
if (!optionDefinition.isCommon || printCommon) {
printHtmlOptionUsage(stream, optionDefinition);
}
@@ -405,14 +439,21 @@ public class CommandLineParser {
for (final CommandLineParser childParser : getChildParsersForHelp()) {
childParser.htmlPrintOptionTableRows(stream, false);
}
-
}
- private static String htmlEscape(String str) {
+ private static final Map<String, String> htmlToText = new LinkedHashMap<String, String>(){{
+ put("<","<");
+ put(">",">");
+ put("≥",">=");
+ put("≤","<=");
+
+ put("<p>","\n");
+ }};
+
+ static String htmlUnescape(String str) {
// May need more here
- str = str.replaceAll("<", "<");
- str = str.replaceAll("\n", "\n<p>");
- return str;
+ return htmlToText.entrySet().stream().sequential()
+ .reduce(str, (string, entrySet) -> string.replace(entrySet.getKey(), entrySet.getValue()), (a, b) -> b);
}
/**
@@ -444,9 +485,8 @@ public class CommandLineParser {
return false;
}
-
final String[] pair = arg.split("=", 2);
- if (pair.length == 2 && pair[1].length() == 0) {
+ if (pair.length == 2 && pair[1].isEmpty()) {
if (i < args.length - 1) {
pair[1] = args[++i];
@@ -495,7 +535,7 @@ public class CommandLineParser {
for (final String mutexOption : optionDefinition.mutuallyExclusive) {
final OptionDefinition mutextOptionDef = optionMap.get(mutexOption);
if (mutextOptionDef != null && mutextOptionDef.hasBeenSet) {
- mutextOptionNames.append(" ").append(prefixDot).append(mutextOptionDef.name);
+ mutextOptionNames.append(' ').append(prefixDot).append(mutextOptionDef.name);
}
}
if (optionDefinition.hasBeenSet && mutextOptionNames.length() > 0) {
@@ -522,8 +562,8 @@ public class CommandLineParser {
}
return false;
}
-
}
+
if (positionalArguments != null) {
final Collection c = (Collection) positionalArguments.get(callerOptions);
if (c.size() < minPositionalArguments) {
@@ -532,13 +572,13 @@ public class CommandLineParser {
return false;
}
for (final Object posArg : c) {
- commandLineString.append(" ").append(posArg.toString());
+ commandLineString.append(' ').append(posArg.toString());
}
}
//first, append args that were explicitly set
for (final OptionDefinition optionDefinition : optionDefinitions) {
if (optionDefinition.hasBeenSet) {
- commandLineString.append(" ").append(prefixDot).append(optionDefinition.name).append("=").append(
+ commandLineString.append(' ').append(prefixDot).append(optionDefinition.name).append('=').append(
optionDefinition.field.get(callerOptions));
}
}
@@ -546,7 +586,7 @@ public class CommandLineParser {
//next, append args that weren't explicitly set, but have a default value
for (final OptionDefinition optionDefinition : optionDefinitions) {
if (!optionDefinition.hasBeenSet && !optionDefinition.defaultValue.equals("null")) {
- commandLineString.append(" ").append(prefixDot).append(optionDefinition.name).append("=").append(
+ commandLineString.append(' ').append(prefixDot).append(optionDefinition.name).append('=').append(
optionDefinition.defaultValue);
}
}
@@ -556,8 +596,6 @@ public class CommandLineParser {
// Should never happen because lack of publicness has already been checked.
throw new RuntimeException(e);
}
-
-
}
private boolean parsePositionalArgument(final String stringValue) {
@@ -725,7 +763,7 @@ public class CommandLineParser {
reader = new BufferedReader(new FileReader(optionsFile));
String line;
while ((line = reader.readLine()) != null) {
- if (line.startsWith("#") || line.trim().length() == 0) {
+ if (line.startsWith("#") || line.trim().isEmpty()) {
continue;
}
final String[] pair = line.split("=", 2);
@@ -754,8 +792,7 @@ public class CommandLineParser {
private void printHtmlOptionUsage(final PrintStream stream, final OptionDefinition optionDefinition) {
final String type = getUnderlyingType(optionDefinition.field).getSimpleName();
final String optionLabel = prefixDot + optionDefinition.name + " (" + type + ")";
- stream.println("<tr><td>" + optionLabel + "</td><td>" +
- htmlEscape(makeOptionDescription(optionDefinition)) + "</td></tr>");
+ stream.println("<tr><td>" + optionLabel + "</td><td>" + makeOptionDescription(optionDefinition) + "</td></tr>");
}
private void printOptionUsage(final PrintStream stream, final OptionDefinition optionDefinition) {
@@ -771,7 +808,7 @@ public class CommandLineParser {
if (type != null) optionLabel += "=" + type;
stream.print(optionLabel);
- if (shortName != null && shortName.length() > 0) {
+ if (shortName != null && !shortName.isEmpty()) {
stream.println();
optionLabel = prefixDot + shortName;
if (type != null) optionLabel += "=" + type;
@@ -784,7 +821,9 @@ public class CommandLineParser {
numSpaces = OPTION_COLUMN_WIDTH;
}
printSpaces(stream, numSpaces);
- final String wrappedDescription = StringUtil.wordWrap(optionDescription, DESCRIPTION_COLUMN_WIDTH);
+ checkForNonASCII(optionDescription, name);
+
+ final String wrappedDescription = StringUtil.wordWrap(convertFromHtml(optionDescription), DESCRIPTION_COLUMN_WIDTH);
final String[] descriptionLines = wrappedDescription.split("\n");
for (int i = 0; i < descriptionLines.length; ++i) {
if (i > 0) {
@@ -797,7 +836,7 @@ public class CommandLineParser {
private String makeOptionDescription(final OptionDefinition optionDefinition) {
final StringBuilder sb = new StringBuilder();
- if (optionDefinition.doc.length() > 0) {
+ if (!optionDefinition.doc.isEmpty()) {
sb.append(optionDefinition.doc);
sb.append(" ");
}
@@ -820,7 +859,7 @@ public class CommandLineParser {
final Boolean isClpEnum = enumConstants.length > 0 && (enumConstants[0] instanceof ClpEnum);
sb.append("Possible values: {");
- if (isClpEnum) sb.append("\n");
+ if (isClpEnum) sb.append('\n');
for (int i = 0; i < enumConstants.length; ++i) {
if (i > 0 && !isClpEnum) {
@@ -864,9 +903,9 @@ public class CommandLineParser {
" doesn't match any known option.");
}
- sb.append(" ").append(mutextOptionDefinition.name);
- if (mutextOptionDefinition.shortName.length() > 0) {
- sb.append(" (").append(mutextOptionDefinition.shortName).append(")");
+ sb.append(' ').append(mutextOptionDefinition.name);
+ if (!mutextOptionDefinition.shortName.isEmpty()) {
+ sb.append(" (").append(mutextOptionDefinition.shortName).append(')');
}
}
}
@@ -876,7 +915,7 @@ public class CommandLineParser {
private void printSpaces(final PrintStream stream, final int numSpaces) {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < numSpaces; ++i) {
- sb.append(" ");
+ sb.append(' ');
}
stream.print(sb);
}
@@ -940,7 +979,7 @@ public class CommandLineParser {
if (!optionDefinition.overridable && optionMap.containsKey(optionDefinition.name)) {
throw new CommandLineParserDefinitionException(optionDefinition.name + " has already been used.");
}
- if (optionDefinition.shortName.length() > 0) {
+ if (!optionDefinition.shortName.isEmpty()) {
if (optionMap.containsKey(optionDefinition.shortName)) {
if (!optionDefinition.overridable) {
throw new CommandLineParserDefinitionException(optionDefinition.shortName +
@@ -1111,17 +1150,15 @@ public class CommandLineParser {
String getHelpDoc();
}
-
protected static class OptionDefinitionByPrintOrderComparator implements Comparator<OptionDefinition> {
- @Override
- public int compare(OptionDefinition o1, OptionDefinition o2) {
- return o1.printOrder - o2.printOrder;
- }
-
+ @Override
+ public int compare(OptionDefinition o1, OptionDefinition o2) {
+ return o1.printOrder - o2.printOrder;
+ }
}
- protected static class OptionDefinition {
+ protected static final class OptionDefinition {
final Field field;
final String name;
final String shortName;
@@ -1172,7 +1209,7 @@ public class CommandLineParser {
/**
* Holds a command-line argument that is destined for a child parser. Prefix has been stripped from name.
*/
- private static class ChildOptionArg {
+ private static final class ChildOptionArg {
final String name;
final String value;
final boolean fromFile;
diff --git a/src/java/picard/fingerprint/CrosscheckReadGroupFingerprints.java b/src/java/picard/fingerprint/CrosscheckReadGroupFingerprints.java
index e724224..a54ffa1 100644
--- a/src/java/picard/fingerprint/CrosscheckReadGroupFingerprints.java
+++ b/src/java/picard/fingerprint/CrosscheckReadGroupFingerprints.java
@@ -291,7 +291,7 @@ public class CrosscheckReadGroupFingerprints extends CommandLineProgram {
private String getReadGroupDetails(final SAMReadGroupRecord readGroupRecord) {
final List<String> elements = new ArrayList<>(5);
- final String tmp[] = readGroupRecord.getPlatformUnit().split("\\."); // Expect to look like: D047KACXX110901.1.ACCAACTG
+ final String[] tmp = readGroupRecord.getPlatformUnit().split("\\."); // Expect to look like: D047KACXX110901.1.ACCAACTG
String runBarcode = "?";
String lane = "?";
String molBarcode = "?";
diff --git a/src/java/picard/fingerprint/HaplotypeMap.java b/src/java/picard/fingerprint/HaplotypeMap.java
index 19cdf8b..fe3fd57 100644
--- a/src/java/picard/fingerprint/HaplotypeMap.java
+++ b/src/java/picard/fingerprint/HaplotypeMap.java
@@ -85,7 +85,7 @@ public class HaplotypeMap {
final Map<String, HaplotypeBlock> anchorToHaplotype = new HashMap<String, HaplotypeBlock>();
do {
- if (line.trim().length() == 0) continue; // skip over blank lines
+ if (line.trim().isEmpty()) continue; // skip over blank lines
if (line.startsWith("#")) continue; // ignore comments/headers
// Make sure we have the right number of fields
@@ -323,7 +323,7 @@ public class HaplotypeMap {
final StringBuilder sb = new StringBuilder();
for (final String panel : panels) {
- if (sb.length() > 0) sb.append(",");
+ if (sb.length() > 0) sb.append(',');
sb.append(panel);
}
diff --git a/src/java/picard/fingerprint/HaplotypeProbabilitiesFromGenotypeLikelihoods.java b/src/java/picard/fingerprint/HaplotypeProbabilitiesFromGenotypeLikelihoods.java
index acea750..1d9b4e4 100644
--- a/src/java/picard/fingerprint/HaplotypeProbabilitiesFromGenotypeLikelihoods.java
+++ b/src/java/picard/fingerprint/HaplotypeProbabilitiesFromGenotypeLikelihoods.java
@@ -50,7 +50,7 @@ public class HaplotypeProbabilitiesFromGenotypeLikelihoods extends HaplotypeProb
* @param logGenotypeLikelihoods correspond to the logLikelihoods of [AA, AB, BB]. Log is assumed to be in base 10.
*/
- public void addToLogLikelihoods(final Snp snp, final List<Allele> alleles, final double logGenotypeLikelihoods[]) {
+ public void addToLogLikelihoods(final Snp snp, final List<Allele> alleles, final double[] logGenotypeLikelihoods) {
assertSnpPartOfHaplotype(snp);
// only allow biallelic snps
diff --git a/src/java/picard/illumina/ClusterDataToSamConverter.java b/src/java/picard/illumina/ClusterDataToSamConverter.java
index 08f3f7a..5e1ab07 100644
--- a/src/java/picard/illumina/ClusterDataToSamConverter.java
+++ b/src/java/picard/illumina/ClusterDataToSamConverter.java
@@ -156,7 +156,7 @@ public class ClusterDataToSamConverter implements
// Get and transform the unmatched barcode, if any, to store with the reads
String unmatchedBarcode = null;
if (hasSampleBarcode && cluster.getMatchedBarcode() == null) {
- final byte barcode[][] = new byte[sampleBarcodeIndices.length][];
+ final byte[][] barcode = new byte[sampleBarcodeIndices.length][];
for (int i = 0; i < sampleBarcodeIndices.length; i++) {
barcode[i] = cluster.getRead(sampleBarcodeIndices[i]).getBases();
}
@@ -167,8 +167,8 @@ public class ClusterDataToSamConverter implements
final String joinedMolecularIndexQ ;
if (hasMolecularBarcode) {
final StringBuilder joinedMolecularIndexQBuilder = new StringBuilder();
- final byte molecularIndex[][] = new byte[molecularBarcodeIndices.length][];
- final byte molecularIndexQ[][] = new byte[molecularBarcodeIndices.length][];
+ final byte[][] molecularIndex = new byte[molecularBarcodeIndices.length][];
+ final byte[][] molecularIndexQ = new byte[molecularBarcodeIndices.length][];
for (int i = 0; i < molecularBarcodeIndices.length; i++) {
molecularIndex[i] = cluster.getRead(molecularBarcodeIndices[i]).getBases();
molecularIndexQ[i] = cluster.getRead(molecularBarcodeIndices[i]).getQualities();
diff --git a/src/java/picard/illumina/ExtractIlluminaBarcodes.java b/src/java/picard/illumina/ExtractIlluminaBarcodes.java
index 4027378..94074c3 100644
--- a/src/java/picard/illumina/ExtractIlluminaBarcodes.java
+++ b/src/java/picard/illumina/ExtractIlluminaBarcodes.java
@@ -353,10 +353,10 @@ public class ExtractIlluminaBarcodes extends CommandLineProgram {
barcodeToMetrics.put(barcode, metric);
}
}
- if (barcodeToMetrics.keySet().size() == 0) {
+ if (barcodeToMetrics.keySet().isEmpty()) {
messages.add("No barcodes have been specified.");
}
- if (messages.size() == 0) {
+ if (messages.isEmpty()) {
return null;
}
return messages.toArray(new String[messages.size()]);
@@ -386,7 +386,7 @@ public class ExtractIlluminaBarcodes extends CommandLineProgram {
final int numBarcodes = readStructure.sampleBarcodes.length();
final Set<String> barcodes = new HashSet<String>();
for (final TabbedTextFileWithHeaderParser.Row row : barcodesParser) {
- final String bcStrings[] = new String[numBarcodes];
+ final String[] bcStrings = new String[numBarcodes];
int barcodeNum = 1;
for (final ReadDescriptor rd : readStructure.descriptors) {
if (rd.type != ReadType.Barcode) continue;
@@ -584,8 +584,8 @@ public class ExtractIlluminaBarcodes extends CommandLineProgram {
//(see customCommnandLineValidation), therefore we must use the outputReadStructure to index into the output cluster data
final int[] barcodeIndices = outputReadStructure.sampleBarcodes.getIndices();
final BufferedWriter writer = IOUtil.openFileForBufferedWriting(barcodeFile);
- final byte barcodeSubsequences[][] = new byte[barcodeIndices.length][];
- final byte qualityScores[][] = usingQualityScores ? new byte[barcodeIndices.length][] : null;
+ final byte[][] barcodeSubsequences = new byte[barcodeIndices.length][];
+ final byte[][] qualityScores = usingQualityScores ? new byte[barcodeIndices.length][] : null;
while (provider.hasNext()) {
// Extract the barcode from the cluster and write it to the file for the tile
final ClusterData cluster = provider.next();
diff --git a/src/java/picard/illumina/IlluminaBasecallsToFastq.java b/src/java/picard/illumina/IlluminaBasecallsToFastq.java
index d3c3b4d..d0141e7 100644
--- a/src/java/picard/illumina/IlluminaBasecallsToFastq.java
+++ b/src/java/picard/illumina/IlluminaBasecallsToFastq.java
@@ -257,7 +257,7 @@ public class IlluminaBasecallsToFastq extends CommandLineProgram {
final Set<String> missingColumns = new HashSet<>(expectedCols);
missingColumns.removeAll(actualCols);
- if (missingColumns.size() > 0) {
+ if (!missingColumns.isEmpty()) {
throw new PicardException(String.format(
"MULTIPLEX_PARAMS file %s is missing the following columns: %s.",
MULTIPLEX_PARAMS.getAbsolutePath(), StringUtil.join(", ", missingColumns
@@ -284,7 +284,7 @@ public class IlluminaBasecallsToFastq extends CommandLineProgram {
for (final TabbedTextFileWithHeaderParser.Row row : libraryParamsParser) {
List<String> sampleBarcodeValues = null;
- if (sampleBarcodeColumnLabels.size() > 0) {
+ if (!sampleBarcodeColumnLabels.isEmpty()) {
sampleBarcodeValues = new ArrayList<>();
for (final String sampleBarcodeLabel : sampleBarcodeColumnLabels) {
sampleBarcodeValues.add(row.getField(sampleBarcodeLabel));
@@ -344,7 +344,7 @@ public class IlluminaBasecallsToFastq extends CommandLineProgram {
* Container for various FastqWriters, one for each template read, one for each sample barcode read,
* and one for each molecular barcode read.
*/
- private static class FastqRecordsWriter implements IlluminaBasecallsConverter.ConvertedClusterDataWriter<FastqRecordsForCluster> {
+ private static final class FastqRecordsWriter implements IlluminaBasecallsConverter.ConvertedClusterDataWriter<FastqRecordsForCluster> {
final FastqWriter[] templateWriters;
final FastqWriter[] sampleBarcodeWriters;
final FastqWriter[] molecularBarcodeWriters;
diff --git a/src/java/picard/illumina/IlluminaBasecallsToSam.java b/src/java/picard/illumina/IlluminaBasecallsToSam.java
index c205052..68dd57d 100644
--- a/src/java/picard/illumina/IlluminaBasecallsToSam.java
+++ b/src/java/picard/illumina/IlluminaBasecallsToSam.java
@@ -271,7 +271,7 @@ public class IlluminaBasecallsToSam extends CommandLineProgram {
final Set<String> missingColumns = new HashSet<String>(expectedCols);
missingColumns.removeAll(actualCols);
- if (missingColumns.size() > 0) {
+ if (!missingColumns.isEmpty()) {
throw new PicardException(String.format(
"LIBRARY_PARAMS file %s is missing the following columns: %s.",
LIBRARY_PARAMS.getAbsolutePath(), StringUtil.join(", ", missingColumns
@@ -293,7 +293,7 @@ public class IlluminaBasecallsToSam extends CommandLineProgram {
final Set<String> forbiddenHeaders = buildSamHeaderParameters(null).keySet();
forbiddenHeaders.retainAll(rgTagColumns);
- if (forbiddenHeaders.size() > 0) {
+ if (!forbiddenHeaders.isEmpty()) {
throw new PicardException("Illegal ReadGroup tags in library params(barcode params) file(" + LIBRARY_PARAMS.getAbsolutePath() + ") Offending headers = " + StringUtil.join(", ", forbiddenHeaders));
}
@@ -336,7 +336,7 @@ public class IlluminaBasecallsToSam extends CommandLineProgram {
for (final TabbedTextFileWithHeaderParser.Row row : libraryParamsParser) {
List<String> barcodeValues = null;
- if (barcodeColumnLabels.size() > 0) {
+ if (!barcodeColumnLabels.isEmpty()) {
barcodeValues = new ArrayList<String>();
for (final String barcodeLabel : barcodeColumnLabels) {
barcodeValues.add(row.getField(barcodeLabel));
@@ -447,13 +447,13 @@ public class IlluminaBasecallsToSam extends CommandLineProgram {
if (READ_GROUP_ID == null) {
READ_GROUP_ID = RUN_BARCODE.substring(0, 5) + "." + LANE;
}
- if (messages.size() == 0) {
+ if (messages.isEmpty()) {
return null;
}
return messages.toArray(new String[messages.size()]);
}
- private static class SAMFileWriterWrapper
+ private static final class SAMFileWriterWrapper
implements IlluminaBasecallsConverter.ConvertedClusterDataWriter<SAMRecordsForCluster> {
public final SAMFileWriter writer;
diff --git a/src/java/picard/illumina/MarkIlluminaAdapters.java b/src/java/picard/illumina/MarkIlluminaAdapters.java
index d7e39f7..bc1e904 100644
--- a/src/java/picard/illumina/MarkIlluminaAdapters.java
+++ b/src/java/picard/illumina/MarkIlluminaAdapters.java
@@ -241,7 +241,7 @@ public class MarkIlluminaAdapters extends CommandLineProgram {
return 0;
}
- private class CustomAdapterPair implements AdapterPair {
+ private final class CustomAdapterPair implements AdapterPair {
final String fivePrime, threePrime, fivePrimeReadOrder;
final byte[] fivePrimeBytes, threePrimeBytes, fivePrimeReadOrderBytes;
diff --git a/src/java/picard/illumina/parser/BarcodeParser.java b/src/java/picard/illumina/parser/BarcodeParser.java
index 675a419..9738a5e 100644
--- a/src/java/picard/illumina/parser/BarcodeParser.java
+++ b/src/java/picard/illumina/parser/BarcodeParser.java
@@ -56,7 +56,7 @@ class BarcodeParser extends PerTileParser<BarcodeData> {
}
private static class BarcodeDataIterator implements CloseableIterator<BarcodeData>{
- private BarcodeFileReader bfr;
+ private final BarcodeFileReader bfr;
public BarcodeDataIterator(final File file) {
bfr = new BarcodeFileReader(file);
}
diff --git a/src/java/picard/illumina/parser/FourChannelIntensityData.java b/src/java/picard/illumina/parser/FourChannelIntensityData.java
index a097ed6..3f751a2 100644
--- a/src/java/picard/illumina/parser/FourChannelIntensityData.java
+++ b/src/java/picard/illumina/parser/FourChannelIntensityData.java
@@ -40,10 +40,10 @@ public class FourChannelIntensityData {
/**
* Major index: channel number; minor index: cycle number (zero based)
*/
- private short [] a;
- private short [] c;
- private short [] g;
- private short [] t;
+ private final short [] a;
+ private final short [] c;
+ private final short [] g;
+ private final short [] t;
public FourChannelIntensityData(final int numberOfCycles) {
a = new short[numberOfCycles];
diff --git a/src/java/picard/illumina/parser/IlluminaDataProviderFactory.java b/src/java/picard/illumina/parser/IlluminaDataProviderFactory.java
index ea7f536..cad0242 100644
--- a/src/java/picard/illumina/parser/IlluminaDataProviderFactory.java
+++ b/src/java/picard/illumina/parser/IlluminaDataProviderFactory.java
@@ -168,7 +168,7 @@ public class IlluminaDataProviderFactory {
//find if we have any IlluminaDataType with NO available file formats and, if any exist, throw an exception
final Set<IlluminaDataType> unmatchedDataTypes = findUnmatchedTypes(dataTypes, formatToDataTypes);
- if (unmatchedDataTypes.size() > 0) {
+ if (!unmatchedDataTypes.isEmpty()) {
throw new PicardException("Could not find a format with available files for the following data types: " + StringUtil.join(", ", new ArrayList<IlluminaDataType>(unmatchedDataTypes)));
}
@@ -224,7 +224,7 @@ public class IlluminaDataProviderFactory {
if (requestedTiles == null) {
requestedTiles = availableTiles;
} else {
- if (requestedTiles.size() == 0) {
+ if (requestedTiles.isEmpty()) {
throw new PicardException("Zero length tile list supplied to makeDataProvider, you must specify at least 1 tile OR pass NULL to use all available tiles");
}
}
diff --git a/src/java/picard/illumina/parser/IlluminaFileUtil.java b/src/java/picard/illumina/parser/IlluminaFileUtil.java
index df3a91c..51cd573 100644
--- a/src/java/picard/illumina/parser/IlluminaFileUtil.java
+++ b/src/java/picard/illumina/parser/IlluminaFileUtil.java
@@ -194,7 +194,7 @@ public class IlluminaFileUtil {
throw new PicardException("Format list provided to getTiles was null!");
}
- if (formats.size() == 0) {
+ if (formats.isEmpty()) {
throw new PicardException(
"0 Formats were specified. You need to specify at least SupportedIlluminaFormat to use getTiles");
}
@@ -233,7 +233,7 @@ public class IlluminaFileUtil {
private String liToStr(final List<Integer> intList) {
- if (intList.size() == 0) {
+ if (intList.isEmpty()) {
return "";
}
diff --git a/src/java/picard/illumina/parser/MultiTileBclFileUtil.java b/src/java/picard/illumina/parser/MultiTileBclFileUtil.java
index ba635a6..e84dd87 100644
--- a/src/java/picard/illumina/parser/MultiTileBclFileUtil.java
+++ b/src/java/picard/illumina/parser/MultiTileBclFileUtil.java
@@ -72,7 +72,7 @@ public class MultiTileBclFileUtil extends ParameterizedFileUtil {
@Override
public boolean filesAvailable() {
- return bci.exists() && cycleFileMap.size() > 0;
+ return bci.exists() && !cycleFileMap.isEmpty();
}
@Override
diff --git a/src/java/picard/illumina/parser/PerTileFileUtil.java b/src/java/picard/illumina/parser/PerTileFileUtil.java
index af31681..fa12df3 100644
--- a/src/java/picard/illumina/parser/PerTileFileUtil.java
+++ b/src/java/picard/illumina/parser/PerTileFileUtil.java
@@ -21,7 +21,7 @@ public class PerTileFileUtil extends ParameterizedFileUtil {
final FileFaker faker, final int lane, final boolean skipEmptyFiles) {
super(true, extension, base, faker, lane, skipEmptyFiles);
this.fileMap = getTiledFiles(base, matchPattern);
- if (fileMap.size() > 0) {
+ if (!fileMap.isEmpty()) {
this.tiles = Collections.unmodifiableList(new ArrayList<Integer>(this.fileMap.keySet()));
} else {
this.tiles = new ArrayList<Integer>();
diff --git a/src/java/picard/illumina/parser/ReadStructure.java b/src/java/picard/illumina/parser/ReadStructure.java
index 513e44d..143217e 100644
--- a/src/java/picard/illumina/parser/ReadStructure.java
+++ b/src/java/picard/illumina/parser/ReadStructure.java
@@ -111,7 +111,7 @@ public class ReadStructure {
* @param collection A collection of ReadDescriptors that describes this ReadStructure
*/
public ReadStructure(final List<ReadDescriptor> collection) {
- if(collection.size() == 0) { //If this changes, change hashcode
+ if(collection.isEmpty()) { //If this changes, change hashcode
throw new IllegalArgumentException("ReadStructure does not support 0 length clusters!");
}
@@ -352,7 +352,7 @@ public class ReadStructure {
/** An iterator over a Substructure's ReadDescriptors */
private class IndexedIterator implements Iterator<ReadDescriptor> {
private int index;
- private int [] indices;
+ private final int [] indices;
public IndexedIterator(final int [] indices) {
this.indices = indices;
this.index = 0;
diff --git a/src/java/picard/illumina/parser/TileIndex.java b/src/java/picard/illumina/parser/TileIndex.java
index 298d9a1..21a224d 100644
--- a/src/java/picard/illumina/parser/TileIndex.java
+++ b/src/java/picard/illumina/parser/TileIndex.java
@@ -134,7 +134,7 @@ public class TileIndex implements Iterable<TileIndex.TileIndexRecord> {
throw new NoSuchElementException(String.format("Tile %d not found in %s", tileNumber, tileIndexFile));
}
- public static class TileIndexRecord {
+ public static final class TileIndexRecord {
/**
* Number of the tile, e.g. 11101. These don't necessarily start at 0, and there may be gaps.
*/
diff --git a/src/java/picard/illumina/parser/fakers/BarcodeFileFaker.java b/src/java/picard/illumina/parser/fakers/BarcodeFileFaker.java
index 4b8aacf..be861f0 100644
--- a/src/java/picard/illumina/parser/fakers/BarcodeFileFaker.java
+++ b/src/java/picard/illumina/parser/fakers/BarcodeFileFaker.java
@@ -6,11 +6,11 @@ import java.nio.ByteBuffer;
* Created by jcarey on 3/13/14.
*/
public class BarcodeFileFaker extends FileFaker {
- private final String barcodeString = "1\tn\t \n";
+ private static final String BARCODE_STRING = "1\tn\t \n";
@Override
protected void fakeFile(final ByteBuffer buffer) {
- buffer.put(barcodeString.getBytes());
+ buffer.put(BARCODE_STRING.getBytes());
}
@Override
@@ -20,6 +20,6 @@ public class BarcodeFileFaker extends FileFaker {
@Override
protected int bufferSize() {
- return barcodeString.getBytes().length;
+ return BARCODE_STRING.getBytes().length;
}
-}
+}
diff --git a/src/java/picard/illumina/parser/fakers/PosFileFaker.java b/src/java/picard/illumina/parser/fakers/PosFileFaker.java
index d3c449e..9596425 100644
--- a/src/java/picard/illumina/parser/fakers/PosFileFaker.java
+++ b/src/java/picard/illumina/parser/fakers/PosFileFaker.java
@@ -6,11 +6,11 @@ import java.nio.ByteBuffer;
* Created by jcarey on 3/13/14.
*/
public class PosFileFaker extends FileFaker {
- private final String posFileString = "102.0\t303.3\n";
+ private static final String POS_FILE_STRING = "102.0\t303.3\n";
@Override
protected void fakeFile(final ByteBuffer buffer) {
- buffer.put(posFileString.getBytes());
+ buffer.put(POS_FILE_STRING.getBytes());
}
@Override
@@ -20,6 +20,6 @@ public class PosFileFaker extends FileFaker {
@Override
protected int bufferSize() {
- return posFileString.getBytes().length;
+ return POS_FILE_STRING.getBytes().length;
}
-}
+}
diff --git a/src/java/picard/illumina/parser/readers/BclQualityEvaluationStrategy.java b/src/java/picard/illumina/parser/readers/BclQualityEvaluationStrategy.java
index dfc8608..9b448f1 100644
--- a/src/java/picard/illumina/parser/readers/BclQualityEvaluationStrategy.java
+++ b/src/java/picard/illumina/parser/readers/BclQualityEvaluationStrategy.java
@@ -29,7 +29,7 @@ public class BclQualityEvaluationStrategy {
public static final int ILLUMINA_ALLEGED_MINIMUM_QUALITY = 2;
private final int minimumRevisedQuality;
/** A thread-safe defaulting map that injects an AtomicInteger starting at 0 when a uninitialized key is get-ted. */
- private Map<Byte, AtomicInteger> qualityCountMap = Collections.synchronizedMap(new CollectionUtil.DefaultingMap<Byte, AtomicInteger>(
+ private final Map<Byte, AtomicInteger> qualityCountMap = Collections.synchronizedMap(new CollectionUtil.DefaultingMap<Byte, AtomicInteger>(
new CollectionUtil.DefaultingMap.Factory<AtomicInteger, Byte>() {
@Override
public AtomicInteger make(final Byte _) {
diff --git a/src/java/picard/illumina/parser/readers/FilterFileReader.java b/src/java/picard/illumina/parser/readers/FilterFileReader.java
index 16b824b..6b8b065 100644
--- a/src/java/picard/illumina/parser/readers/FilterFileReader.java
+++ b/src/java/picard/illumina/parser/readers/FilterFileReader.java
@@ -42,7 +42,7 @@ public class FilterFileReader implements Iterator<Boolean> {
private static final int HEADER_SIZE = 12;
/** Expected Version */
- public final int EXPECTED_VERSION = 3;
+ public static final int EXPECTED_VERSION = 3;
/** Iterator over each cluster in the FilterFile */
private final BinaryFileIterator<Byte> bbIterator;
diff --git a/src/java/picard/illumina/parser/readers/MMapBackedIteratorFactory.java b/src/java/picard/illumina/parser/readers/MMapBackedIteratorFactory.java
index 0a66128..c76b383 100644
--- a/src/java/picard/illumina/parser/readers/MMapBackedIteratorFactory.java
+++ b/src/java/picard/illumina/parser/readers/MMapBackedIteratorFactory.java
@@ -203,8 +203,8 @@ public class MMapBackedIteratorFactory {
//TODO: Add test
//TODO: Make a note that if you want to multithread over this then you have to copy the contents
private static class ByteBufferMMapIterator extends MMapBackedIterator<ByteBuffer> {
- private byte [] localBacking;
- private ByteBuffer localBuffer;
+ private final byte [] localBacking;
+ private final ByteBuffer localBuffer;
public ByteBufferMMapIterator(final byte[] header, final File file, final int elementBufferSize, final ByteBuffer buf) {
super(header, file, elementBufferSize, buf);
this.localBacking = new byte[elementBufferSize];
diff --git a/src/java/picard/illumina/quality/CollectHiSeqXPfFailMetrics.java b/src/java/picard/illumina/quality/CollectHiSeqXPfFailMetrics.java
index 66ae083..cacc0fa 100644
--- a/src/java/picard/illumina/quality/CollectHiSeqXPfFailMetrics.java
+++ b/src/java/picard/illumina/quality/CollectHiSeqXPfFailMetrics.java
@@ -109,7 +109,7 @@ public class CollectHiSeqXPfFailMetrics extends CommandLineProgram {
errors.add("PROB_EXPLICIT_READS must be a probability, i.e., 0 <= PROB_EXPLICIT_READS <= 1");
}
- if (errors.size() > 0) {
+ if (!errors.isEmpty()) {
return errors.toArray(new String[errors.size()]);
} else {
return super.customCommandLineValidation();
diff --git a/src/java/picard/sam/FastqToSam.java b/src/java/picard/sam/FastqToSam.java
index 37bf41e..441d292 100644
--- a/src/java/picard/sam/FastqToSam.java
+++ b/src/java/picard/sam/FastqToSam.java
@@ -462,7 +462,7 @@ public class FastqToSam extends CommandLineProgram {
if(readName.equals("")) throw new PicardException(error(freader,"Pair read name "+pairNum+" cannot be empty: "+readName));
final int idx = readName.lastIndexOf("/");
- final String result[] = new String[2];
+ final String[] result = new String[2];
if (idx == -1) {
result[0] = readName;
diff --git a/src/java/picard/sam/FilterSamReads.java b/src/java/picard/sam/FilterSamReads.java
index 234262b..12536be 100644
--- a/src/java/picard/sam/FilterSamReads.java
+++ b/src/java/picard/sam/FilterSamReads.java
@@ -20,6 +20,7 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
+ *
*/
/**
@@ -35,6 +36,7 @@ import htsjdk.samtools.SamReader;
import htsjdk.samtools.SamReaderFactory;
import htsjdk.samtools.filter.AlignedFilter;
import htsjdk.samtools.filter.FilteringIterator;
+import htsjdk.samtools.filter.JavascriptSamRecordFilter;
import htsjdk.samtools.filter.ReadNameFilter;
import htsjdk.samtools.util.IOUtil;
import htsjdk.samtools.util.Log;
@@ -78,13 +80,13 @@ public class FilterSamReads extends CommandLineProgram {
"For information on the SAM format, please see: http://samtools.sourceforge.net" +
"<hr />";
private static final Log log = Log.getInstance(FilterSamReads.class);
-
- private static enum Filter {
+
+ protected /* <- used in test */ enum Filter {
includeAligned("OUTPUT SAM/BAM will contain aligned reads only. INPUT SAM/BAM must be in queryname SortOrder. (Note that *both* first and second of paired reads must be aligned to be included in the OUTPUT SAM or BAM)"),
excludeAligned("OUTPUT SAM/BAM will contain un-mapped reads only. INPUT SAM/BAM must be in queryname SortOrder. (Note that *both* first and second of pair must be aligned to be excluded from the OUTPUT SAM or BAM)"),
includeReadList("OUTPUT SAM/BAM will contain reads that are supplied in the READ_LIST_FILE file"),
- excludeReadList("OUTPUT bam will contain reads that are *not* supplied in the READ_LIST_FILE file");
-
+ excludeReadList("OUTPUT bam will contain reads that are *not* supplied in the READ_LIST_FILE file"),
+ includeJavascript("OUTPUT bam will contain reads that hava been accepted by the JAVASCRIPT_FILE script.");
private final String description;
Filter(final String description) {
@@ -123,7 +125,17 @@ public class FilterSamReads extends CommandLineProgram {
@Option(doc = "SAM or BAM file to write read excluded results to",
optional = false, shortName = "O")
public File OUTPUT;
-
+
+ @Option(shortName = "JS",
+ doc = "Filters a SAM or BAM file with a javascript expression using the java javascript-engine. "
+ + " The script puts the following variables in the script context: "
+ + " 'record' a SamRecord ( https://samtools.github.io/htsjdk/javadoc/htsjdk/htsjdk/samtools/SAMRecord.html ) and "
+ + " 'header' a SAMFileHeader ( https://samtools.github.io/htsjdk/javadoc/htsjdk/htsjdk/samtools/SAMFileHeader.html )."
+ + " Last value of the script should be a boolean to tell wether we should accept or reject the record.",
+ optional = true)
+ public File JAVASCRIPT_FILE = null;
+
+
private void filterReads(final FilteringIterator filteringIterator) {
// get OUTPUT header from INPUT and overwrite it if necessary
@@ -181,27 +193,39 @@ public class FilterSamReads extends CommandLineProgram {
IOUtil.assertFileIsReadable(INPUT);
IOUtil.assertFileIsWritable(OUTPUT);
if (WRITE_READS_FILES) writeReadsFile(INPUT);
-
+ final SamReader samReader = SamReaderFactory.makeDefault().referenceSequence(REFERENCE_SEQUENCE).open(INPUT);
+ final FilteringIterator filteringIterator;
+
switch (FILTER) {
case includeAligned:
- filterReads(new FilteringIterator(SamReaderFactory.makeDefault().referenceSequence(REFERENCE_SEQUENCE).open(INPUT).iterator(),
- new AlignedFilter(true), true));
+ filteringIterator = new FilteringIterator(samReader.iterator(),
+ new AlignedFilter(true), true);
break;
case excludeAligned:
- filterReads(new FilteringIterator(SamReaderFactory.makeDefault().referenceSequence(REFERENCE_SEQUENCE).open(INPUT).iterator(),
- new AlignedFilter(false), true));
+ filteringIterator = new FilteringIterator(samReader.iterator(),
+ new AlignedFilter(false), true);
break;
case includeReadList:
- filterReads(new FilteringIterator(SamReaderFactory.makeDefault().referenceSequence(REFERENCE_SEQUENCE).open(INPUT).iterator(),
- new ReadNameFilter(READ_LIST_FILE, true)));
+ filteringIterator = new FilteringIterator(samReader.iterator(),
+ new ReadNameFilter(READ_LIST_FILE, true));
break;
case excludeReadList:
- filterReads(new FilteringIterator(SamReaderFactory.makeDefault().referenceSequence(REFERENCE_SEQUENCE).open(INPUT).iterator(),
- new ReadNameFilter(READ_LIST_FILE, false)));
+ filteringIterator = new FilteringIterator(samReader.iterator(),
+ new ReadNameFilter(READ_LIST_FILE, false));
+ break;
+ case includeJavascript:
+ filteringIterator = new FilteringIterator(samReader.iterator(),
+ new JavascriptSamRecordFilter(
+ JAVASCRIPT_FILE,
+ samReader.getFileHeader()
+ ));
+
break;
default:
throw new UnsupportedOperationException(FILTER.name() + " has not been implemented!");
}
+
+ filterReads(filteringIterator);
IOUtil.assertFileIsReadable(OUTPUT);
if (WRITE_READS_FILES) writeReadsFile(OUTPUT);
diff --git a/src/java/picard/sam/MergeBamAlignment.java b/src/java/picard/sam/MergeBamAlignment.java
index 57e1ece..18a54f8 100644
--- a/src/java/picard/sam/MergeBamAlignment.java
+++ b/src/java/picard/sam/MergeBamAlignment.java
@@ -289,14 +289,14 @@ public class MergeBamAlignment extends CommandLineProgram {
"be included."};
}
- final boolean r1sExist = READ1_ALIGNED_BAM != null && READ1_ALIGNED_BAM.size() > 0;
- final boolean r2sExist = READ2_ALIGNED_BAM != null && READ2_ALIGNED_BAM.size() > 0;
+ final boolean r1sExist = READ1_ALIGNED_BAM != null && !READ1_ALIGNED_BAM.isEmpty();
+ final boolean r2sExist = READ2_ALIGNED_BAM != null && !READ2_ALIGNED_BAM.isEmpty();
if ((r1sExist && !r2sExist) || (r2sExist && !r1sExist)) {
return new String[]{"READ1_ALIGNED_BAM and READ2_ALIGNED_BAM " +
"must both be supplied or neither should be included. For " +
"single-end read use ALIGNED_BAM."};
}
- if (ALIGNED_BAM == null || ALIGNED_BAM.size() == 0 && !(r1sExist && r2sExist)) {
+ if (ALIGNED_BAM == null || ALIGNED_BAM.isEmpty() && !(r1sExist && r2sExist)) {
return new String[]{"Either ALIGNED_BAM or the combination of " +
"READ1_ALIGNED_BAM and READ2_ALIGNED_BAM must be supplied."};
diff --git a/src/java/picard/sam/RevertSam.java b/src/java/picard/sam/RevertSam.java
index 65c1aea..7e7d72e 100644
--- a/src/java/picard/sam/RevertSam.java
+++ b/src/java/picard/sam/RevertSam.java
@@ -313,7 +313,7 @@ public class RevertSam extends CommandLineProgram {
// The only valid quality score encoding scheme is standard; if it's not standard, change it.
final FastqQualityFormat recordFormat = readGroupToFormat.get(rec.getReadGroup());
if (!recordFormat.equals(FastqQualityFormat.Standard)) {
- final byte quals[] = rec.getBaseQualities();
+ final byte[] quals = rec.getBaseQualities();
for (int i = 0; i < quals.length; i++) {
quals[i] -= SolexaQualityConverter.ILLUMINA_TO_PHRED_SUBTRAHEND;
}
diff --git a/src/java/picard/sam/SamAlignmentMerger.java b/src/java/picard/sam/SamAlignmentMerger.java
index f781a61..15a697f 100644
--- a/src/java/picard/sam/SamAlignmentMerger.java
+++ b/src/java/picard/sam/SamAlignmentMerger.java
@@ -107,9 +107,9 @@ public class SamAlignmentMerger extends AbstractAlignmentMerger {
alignedReadsOnly, programRecord, attributesToRetain, attributesToRemove, read1BasesTrimmed,
read2BasesTrimmed, expectedOrientations, sortOrder, primaryAlignmentSelectionStrategy, addMateCigar, unmapContaminantReads);
- if ((alignedSamFile == null || alignedSamFile.size() == 0) &&
- (read1AlignedSamFile == null || read1AlignedSamFile.size() == 0 ||
- read2AlignedSamFile == null || read2AlignedSamFile.size() == 0)) {
+ if ((alignedSamFile == null || alignedSamFile.isEmpty()) &&
+ (read1AlignedSamFile == null || read1AlignedSamFile.isEmpty() ||
+ read2AlignedSamFile == null || read2AlignedSamFile.isEmpty())) {
throw new IllegalArgumentException("Either alignedSamFile or BOTH of read1AlignedSamFile and " +
"read2AlignedSamFile must be specified.");
}
@@ -164,7 +164,7 @@ public class SamAlignmentMerger extends AbstractAlignmentMerger {
final SAMFileHeader header;
// When the alignment records, including both ends of a pair, are in SAM files
- if (alignedSamFile != null && alignedSamFile.size() > 0) {
+ if (alignedSamFile != null && !alignedSamFile.isEmpty()) {
final List<SAMFileHeader> headers = new ArrayList<SAMFileHeader>(alignedSamFile.size());
final List<SamReader> readers = new ArrayList<SamReader>(alignedSamFile.size());
for (final File f : this.alignedSamFile) {
@@ -227,7 +227,7 @@ public class SamAlignmentMerger extends AbstractAlignmentMerger {
};
}
- private class SuffixTrimingSamRecordIterator implements CloseableIterator<SAMRecord> {
+ private final class SuffixTrimingSamRecordIterator implements CloseableIterator<SAMRecord> {
private final CloseableIterator<SAMRecord> underlyingIterator;
private final String suffixToTrim;
diff --git a/src/java/picard/sam/SamToFastq.java b/src/java/picard/sam/SamToFastq.java
index 8d06444..8990c33 100755
--- a/src/java/picard/sam/SamToFastq.java
+++ b/src/java/picard/sam/SamToFastq.java
@@ -208,7 +208,7 @@ public class SamToFastq extends CommandLineProgram {
writerMapping.closeAll();
}
- if (firstSeenMates.size() > 0) {
+ if (!firstSeenMates.isEmpty()) {
SAMUtils.processValidationError(new SAMValidationError(SAMValidationError.Type.MATE_NOT_FOUND,
"Found " + firstSeenMates.size() + " unpaired mates", null), VALIDATION_STRINGENCY);
}
@@ -438,7 +438,7 @@ public class SamToFastq extends CommandLineProgram {
* Allows for lazy construction of the second-of-pair writer, since when we are in the "output per read group mode", we only wish to
* generate a second-of-pair fastq if we encounter a second-of-pair read.
*/
- static class FastqWriters {
+ static final class FastqWriters {
private final FastqWriter firstOfPair, unpaired;
private final Lazy<FastqWriter> secondOfPair;
diff --git a/src/java/picard/sam/SplitSamByLibrary.java b/src/java/picard/sam/SplitSamByLibrary.java
index 6de2f1c..7528216 100755
--- a/src/java/picard/sam/SplitSamByLibrary.java
+++ b/src/java/picard/sam/SplitSamByLibrary.java
@@ -106,7 +106,7 @@ public class SplitSamByLibrary extends CommandLineProgram {
}
}
- if (libraryToRg.size() == 0) {
+ if (libraryToRg.isEmpty()) {
log.error("No individual libraries are " +
"specified in the header of " + INPUT.getAbsolutePath());
return NO_LIBRARIES_SPECIFIED_IN_HEADER;
diff --git a/src/java/picard/sam/markduplicates/EstimateLibraryComplexity.java b/src/java/picard/sam/markduplicates/EstimateLibraryComplexity.java
index d8e9718..5201bdb 100644
--- a/src/java/picard/sam/markduplicates/EstimateLibraryComplexity.java
+++ b/src/java/picard/sam/markduplicates/EstimateLibraryComplexity.java
@@ -173,7 +173,7 @@ public class EstimateLibraryComplexity extends AbstractOpticalDuplicateFinderCom
if (MIN_IDENTICAL_BASES <= 0) {
errorMsgs.add("MIN_IDENTICAL_BASES must be greater than 0");
}
- return errorMsgs.size() == 0 ? super.customCommandLineValidation() : errorMsgs.toArray(new String[errorMsgs.size()]);
+ return errorMsgs.isEmpty() ? super.customCommandLineValidation() : errorMsgs.toArray(new String[errorMsgs.size()]);
}
/**
@@ -540,7 +540,7 @@ public class EstimateLibraryComplexity extends AbstractOpticalDuplicateFinderCom
}
}
- if (dupes.size() > 0) {
+ if (!dupes.isEmpty()) {
dupes.add(lhs);
final int duplicateCount = dupes.size();
duplicationHisto.increment(duplicateCount);
diff --git a/src/java/picard/sam/markduplicates/util/AbstractOpticalDuplicateFinderCommandLineProgram.java b/src/java/picard/sam/markduplicates/util/AbstractOpticalDuplicateFinderCommandLineProgram.java
index c574af3..0b66a24 100644
--- a/src/java/picard/sam/markduplicates/util/AbstractOpticalDuplicateFinderCommandLineProgram.java
+++ b/src/java/picard/sam/markduplicates/util/AbstractOpticalDuplicateFinderCommandLineProgram.java
@@ -50,9 +50,9 @@ public abstract class AbstractOpticalDuplicateFinderCommandLineProgram extends C
optional = true)
public String READ_NAME_REGEX = OpticalDuplicateFinder.DEFAULT_READ_NAME_REGEX;
- @Option(doc = "The maximum offset between two duplicte clusters in order to consider them optical duplicates. This " +
- "should usually be set to some fairly small number (e.g. 5-10 pixels) unless using later versions of the " +
- "Illumina pipeline that multiply pixel values by 10, in which case 50-100 is more normal.")
+ @Option(doc = "The maximum offset between two duplicate clusters in order to consider them optical duplicates. The default " +
+ "is appropriate for unpatterned versions of the Illumina platform. For the patterned flowcell models, 2500 is more" +
+ "appropriate. For other platforms and models, users should experiment to find what works best.")
public int OPTICAL_DUPLICATE_PIXEL_DISTANCE = OpticalDuplicateFinder.DEFAULT_OPTICAL_DUPLICATE_DISTANCE;
// The tool with which to find optical duplicates
diff --git a/src/java/picard/sam/markduplicates/util/MemoryBasedReadEndsForMarkDuplicatesMap.java b/src/java/picard/sam/markduplicates/util/MemoryBasedReadEndsForMarkDuplicatesMap.java
index 745a2a8..4d20e1e 100644
--- a/src/java/picard/sam/markduplicates/util/MemoryBasedReadEndsForMarkDuplicatesMap.java
+++ b/src/java/picard/sam/markduplicates/util/MemoryBasedReadEndsForMarkDuplicatesMap.java
@@ -39,7 +39,7 @@ class MemoryBasedReadEndsForMarkDuplicatesMap implements ReadEndsForMarkDuplicat
* Index of this list is sequence index. Value is map from String {read group id:read name} to ReadEnds.
* When a ReadEnds is put into this container, it is stored according to the sequenceIndex of the mate
*/
- private List<Map<String, ReadEndsForMarkDuplicates>> mapPerSequence = new ArrayList<Map<String, ReadEndsForMarkDuplicates>>();
+ private final List<Map<String, ReadEndsForMarkDuplicates>> mapPerSequence = new ArrayList<Map<String, ReadEndsForMarkDuplicates>>();
public ReadEndsForMarkDuplicates remove(int mateSequenceIndex, String key) {
if (mateSequenceIndex >= mapPerSequence.size()) {
diff --git a/src/java/picard/sam/util/PhysicalLocation.java b/src/java/picard/sam/util/PhysicalLocation.java
index eaf0fc4..fba814e 100644
--- a/src/java/picard/sam/util/PhysicalLocation.java
+++ b/src/java/picard/sam/util/PhysicalLocation.java
@@ -6,7 +6,7 @@ package picard.sam.util;
* non-zero positive integers, x and y coordinates may be negative.
*/
public interface PhysicalLocation {
- public int NO_VALUE = -1;
+ public static int NO_VALUE = -1;
public short getReadGroup();
diff --git a/src/java/picard/util/AdapterMarker.java b/src/java/picard/util/AdapterMarker.java
index 683f04a..5ddaba9 100644
--- a/src/java/picard/util/AdapterMarker.java
+++ b/src/java/picard/util/AdapterMarker.java
@@ -277,7 +277,7 @@ public class AdapterMarker {
}
}
- private static class TruncatedAdapterPair implements AdapterPair {
+ private static final class TruncatedAdapterPair implements AdapterPair {
String name;
final String fivePrime, threePrime, fivePrimeReadOrder;
final byte[] fivePrimeBytes, threePrimeBytes, fivePrimeReadOrderBytes;
diff --git a/src/java/picard/util/BaitDesigner.java b/src/java/picard/util/BaitDesigner.java
index aa5737f..c20742f 100644
--- a/src/java/picard/util/BaitDesigner.java
+++ b/src/java/picard/util/BaitDesigner.java
@@ -355,7 +355,7 @@ public class BaitDesigner extends CommandLineProgram {
errors.add("Right primer " + RIGHT_PRIMER + " is not a valid primer sequence.");
}
- if (errors.size() > 0) return errors.toArray(new String[errors.size()]);
+ if (!errors.isEmpty()) return errors.toArray(new String[errors.size()]);
else return null;
}
diff --git a/src/java/picard/util/BasicInputParser.java b/src/java/picard/util/BasicInputParser.java
index 2df0293..91f285d 100644
--- a/src/java/picard/util/BasicInputParser.java
+++ b/src/java/picard/util/BasicInputParser.java
@@ -110,7 +110,7 @@ public class BasicInputParser extends AbstractInputParser
nextLine = line;
return line.getBytes();
}
- if (inputs.size() > 0) {
+ if (!inputs.isEmpty()) {
advanceFile();
return readNextLine();
}
@@ -122,7 +122,7 @@ public class BasicInputParser extends AbstractInputParser
}
protected void advanceFile() {
- currentFileName = fileNames.size() > 0 ? fileNames.remove(0) : null;
+ currentFileName = !fileNames.isEmpty() ? fileNames.remove(0) : null;
nextLineNumber = 0;
nextLine = null;
reader = new BufferedLineReader(inputs.remove(0));
@@ -166,8 +166,8 @@ public class BasicInputParser extends AbstractInputParser
return currentLineNumber;
}
- private static InputStream[] filesToInputStreams(final File files[]) {
- final InputStream result[] = new InputStream[files.length];
+ private static InputStream[] filesToInputStreams(final File[] files) {
+ final InputStream[] result = new InputStream[files.length];
for (int i = 0; i < files.length; i++) {
result[i] = IOUtil.openFileForReading(files[i]);
}
diff --git a/src/java/picard/util/DbSnpBitSetUtil.java b/src/java/picard/util/DbSnpBitSetUtil.java
index 355e95c..af0559c 100755
--- a/src/java/picard/util/DbSnpBitSetUtil.java
+++ b/src/java/picard/util/DbSnpBitSetUtil.java
@@ -24,13 +24,20 @@
package picard.util;
import htsjdk.samtools.SAMSequenceDictionary;
-import htsjdk.samtools.util.CloseableIterator;
import htsjdk.samtools.util.CloserUtil;
+import htsjdk.samtools.util.IntervalList;
import htsjdk.variant.variantcontext.VariantContext;
import htsjdk.variant.vcf.VCFFileReader;
+import picard.vcf.ByIntervalListVariantContextIterator;
import java.io.File;
-import java.lang.IllegalArgumentException;import java.lang.String;import java.util.BitSet;import java.util.Collection;import java.util.EnumSet;import java.util.HashMap;import java.util.Map;import java.util.Set;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
/**
* Utility class to use with DbSnp files to determine is a locus is
@@ -38,7 +45,7 @@ import java.lang.IllegalArgumentException;import java.lang.String;import java.ut
*/
public class DbSnpBitSetUtil {
- private final Map<String, BitSet> sequenceToBitSet = new HashMap<String,BitSet>();
+ private final Map<String, BitSet> sequenceToBitSet = new HashMap<>();
/** Little tuple class to contain one bitset for SNPs and another for Indels. */
public static class DbSnpBitSets {
@@ -54,6 +61,13 @@ public class DbSnpBitSetUtil {
this(dbSnpFile, sequenceDictionary, EnumSet.noneOf(VariantType.class));
}
+ /** Constructor that creates a bit set with bits set to true for the given variant types. */
+ public DbSnpBitSetUtil(final File dbSnpFile,
+ final SAMSequenceDictionary sequenceDictionary,
+ final Collection<VariantType> variantsToMatch) {
+ this(dbSnpFile, sequenceDictionary, variantsToMatch, null);
+ }
+
/**
* Constructor.
*
@@ -66,39 +80,56 @@ public class DbSnpBitSetUtil {
* @param sequenceDictionary Optionally, a sequence dictionary corresponding to the dbSnp file, else null.
* If present, BitSets will be allocated more efficiently because the maximum size will be known.
* @param variantsToMatch what types of variants to load.
+ * @param intervals an interval list specifying the regions to load, or null, if we are return all dbSNP sites.
*/
public DbSnpBitSetUtil(final File dbSnpFile,
final SAMSequenceDictionary sequenceDictionary,
- final Collection<VariantType> variantsToMatch) {
+ final Collection<VariantType> variantsToMatch,
+ final IntervalList intervals) {
if (dbSnpFile == null) throw new IllegalArgumentException("null dbSnpFile");
- final Map<DbSnpBitSetUtil, Set<VariantType>> tmp = new HashMap<DbSnpBitSetUtil, Set<VariantType>>();
+ final Map<DbSnpBitSetUtil, Set<VariantType>> tmp = new HashMap<>();
tmp.put(this, EnumSet.copyOf(variantsToMatch));
- loadVcf(dbSnpFile, sequenceDictionary, tmp);
+ loadVcf(dbSnpFile, sequenceDictionary, tmp, intervals);
}
/** Factory method to create both a SNP bitmask and an indel bitmask in a single pass of the VCF. */
public static DbSnpBitSets createSnpAndIndelBitSets(final File dbSnpFile,
final SAMSequenceDictionary sequenceDictionary) {
+ return createSnpAndIndelBitSets(dbSnpFile, sequenceDictionary, null);
+ }
+
+ /** Factory method to create both a SNP bitmask and an indel bitmask in a single pass of the VCF.
+ * If intervals are given, consider only SNP and indel sites that overlap the intervals. */
+ public static DbSnpBitSets createSnpAndIndelBitSets(final File dbSnpFile,
+ final SAMSequenceDictionary sequenceDictionary,
+ final IntervalList intervals) {
final DbSnpBitSets sets = new DbSnpBitSets();
sets.snps = new DbSnpBitSetUtil();
sets.indels = new DbSnpBitSetUtil();
- final Map<DbSnpBitSetUtil, Set<VariantType>> map = new HashMap<DbSnpBitSetUtil, Set<VariantType>>();
+ final Map<DbSnpBitSetUtil, Set<VariantType>> map = new HashMap<>();
map.put(sets.snps, EnumSet.of(VariantType.SNP));
map.put(sets.indels, EnumSet.of(VariantType.insertion, VariantType.deletion));
- loadVcf(dbSnpFile, sequenceDictionary, map);
+ loadVcf(dbSnpFile, sequenceDictionary, map, intervals);
return sets;
}
/** Private helper method to read through the VCF and create one or more bit sets. */
private static void loadVcf(final File dbSnpFile,
final SAMSequenceDictionary sequenceDictionary,
- final Map<DbSnpBitSetUtil, Set<VariantType>> bitSetsToVariantTypes) {
+ final Map<DbSnpBitSetUtil, Set<VariantType>> bitSetsToVariantTypes,
+ final IntervalList intervals) {
- final VCFFileReader variantReader = new VCFFileReader(dbSnpFile);
- final CloseableIterator<VariantContext> variantIterator = variantReader.iterator();
+ final VCFFileReader variantReader = new VCFFileReader(dbSnpFile, intervals != null);
+ final Iterator<VariantContext> variantIterator;
+ if (intervals != null) {
+ variantIterator = new ByIntervalListVariantContextIterator(variantReader, intervals);
+ }
+ else {
+ variantIterator = variantReader.iterator();
+ }
while (variantIterator.hasNext()) {
final VariantContext kv = variantIterator.next();
@@ -107,13 +138,13 @@ public class DbSnpBitSetUtil {
final DbSnpBitSetUtil bitset = tuple.getKey();
final Set<VariantType> variantsToMatch = tuple.getValue();
- BitSet bits = bitset.sequenceToBitSet.get(kv.getChr());
+ BitSet bits = bitset.sequenceToBitSet.get(kv.getContig());
if (bits == null) {
final int nBits;
if (sequenceDictionary == null) nBits = kv.getEnd() + 1;
- else nBits = sequenceDictionary.getSequence(kv.getChr()).getSequenceLength() + 1;
+ else nBits = sequenceDictionary.getSequence(kv.getContig()).getSequenceLength() + 1;
bits = new BitSet(nBits);
- bitset.sequenceToBitSet.put(kv.getChr(), bits);
+ bitset.sequenceToBitSet.put(kv.getContig(), bits);
}
if (variantsToMatch.isEmpty() ||
(kv.isSNP() && variantsToMatch.contains(VariantType.SNP)) ||
@@ -125,7 +156,6 @@ public class DbSnpBitSetUtil {
}
}
- CloserUtil.close(variantIterator);
CloserUtil.close(variantReader);
}
@@ -134,13 +164,8 @@ public class DbSnpBitSetUtil {
*/
public boolean isDbSnpSite(final String sequenceName, final int pos) {
// When we have a dbSnpFile with no sequence dictionary, this line will be necessary
- if (sequenceToBitSet.get(sequenceName) == null) {
- return false;
- }
- if (pos > sequenceToBitSet.get(sequenceName).length()) {
- return false;
- }
- return sequenceToBitSet.get(sequenceName).get(pos);
+ return sequenceToBitSet.get(sequenceName) != null &&
+ pos <= sequenceToBitSet.get(sequenceName).length() &&
+ sequenceToBitSet.get(sequenceName).get(pos);
}
-
}
diff --git a/src/java/picard/util/IlluminaUtil.java b/src/java/picard/util/IlluminaUtil.java
index 82e456f..03732af 100644
--- a/src/java/picard/util/IlluminaUtil.java
+++ b/src/java/picard/util/IlluminaUtil.java
@@ -200,7 +200,7 @@ public class IlluminaUtil {
* @param barcodes
* @return A single string representation of all the barcodes
*/
- public static String barcodeSeqsToString(final String barcodes[]) {
+ public static String barcodeSeqsToString(final String[] barcodes) {
return stringSeqsToString(barcodes, BARCODE_DELIMITER);
}
@@ -209,11 +209,11 @@ public class IlluminaUtil {
* @param barcodes
* @return A single string representation of all the barcodes
*/
- public static String barcodeSeqsToString(final byte barcodes[][]) {
+ public static String barcodeSeqsToString(final byte[][] barcodes) {
return byteArrayToString(barcodes, BARCODE_DELIMITER);
}
- public static String stringSeqsToString(final String barcodes[], String delim) {
+ public static String stringSeqsToString(final String[] barcodes, String delim) {
final StringBuilder sb = new StringBuilder();
for (final String bc : barcodes) {
if (sb.length() > 0) sb.append(delim);
@@ -227,8 +227,8 @@ public class IlluminaUtil {
* @param barcodes
* @return A single string representation of all the barcodes
*/
- public static String byteArrayToString(final byte barcodes[][], String delim) {
- final String bcs[] = new String[barcodes.length];
+ public static String byteArrayToString(final byte[][] barcodes, String delim) {
+ final String[] bcs = new String[barcodes.length];
for (int i = 0; i < barcodes.length; i++) {
bcs[i] = StringUtil.bytesToString(barcodes[i]);
}
diff --git a/src/java/picard/util/IntervalListTools.java b/src/java/picard/util/IntervalListTools.java
index 7dc06d7..ec03bfd 100644
--- a/src/java/picard/util/IntervalListTools.java
+++ b/src/java/picard/util/IntervalListTools.java
@@ -295,7 +295,7 @@ public class IntervalListTools extends CommandLineProgram {
if (BREAK_BANDS_AT_MULTIPLES_OF < 0) {
errorMsgs.add("BREAK_BANDS_AT_MULTIPLES_OF must be greater than or equal to 0.");
}
- return errorMsgs.size() == 0 ? null : errorMsgs.toArray(new String[errorMsgs.size()]);
+ return errorMsgs.isEmpty() ? null : errorMsgs.toArray(new String[errorMsgs.size()]);
}
/**
diff --git a/src/java/picard/util/MathUtil.java b/src/java/picard/util/MathUtil.java
index bd04497..acaf80c 100644
--- a/src/java/picard/util/MathUtil.java
+++ b/src/java/picard/util/MathUtil.java
@@ -370,7 +370,7 @@ final public class MathUtil {
/** Returns the log-representation of the provided decimal array. */
public double[] getLogValue(final double[] nonLogArray) {
- final double logArray[] = new double[nonLogArray.length];
+ final double[] logArray = new double[nonLogArray.length];
for (int i = 0; i < nonLogArray.length; i++) {
logArray[i] = getLogValue(nonLogArray[i]);
}
diff --git a/src/java/picard/vcf/CollectVariantCallingMetrics.java b/src/java/picard/vcf/CollectVariantCallingMetrics.java
index b436bf5..1a709f2 100644
--- a/src/java/picard/vcf/CollectVariantCallingMetrics.java
+++ b/src/java/picard/vcf/CollectVariantCallingMetrics.java
@@ -86,6 +86,9 @@ public class CollectVariantCallingMetrics extends CommandLineProgram {
@Override
protected int doWork() {
IOUtil.assertFileIsReadable(INPUT);
+ IOUtil.assertFileIsReadable(DBSNP);
+ if (TARGET_INTERVALS != null) IOUtil.assertFileIsReadable(TARGET_INTERVALS);
+ if (SEQUENCE_DICTIONARY != null) IOUtil.assertFileIsReadable(SEQUENCE_DICTIONARY);
final boolean requiresIndex = this.TARGET_INTERVALS != null || this.THREAD_COUNT > 1;
final VCFFileReader variantReader = new VCFFileReader(INPUT, requiresIndex);
@@ -95,8 +98,10 @@ public class CollectVariantCallingMetrics extends CommandLineProgram {
final SAMSequenceDictionary sequenceDictionary =
SAMSequenceDictionaryExtractor.extractDictionary(SEQUENCE_DICTIONARY == null ? INPUT : SEQUENCE_DICTIONARY);
+ final IntervalList targetIntervals = (TARGET_INTERVALS == null) ? null : IntervalList.fromFile(TARGET_INTERVALS).uniqued();
+
log.info("Loading dbSNP file ...");
- final DbSnpBitSetUtil.DbSnpBitSets dbsnp = DbSnpBitSetUtil.createSnpAndIndelBitSets(DBSNP, sequenceDictionary);
+ final DbSnpBitSetUtil.DbSnpBitSets dbsnp = DbSnpBitSetUtil.createSnpAndIndelBitSets(DBSNP, sequenceDictionary, targetIntervals);
log.info("Starting iteration of variants.");
@@ -111,8 +116,8 @@ public class CollectVariantCallingMetrics extends CommandLineProgram {
.withInput(INPUT)
.multithreadingBy(THREAD_COUNT);
- if (TARGET_INTERVALS != null) {
- builder.limitingProcessedRegionsTo(IntervalList.fromFile(TARGET_INTERVALS).uniqued());
+ if (targetIntervals != null) {
+ builder.limitingProcessedRegionsTo(targetIntervals);
}
final CallingMetricAccumulator.Result result = builder.build().process();
@@ -274,7 +279,7 @@ public class CollectVariantCallingMetrics extends CommandLineProgram {
public static void foldInto(final VariantCallingDetailMetrics target,
final Collection<VariantCallingDetailMetrics> metrics) {
VariantCallingSummaryMetrics.foldInto(target, metrics);
- final Set<String> sampleAliases = new HashSet<String>();
+ final Set<String> sampleAliases = new HashSet<>();
for (final VariantCallingDetailMetrics metric : metrics) {
target.numHets += metric.numHets;
target.numHomVar += metric.numHomVar;
diff --git a/src/java/picard/vcf/GenotypeConcordance.java b/src/java/picard/vcf/GenotypeConcordance.java
index 4f86ac2..0b25b97 100644
--- a/src/java/picard/vcf/GenotypeConcordance.java
+++ b/src/java/picard/vcf/GenotypeConcordance.java
@@ -176,7 +176,7 @@ public class GenotypeConcordance extends CommandLineProgram {
// Note - If the user specifies to use INTERVALS, the code will fail if the vcfs are not indexed, so we set USE_VCF_INDEX to true and check that the vcfs are indexed.
IOUtil.assertFileIsReadable(TRUTH_VCF);
IOUtil.assertFileIsReadable(CALL_VCF);
- final boolean usingIntervals = this.INTERVALS != null && this.INTERVALS.size() > 0;
+ final boolean usingIntervals = this.INTERVALS != null && !this.INTERVALS.isEmpty();
final List<String> errors = new ArrayList<String>();
if (usingIntervals) {
USE_VCF_INDEX = true;
@@ -223,7 +223,7 @@ public class GenotypeConcordance extends CommandLineProgram {
IOUtil.assertFileIsWritable(detailedMetricsFile);
IOUtil.assertFileIsWritable(contingencyMetricsFile);
- final boolean usingIntervals = this.INTERVALS != null && this.INTERVALS.size() > 0;
+ final boolean usingIntervals = this.INTERVALS != null && !this.INTERVALS.isEmpty();
IntervalList intervals = null;
SAMSequenceDictionary intervalsSamSequenceDictionary = null;
if (usingIntervals) {
diff --git a/src/java/picard/vcf/filter/AlleleBalanceFilter.java b/src/java/picard/vcf/filter/AlleleBalanceFilter.java
index d33ed5a..340d3d8 100644
--- a/src/java/picard/vcf/filter/AlleleBalanceFilter.java
+++ b/src/java/picard/vcf/filter/AlleleBalanceFilter.java
@@ -64,7 +64,7 @@ public class AlleleBalanceFilter implements VariantFilter {
final Map<List<Allele>, Counts> countsMap = new HashMap<List<Allele>, Counts>();
for (final Genotype gt : ctx.getGenotypesOrderedByName()) {
- if (gt.isNoCall() || !gt.isHet()) continue;
+ if (gt.isNoCall() || !gt.isHet() || !gt.hasAD()) continue;
final List<Allele> alleles = gt.getAlleles();
Counts counts = countsMap.get(alleles);
diff --git a/src/java/picard/vcf/filter/FilterVcf.java b/src/java/picard/vcf/filter/FilterVcf.java
index 0c277f5..ee9798b 100644
--- a/src/java/picard/vcf/filter/FilterVcf.java
+++ b/src/java/picard/vcf/filter/FilterVcf.java
@@ -20,12 +20,16 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
+ *
*/
package picard.vcf.filter;
import htsjdk.samtools.SAMSequenceDictionary;
+import htsjdk.samtools.util.CloserUtil;
import htsjdk.samtools.util.CollectionUtil;
import htsjdk.samtools.util.IOUtil;
+import htsjdk.variant.variantcontext.VariantContext;
+import htsjdk.variant.variantcontext.filter.JavascriptVariantFilter;
import htsjdk.variant.variantcontext.writer.VariantContextWriter;
import htsjdk.variant.variantcontext.writer.VariantContextWriterBuilder;
import htsjdk.variant.vcf.VCFFileReader;
@@ -42,12 +46,15 @@ import picard.cmdline.StandardOptionDefinitions;
import picard.cmdline.programgroups.VcfOrBcf;
import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
/**
* Applies a set of hard filters to Variants and to Genotypes within a VCF.
*
* @author Tim Fennell
+ * @author Pierre Lindenbaum added the javascript filter in 2016
*/
@CommandLineProgramProperties(
usage = "Applies one or more hard filters to a VCF file to filter out genotypes and variants.",
@@ -77,6 +84,15 @@ public class FilterVcf extends CommandLineProgram {
@Option(doc="The minimum QD value to accept or otherwise filter out the variant.")
public double MIN_QD = 0;
+
+ @Option(shortName = "JS", doc = "Filters a VCF file with a javascript expression interpreted by the java javascript engine. "
+ + " The script puts the following variables in the script context: "
+ + " 'variant' a VariantContext ( https://samtools.github.io/htsjdk/javadoc/htsjdk/htsjdk/variant/variantcontext/VariantContext.html ) and "
+ + " 'header' a VCFHeader ( https://samtools.github.io/htsjdk/javadoc/htsjdk/htsjdk/variant/vcf/VCFHeader.html )."
+ + " Last value of the script should be a boolean to tell wether we should accept or reject the record.",
+ optional = true)
+ public File JAVASCRIPT_FILE = null;
+
/** Constructor to default to having index creation on. */
public FilterVcf() { this.CREATE_INDEX = true; }
@@ -91,44 +107,93 @@ public class FilterVcf extends CommandLineProgram {
IOUtil.assertFileIsReadable(INPUT);
IOUtil.assertFileIsWritable(OUTPUT);
- final List<VariantFilter> variantFilters = CollectionUtil.makeList(new AlleleBalanceFilter(MIN_AB), new FisherStrandFilter(MAX_FS), new QdFilter(MIN_QD));
- final List<GenotypeFilter> genotypeFilters = CollectionUtil.makeList(new GenotypeQualityFilter(MIN_GQ), new DepthFilter(MIN_DP));
- final VCFFileReader in = new VCFFileReader(INPUT, false);
- final FilterApplyingVariantIterator iterator = new FilterApplyingVariantIterator(in.iterator(), variantFilters, genotypeFilters);
-
- final VCFHeader header = in.getFileHeader();
- // If the user is writing to a .bcf or .vcf, VariantContextBuilderWriter requires a Sequence Dictionary. Make sure that the
- // Input VCF has one.
- final VariantContextWriterBuilder variantContextWriterBuilder = new VariantContextWriterBuilder();
- if (isVcfOrBcf(OUTPUT)) {
- final SAMSequenceDictionary sequenceDictionary = header.getSequenceDictionary();
- if (sequenceDictionary == null) {
- throw new PicardException("The input vcf must have a sequence dictionary in order to create indexed vcf or bcfs.");
- }
- variantContextWriterBuilder.setReferenceDictionary(sequenceDictionary);
- }
- final VariantContextWriter out = variantContextWriterBuilder.setOutputFile(OUTPUT).build();
- header.addMetaDataLine(new VCFFilterHeaderLine("AllGtsFiltered", "Site filtered out because all genotypes are filtered out."));
- header.addMetaDataLine(new VCFFormatHeaderLine("FT", VCFHeaderLineCount.UNBOUNDED, VCFHeaderLineType.String, "Genotype filters."));
- for (final VariantFilter filter : variantFilters) {
- for (final VCFFilterHeaderLine line : filter.headerLines()) {
- header.addMetaDataLine(line);
- }
- }
-
- out.writeHeader(in.getFileHeader());
-
- while (iterator.hasNext()) {
- out.add(iterator.next());
+ VCFFileReader in = null;
+ VariantContextWriter out = null;
+ try {// try/finally used to close 'in' and 'out'
+ in = new VCFFileReader(INPUT, false);
+ final List<VariantFilter> variantFilters = new ArrayList<VariantFilter>(4);
+ variantFilters.add(new AlleleBalanceFilter(MIN_AB));
+ variantFilters.add(new FisherStrandFilter(MAX_FS));
+ variantFilters.add(new QdFilter(MIN_QD));
+ if( JAVASCRIPT_FILE != null) {
+ try {
+ variantFilters.add(new VariantContextJavascriptFilter(JAVASCRIPT_FILE, in.getFileHeader()));
+ } catch(final IOException error) {
+ throw new PicardException("javascript-related error", error);
+ }
+ }
+ final List<GenotypeFilter> genotypeFilters = CollectionUtil.makeList(new GenotypeQualityFilter(MIN_GQ), new DepthFilter(MIN_DP));
+ @SuppressWarnings("resource")
+ final FilterApplyingVariantIterator iterator = new FilterApplyingVariantIterator(in.iterator(), variantFilters, genotypeFilters);
+
+ final VCFHeader header = in.getFileHeader();
+ // If the user is writing to a .bcf or .vcf, VariantContextBuilderWriter requires a Sequence Dictionary. Make sure that the
+ // Input VCF has one.
+ final VariantContextWriterBuilder variantContextWriterBuilder = new VariantContextWriterBuilder();
+ if (isVcfOrBcf(OUTPUT)) {
+ final SAMSequenceDictionary sequenceDictionary = header.getSequenceDictionary();
+ if (sequenceDictionary == null) {
+ throw new PicardException("The input vcf must have a sequence dictionary in order to create indexed vcf or bcfs.");
+ }
+ variantContextWriterBuilder.setReferenceDictionary(sequenceDictionary);
+ }
+ out = variantContextWriterBuilder.setOutputFile(OUTPUT).build();
+ header.addMetaDataLine(new VCFFilterHeaderLine("AllGtsFiltered", "Site filtered out because all genotypes are filtered out."));
+ header.addMetaDataLine(new VCFFormatHeaderLine("FT", VCFHeaderLineCount.UNBOUNDED, VCFHeaderLineType.String, "Genotype filters."));
+ for (final VariantFilter filter : variantFilters) {
+ for (final VCFFilterHeaderLine line : filter.headerLines()) {
+ header.addMetaDataLine(line);
+ }
+ }
+
+ out.writeHeader(in.getFileHeader());
+
+ while (iterator.hasNext()) {
+ out.add(iterator.next());
+ }
+ return 0;
+ } finally {
+ CloserUtil.close(out);
+ CloserUtil.close(in);
}
-
- out.close();
- in.close();
- return 0;
}
private boolean isVcfOrBcf(final File file) {
final String fileName = file.getName();
return fileName.endsWith(".vcf") || fileName.endsWith(".bcf");
}
+
+ /** Javascript filter implementing VariantFilter */
+ private static class VariantContextJavascriptFilter
+ extends JavascriptVariantFilter
+ implements VariantFilter {
+ /** filter name */
+ private final String filterName;
+ /** script file */
+ private final File scriptFile;
+
+ private VariantContextJavascriptFilter(final File scriptFile, final VCFHeader header) throws IOException {
+ super(scriptFile, header);
+ this.scriptFile = scriptFile;
+ /* create filter name using file basename */
+ String fname = IOUtil.basename(scriptFile);
+ if(fname.isEmpty()) fname="JSFILTER";
+ this.filterName = fname;
+ }
+
+ /**
+ * returns the filterName if the javascript doesn't accept the variant ,
+ * null otherwise
+ */
+ @Override
+ public String filter(final VariantContext ctx) {
+ return (super.accept(ctx) ? null : this.filterName );
+ }
+
+ @Override
+ public List<VCFFilterHeaderLine> headerLines() {
+ return CollectionUtil.makeList(
+ new VCFFilterHeaderLine(this.filterName, "Variant Filtered by Javascript file " + this.scriptFile));
+ }
+ }
}
diff --git a/src/java/picard/vcf/processor/VcfFileSegment.java b/src/java/picard/vcf/processor/VcfFileSegment.java
index 104aabb..ff0ca4e 100644
--- a/src/java/picard/vcf/processor/VcfFileSegment.java
+++ b/src/java/picard/vcf/processor/VcfFileSegment.java
@@ -52,7 +52,7 @@ public abstract class VcfFileSegment {
return new SequenceSizedChunk(sequence, vcf);
}
- static class SequenceSizedChunk extends VcfFileSegment {
+ static final class SequenceSizedChunk extends VcfFileSegment {
final SAMSequenceRecord sequence;
final File vcf;
diff --git a/src/java/picard/vcf/processor/VcfFileSegmentGenerator.java b/src/java/picard/vcf/processor/VcfFileSegmentGenerator.java
index e8a639e..8955883 100644
--- a/src/java/picard/vcf/processor/VcfFileSegmentGenerator.java
+++ b/src/java/picard/vcf/processor/VcfFileSegmentGenerator.java
@@ -118,7 +118,7 @@ public abstract class VcfFileSegmentGenerator {
*
* @author mccowan
*/
- static class WidthLimitingDecorator extends VcfFileSegmentGenerator {
+ static final class WidthLimitingDecorator extends VcfFileSegmentGenerator {
final VcfFileSegmentGenerator underlyingStrategy;
final long width;
@@ -135,7 +135,7 @@ public abstract class VcfFileSegmentGenerator {
* The thing that does the work; accepts a {@link VcfFileSegment} (produced by the parent {@link VcfFileSegmentGenerator}) and breaks
* it down into subsegments.
*/
- private class VcfFileSegmentSubdivider implements Iterable<VcfFileSegment> {
+ private final class VcfFileSegmentSubdivider implements Iterable<VcfFileSegment> {
final VcfFileSegment basis;
private VcfFileSegmentSubdivider(final VcfFileSegment basis) {
diff --git a/src/tests/java/picard/analysis/CollectAlignmentSummaryMetricsTest.java b/src/tests/java/picard/analysis/CollectAlignmentSummaryMetricsTest.java
index 11b1fc4..58e2da9 100644
--- a/src/tests/java/picard/analysis/CollectAlignmentSummaryMetricsTest.java
+++ b/src/tests/java/picard/analysis/CollectAlignmentSummaryMetricsTest.java
@@ -28,6 +28,7 @@ import htsjdk.samtools.metrics.MetricsFile;
import org.testng.Assert;
import org.testng.annotations.Test;
import picard.cmdline.CommandLineProgramTest;
+import picard.util.TestNGUtil;
import java.io.File;
import java.io.FileReader;
@@ -524,7 +525,10 @@ public class CollectAlignmentSummaryMetricsTest extends CommandLineProgramTest {
for (final AlignmentSummaryMetrics metrics : output.getMetrics()) {
if (metrics.CATEGORY == AlignmentSummaryMetrics.Category.FIRST_OF_PAIR) {
- Assert.assertEquals(metrics.PCT_CHIMERAS, 0.8);
+ TestNGUtil.compareDoubleWithAccuracy(metrics.PCT_CHIMERAS, 5D / 6, 0.0001);
+ }
+ if (metrics.CATEGORY == AlignmentSummaryMetrics.Category.SECOND_OF_PAIR) {
+ TestNGUtil.compareDoubleWithAccuracy(metrics.PCT_CHIMERAS, 3D / 6, 0.0001);
}
}
}
diff --git a/src/tests/java/picard/cmdline/CommandLineParserTest.java b/src/tests/java/picard/cmdline/CommandLineParserTest.java
index f136d08..4a78ff3 100644
--- a/src/tests/java/picard/cmdline/CommandLineParserTest.java
+++ b/src/tests/java/picard/cmdline/CommandLineParserTest.java
@@ -29,7 +29,11 @@ import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import picard.cmdline.programgroups.Testing;
+import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -977,4 +981,162 @@ public class CommandLineParserTest {
Assert.assertTrue(propsSet.STRING3.equals("String3Supplied"));
Assert.assertTrue(((StaticParent) propsSet).STRING3.equals("String3Supplied"));
}
+
+
+ @DataProvider(name = "testHtmlEscapeData")
+ public Object[][] testHtmlEscapeData() {
+ final List<Object[]> retval = new ArrayList<>();
+
+ retval.add(new Object[]{"<", "<"});
+ retval.add(new Object[]{"x<y", "x<y"});
+ retval.add(new Object[]{"x<y<z", "x<y<z"});
+ retval.add(new Object[]{"\n", "<p>"});
+ retval.add(new Object[]{"<html> x<y </html> y< <strong> x </strong>","<html> x<y </html> y< <strong> x </strong>"});
+
+ return retval.toArray(new Object[0][]);
+ }
+
+// @Test(dataProvider = "testHtmlEscapeData")
+// public void testHtmlEscape(final String text, final String expected) {
+// Assert.assertEquals(CommandLineParser.htmlEscape(text), expected, "problems");
+// }
+
+ @Test(dataProvider = "testHtmlEscapeData")
+ public void testHtmlUnescape(final String expected, final String html) {
+ Assert.assertEquals(CommandLineParser.htmlUnescape(html), expected, "problems");
+ }
+
+ @DataProvider(name = "testHTMLConverter")
+ public Object[][] testHTMLConverterData() {
+ final List<Object[]> retval = new ArrayList<>();
+
+ retval.add(new Object[]{"hello", "hello"});
+ retval.add(new Object[]{"", ""});
+ retval.add(new Object[]{"hi</th>bye", "hi\tbye"});
+ retval.add(new Object[]{"hi<th>bye", "hibye"});
+ retval.add(new Object[]{"hi<li>bye", "hi - bye"});
+ retval.add(new Object[]{"hi<NOT_A_REAL_TAG>bye", "hibye"});
+ retval.add(new Object[]{"</h4><pre>", "\n\n"});
+ retval.add(new Object[]{"<a href=\"http://go.here.org\"> string</ a >", " string (http://go.here.org)"});
+ retval.add(new Object[]{"<a href=\"http://go.here.org\" > string</ a>", " string (http://go.here.org)"});
+ retval.add(new Object[]{"< a href=\"http://go.here.org\"> string<a />", " string (http://go.here.org)"});
+
+
+ //for some reason, the next test seems to break intelliJ, but it works on the commandline
+ retval.add(new Object[]{"hi</li>bye", "hi\nbye"});
+
+ retval.add(new Object[]{"Using read outputs from high throughput sequencing (HTS) technologies, this tool provides " +
+ "metrics regarding the quality of read alignments to a reference sequence, as well as the proportion of the reads " +
+ "that passed machine signal-to-noise threshold quality filters (Illumina)." +
+ "<h4>Usage example:</h4>" +
+ "<pre>" +
+ " java -jar picard.jar CollectAlignmentSummaryMetrics \\<br />" +
+ " R=reference_sequence.fasta \\<br />" +
+ " I=input.bam \\<br />" +
+ " O=output.txt" +
+ "</pre>" +
+ "Please see <a href='http://broadinstitute.github.io/picard/picard-metric-definitions.html#AlignmentSummaryMetrics'>" +
+ "the AlignmentSummaryMetrics documentation</a> for detailed explanations of each metric. <br /> <br />" +
+ "Additional information about Illumina's quality filters can be found in the following documents on the Illumina website:" +
+ "<ul><li><a href=\"http://support.illumina.com/content/dam/illumina-marketing/documents/products/technotes/hiseq-x-percent-pf-technical-note-770-2014-043.pdf\">" +
+ "hiseq-x-percent-pf-technical-note</a></li>" +
+ "<li><a href=\"http://support.illumina.com/content/dam/illumina-support/documents/documentation/system_documentation/hiseqx/hiseq-x-system-guide-15050091-d.pdf\">" +
+ "hiseq-x-system-guide</a></li></ul>" +
+ "<hr />",
+
+ "Using read outputs from high throughput sequencing (HTS) technologies, this tool provides " +
+ "metrics regarding the quality of read alignments to a reference sequence, as well as the proportion of the reads " +
+ "that passed machine signal-to-noise threshold quality filters (Illumina)." +
+ "\nUsage example:\n" +
+ "\n" +
+ " java -jar picard.jar CollectAlignmentSummaryMetrics \\\n" +
+ " R=reference_sequence.fasta \\\n" +
+ " I=input.bam \\\n" +
+ " O=output.txt" +
+ "\n" +
+ "Please see the AlignmentSummaryMetrics documentation (http://broadinstitute.github.io/picard/picard-metric-definitions.html#AlignmentSummaryMetrics) for detailed explanations of each metric. \n \n" +
+ "Additional information about Illumina's quality filters can be found in the following documents on the Illumina website:" +
+ "\n" +
+ " - hiseq-x-percent-pf-technical-note (http://support.illumina.com/content/dam/illumina-marketing/documents/products/technotes/hiseq-x-percent-pf-technical-note-770-2014-043.pdf)\n" +
+ " - hiseq-x-system-guide (http://support.illumina.com/content/dam/illumina-support/documents/documentation/system_documentation/hiseqx/hiseq-x-system-guide-15050091-d.pdf)\n\n" +
+ "\n"});
+
+ return retval.toArray(new Object[0][]);
+ }
+
+ @Test(dataProvider = "testHTMLConverter")
+ public void testHTMLConverter(String input, String expected) {
+ final String converted = CommandLineParser.convertFromHtml(input);
+ Assert.assertEquals(converted, expected, "common part:\"" + expected.substring(0, lengthOfCommonSubstring(converted, expected)) + "\"\n\n");
+ }
+
+ @CommandLineProgramProperties(
+ usage = TestParserFail.USAGE_SUMMARY + TestParserFail.USAGE_DETAILS,
+ usageShort = TestParserFail.USAGE_SUMMARY,
+ programGroup = Testing.class
+ )
+ protected class TestParserFail extends CommandLineProgram {
+
+ static public final String USAGE_DETAILS = "blah &blah; blah ";
+ static public final String USAGE_SUMMARY = "This tool offers.....";
+
+ @Override
+ protected int doWork() {return 0;}
+ }
+
+ @CommandLineProgramProperties(
+ usage = TestParserSucceed.USAGE_SUMMARY + TestParserSucceed.USAGE_DETAILS,
+ usageShort = TestParserSucceed.USAGE_SUMMARY,
+ programGroup = Testing.class
+ )
+
+ protected class TestParserSucceed extends CommandLineProgram {
+
+ static public final String USAGE_DETAILS = "This is the first row <p>And this is the second";
+ static public final String USAGE_SUMMARY = " X < Y ";
+
+ @Override
+ protected int doWork() {return 0;}
+ }
+
+ @Test(expectedExceptions = AssertionError.class)
+ public void testNonAsciiAssertion() {
+ TestParserFail testparserFail = new TestParserFail();
+ testparserFail.parseArgs(new String[]{});
+
+ PrintStream stream = new PrintStream(new NullOutputStream());
+ testparserFail.getCommandLineParser().usage(stream, true);
+ }
+
+ @Test
+ public void testNonAsciiConverted() {
+ TestParserSucceed testparserSucceed = new TestParserSucceed();
+ testparserSucceed.parseArgs(new String[]{});
+
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ PrintStream stream = new PrintStream(byteArrayOutputStream);
+ testparserSucceed.getCommandLineParser().usage(stream, true);
+
+ String expected = "USAGE: TestParserSucceed [options]\n" +
+ "\n" +
+ "Documentation: http://broadinstitute.github.io/picard/command-line-overview.html#TestParserSucceed\n" +
+ "\n" +
+ " X < Y This is the first row \n" +
+ "And this is the second";
+ Assert.assertEquals(byteArrayOutputStream.toString().substring(0, expected.length()), expected);
+ }
+
+ static private int lengthOfCommonSubstring(String lhs, String rhs) {
+ int i = 0;
+ while (i < Math.min(lhs.length(), rhs.length()) && lhs.charAt(i) == rhs.charAt(i)) i++;
+
+ return i;
+ }
+
+ private class NullOutputStream extends OutputStream {
+ @Override
+ public void write(final int b) throws IOException {
+
+ }
+ }
}
diff --git a/src/tests/java/picard/illumina/CheckIlluminaDirectoryTest.java b/src/tests/java/picard/illumina/CheckIlluminaDirectoryTest.java
index 7828b22..d4de278 100644
--- a/src/tests/java/picard/illumina/CheckIlluminaDirectoryTest.java
+++ b/src/tests/java/picard/illumina/CheckIlluminaDirectoryTest.java
@@ -100,7 +100,7 @@ public class CheckIlluminaDirectoryTest extends CommandLineProgramTest {
dataTypeArgs[i + 5] = "DT=" + dataTypes[i];
}
- if (filterTiles.size() > 0) {
+ if (!filterTiles.isEmpty()) {
final int start = dataTypes.length + 5;
for (int i = start; i < dataTypeArgs.length; i++) {
dataTypeArgs[i] = "T=" + filterTiles.get(i - start);
diff --git a/src/tests/java/picard/sam/FilterSamReadsTest.java b/src/tests/java/picard/sam/FilterSamReadsTest.java
new file mode 100644
index 0000000..c611246
--- /dev/null
+++ b/src/tests/java/picard/sam/FilterSamReadsTest.java
@@ -0,0 +1,77 @@
+/*
+ * The MIT License
+ *
+ * Pierre Lindenbaum - Institut du Thorax - 2016
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package picard.sam;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import htsjdk.samtools.SAMRecordIterator;
+import htsjdk.samtools.SamReader;
+import htsjdk.samtools.SamReaderFactory;
+import picard.cmdline.CommandLineProgramTest;
+
+import java.io.File;
+
+public class FilterSamReadsTest extends CommandLineProgramTest {
+ @Override
+ public String getCommandLineProgramName() {
+ return FilterSamReads.class.getSimpleName();
+ }
+
+ @DataProvider(name = "dataTestJsFilter")
+ public Object[][] dataTestJsFilter() {
+ return new Object[][]{
+ {"testdata/picard/sam/aligned.sam","testdata/picard/sam/FilterSamReads/filterOddStarts.js",3},
+ {"testdata/picard/sam/aligned.sam","testdata/picard/sam/FilterSamReads/filterReadsWithout5primeSoftClip.js", 0}
+ };
+ }
+
+ /**
+ * filters a SAM using a javascript filter
+ */
+ @Test(dataProvider = "dataTestJsFilter")
+ public void testJavaScriptFilters(final String samFilename, final String javascriptFilename,final int expectNumber) throws Exception {
+ // input as SAM file
+ final File inputSam = new File(samFilename);
+ final File javascriptFile = new File(javascriptFilename);
+ //loop over javascript filters
+ final FilterSamReads program = new FilterSamReads();
+ program.INPUT = inputSam;
+ program.OUTPUT = File.createTempFile("FilterSamReads.output.", ".sam");
+ program.OUTPUT.deleteOnExit();
+ program.FILTER = FilterSamReads.Filter.includeJavascript;
+ program.JAVASCRIPT_FILE = javascriptFile;
+ Assert.assertEquals(program.doWork(),0);
+
+ //count reads
+ final SamReader samReader = SamReaderFactory.makeDefault().open(program.OUTPUT);
+ final SAMRecordIterator iter = samReader.iterator();
+ int count = 0;
+ while(iter.hasNext()) { iter.next(); ++ count; }
+ iter.close();
+ samReader.close();
+ Assert.assertEquals(count, expectNumber);
+ }
+ }
diff --git a/src/tests/java/picard/util/BedToIntervalListTest.java b/src/tests/java/picard/util/BedToIntervalListTest.java
index 6ad561e..191bc4b 100644
--- a/src/tests/java/picard/util/BedToIntervalListTest.java
+++ b/src/tests/java/picard/util/BedToIntervalListTest.java
@@ -16,7 +16,7 @@ import java.io.InputStream;
*/
public class BedToIntervalListTest {
- private final String TEST_DATA_DIR = "testdata/picard/util/BedToIntervalListTest";
+ private static final String TEST_DATA_DIR = "testdata/picard/util/BedToIntervalListTest";
private void doTest(final String inputBed, final String header) throws IOException, SAMException {
final File outputFile = File.createTempFile("bed_to_interval_list_test.", ".interval_list");
diff --git a/src/tests/java/picard/util/IntervalListToBedTest.java b/src/tests/java/picard/util/IntervalListToBedTest.java
index 8626d78..03cfeaa 100644
--- a/src/tests/java/picard/util/IntervalListToBedTest.java
+++ b/src/tests/java/picard/util/IntervalListToBedTest.java
@@ -11,7 +11,7 @@ import java.util.List;
* Tests for IntervalListToBed
*/
public class IntervalListToBedTest {
- private final String TEST_DATA_DIR = "testdata/picard/util/";
+ private static final String TEST_DATA_DIR = "testdata/picard/util/";
private final File INTERVAL_LIST = new File(TEST_DATA_DIR, "interval_list_to_bed_test.interval_list");
private final File BED_FILE = new File(TEST_DATA_DIR, "interval_list_to_bed_test.bed");
diff --git a/src/tests/java/picard/vcf/SortVcfsTest.java b/src/tests/java/picard/vcf/SortVcfsTest.java
index c2836e1..7808cb3 100644
--- a/src/tests/java/picard/vcf/SortVcfsTest.java
+++ b/src/tests/java/picard/vcf/SortVcfsTest.java
@@ -10,7 +10,6 @@ import picard.cmdline.CommandLineProgram;
import java.io.File;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
diff --git a/src/tests/java/picard/vcf/UpdateVcfSequenceDictionaryTest.java b/src/tests/java/picard/vcf/UpdateVcfSequenceDictionaryTest.java
index e0c8bed..3f8f4d9 100644
--- a/src/tests/java/picard/vcf/UpdateVcfSequenceDictionaryTest.java
+++ b/src/tests/java/picard/vcf/UpdateVcfSequenceDictionaryTest.java
@@ -23,16 +23,11 @@
*/
package picard.vcf;
-import htsjdk.samtools.SAMSequenceDictionary;
-import htsjdk.samtools.util.CloserUtil;
import htsjdk.samtools.util.IOUtil;
import htsjdk.variant.utils.SAMSequenceDictionaryExtractor;
-import htsjdk.variant.vcf.VCFFileReader;
-import htsjdk.variant.vcf.VCFHeader;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
-import picard.PicardException;
import java.io.File;
diff --git a/src/tests/java/picard/vcf/TestFilterVcf.java b/src/tests/java/picard/vcf/filter/TestFilterVcf.java
similarity index 87%
rename from src/tests/java/picard/vcf/TestFilterVcf.java
rename to src/tests/java/picard/vcf/filter/TestFilterVcf.java
index 306488b..cb9a1cd 100644
--- a/src/tests/java/picard/vcf/TestFilterVcf.java
+++ b/src/tests/java/picard/vcf/filter/TestFilterVcf.java
@@ -23,6 +23,7 @@
*/
package picard.vcf.filter;
+import htsjdk.samtools.util.CloseableIterator;
import htsjdk.samtools.util.CollectionUtil;
import htsjdk.samtools.util.ListMap;
import htsjdk.variant.variantcontext.VariantContext;
@@ -30,8 +31,10 @@ import htsjdk.variant.vcf.VCFFileReader;
import org.testng.Assert;
import org.testng.annotations.Test;
import picard.PicardException;
+import picard.vcf.filter.FilterVcf;
import java.io.File;
+import java.io.PrintWriter;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -43,6 +46,43 @@ public class TestFilterVcf {
private final File INPUT = new File("testdata/picard/vcf/filter/testFiltering.vcf");
private final File BAD_INPUT = new File("testdata/picard/vcf/filter/testFilteringNoSeqDictionary.vcf");
+
+ /* write content of javascript in the returned file */
+ private File quickJavascriptFilter(String content) throws Exception {
+ final File out = File.createTempFile("jsfilter", ".js");
+ out.deleteOnExit();
+ try (final PrintWriter pw = new PrintWriter(out)) {
+ pw.println(content);
+ }
+ return out;
+ }
+
+ @Test
+ public void testJavaScript() throws Exception {
+ final File out = File.createTempFile("filterVcfTestJS.", ".vcf");
+ out.deleteOnExit();
+ final FilterVcf filterer = new FilterVcf();
+ filterer.INPUT = INPUT;
+ filterer.OUTPUT = out;
+ filterer.JAVASCRIPT_FILE = quickJavascriptFilter("variant.getStart()%5 != 0");
+
+ final int retval = filterer.doWork();
+ Assert.assertEquals(retval, 0);
+
+ //count the number of reads
+ final int expectedNumber = 4;
+ int count=0;
+ VCFFileReader in = new VCFFileReader(filterer.OUTPUT, false);
+ CloseableIterator<VariantContext> iter = in.iterator();
+ while(iter.hasNext()) {
+ final VariantContext ctx = iter.next();
+ count += (ctx.isFiltered()?1:0);
+ }
+ iter.close();
+ in.close();
+ Assert.assertEquals(count, expectedNumber);
+ }
+
/** Returns a sorted copy of the supplied set, for safer comparison. */
<T extends Comparable> SortedSet<T> sorted(Set<T> in) { return new TreeSet<T>(in); }
@@ -55,6 +95,7 @@ public class TestFilterVcf {
Assert.fail("Context should not have been filtered: " + ctx.toString());
}
}
+ in.close();
}
/** Tests that sites with a het allele balance < 0.4 are marked as filtered out. */
diff --git a/src/tests/java/picard/vcf/processor/VcfFileSegmentGeneratorTest.java b/src/tests/java/picard/vcf/processor/VcfFileSegmentGeneratorTest.java
index c41eb83..26d25f3 100644
--- a/src/tests/java/picard/vcf/processor/VcfFileSegmentGeneratorTest.java
+++ b/src/tests/java/picard/vcf/processor/VcfFileSegmentGeneratorTest.java
@@ -39,7 +39,7 @@ public class VcfFileSegmentGeneratorTest {
final static Log LOG = Log.getInstance(VcfFileSegmentGeneratorTest.class);
final File VCF_WITH_LOGS_OF_GAPS = new File("testdata/picard/vcf/chunking/multi_allelic_at_10M.vcf");
- final int TEN_MILLION = (int) 10e6;
+ static final int TEN_MILLION = (int) 10e6;
@Test
public void ensureOverlapExclusionTest() {
diff --git a/testdata/picard/sam/FilterSamReads/filterOddStarts.js b/testdata/picard/sam/FilterSamReads/filterOddStarts.js
new file mode 100644
index 0000000..f0007f6
--- /dev/null
+++ b/testdata/picard/sam/FilterSamReads/filterOddStarts.js
@@ -0,0 +1,2 @@
+/** reads mapped and having start%2 = 0 */
+!record.getReadUnmappedFlag() && record.getStart()%2==0
diff --git a/testdata/picard/sam/FilterSamReads/filterReadsWithout5primeSoftClip.js b/testdata/picard/sam/FilterSamReads/filterReadsWithout5primeSoftClip.js
new file mode 100644
index 0000000..4a16340
--- /dev/null
+++ b/testdata/picard/sam/FilterSamReads/filterReadsWithout5primeSoftClip.js
@@ -0,0 +1,10 @@
+/** reads having a soft clip in 5' larger than 2 bases */
+function accept(rec) {
+ if( rec.getReadUnmappedFlag()) return false;
+ var cigar = rec.getCigar();
+ if( cigar == null ) return false;
+ var ce = cigar.getCigarElement(0);
+ return ce.getOperator().name()=="S" && ce.length()>2;
+ }
+
+accept(record);
diff --git a/testdata/picard/sam/summary_alignment_stats_test_chimeras.sam b/testdata/picard/sam/summary_alignment_stats_test_chimeras.sam
index 95143c9..583072e 100644
--- a/testdata/picard/sam/summary_alignment_stats_test_chimeras.sam
+++ b/testdata/picard/sam/summary_alignment_stats_test_chimeras.sam
@@ -8,13 +8,15 @@
@SQ SN:chr7 LN:202
@SQ SN:chr8 LN:202
@RG ID:0 SM:Hi,Momma! LB:whatever PU:me PL:ILLUMINA
-SL-XAV:1:1:0:764#0/1 113 chr1 1 255 6M chr1 10 10 TTCATG &/,&-.
-SL-XAV:1:1:0:764#0/1 177 chr1 10 255 6M chr1 1 10 TTCATG &/,&-.
-SL-XAV:1:1:0:800#0/1 81 chr2 1 255 6M chr2 10 10 TTCATG &/,&-.
-SL-XAV:1:1:0:800#0/1 161 chr2 10 255 6M chr2 1 10 TTCATG &/,&-.
-SL-XAV:1:1:0:877#0/1 97 chr3 1 255 6M chr4 10 10 TTCATG &/,&-.
-SL-XAV:1:1:0:877#0/1 145 chr4 10 255 6M chr3 1 10 TTCATG &/,&-.
-SL-XAV:1:1:0:940#0/1 97 chr5 1 255 6M chr5 10 10 TTCATG &/,&-.
-SL-XAV:1:1:0:940#0/1 145 chr5 10 255 6M chr5 1 10 TTCATG &/,&-.
-SL-XAV:1:1:0:999#0/1 97 chr6 1 255 6M chr5 10 60 TTCATG &/,&-.
-SL-XAV:1:1:0:999#0/1 145 chr6 60 255 6M chr5 1 60 TTCATG &/,&-.
+SL-XAV:1:1:0:764#0/1 0113 chr1 1 255 6M chr1 10 10 TTCATG &/,&-. OT:Z:left pointing
+SL-XAV:1:1:0:764#0/1 0177 chr1 10 255 6M chr1 1 10 TTCATG &/,&-. OT:Z:normal
+SL-XAV:1:1:0:800#0/1 0081 chr2 1 255 6M chr2 10 10 TTCATG &/,&-. OT:Z:outtie
+SL-XAV:1:1:0:800#0/1 00161 chr2 10 255 6M chr2 1 10 TTCATG &/,&-. OT:Z:outtie
+SL-XAV:1:1:0:877#0/1 0097 chr3 1 255 6M chr4 10 10 TTCATG &/,&-. OT:Z:chimeric
+SL-XAV:1:1:0:877#0/1 00145 chr4 10 255 6M chr3 1 10 TTCATG &/,&-. OT:Z:chimeric
+SL-XAV:1:1:0:940#0/1 0097 chr5 1 255 6M chr5 10 10 TTCATG &/,&-. OT:Z:normal
+SL-XAV:1:1:0:940#0/1 00145 chr5 10 255 6M chr5 1 10 TTCATG &/,&-. OT:Z:normal
+SL-XAV:1:1:0:999#0/1 0097 chr6 1 255 6M chr5 10 60 TTCATG &/,&-. OT:Z:chimeric
+SL-XAV:1:1:0:999#0/1 00145 chr6 60 255 6M chr5 1 60 TTCATG &/,&-. OT:Z:chimeric
+SL-XAV:1:1:0:430#0/1 0097 chr7 1 255 6M chr5 10 10 TTCATG &/,&-. OT:Z:hasSa SA:Z:gotSA
+SL-XAV:1:1:0:430#0/1 00145 chr7 10 255 6M chr5 1 10 TTCATG &/,&-. OT:Z:normal
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/picard-tools.git
More information about the debian-med-commit
mailing list