Bringing latest performance updates from the GATK to CMI
This commit is contained in:
commit
6d22f4f737
97
build.xml
97
build.xml
|
|
@ -185,10 +185,7 @@
|
|||
<include name="**/*.class"/>
|
||||
</fileset>
|
||||
|
||||
<patternset id="dependency.mask" includes="*.jar">
|
||||
<exclude name="testng*.jar" />
|
||||
<exclude name="bcel*.jar" />
|
||||
</patternset>
|
||||
<patternset id="dependency.mask" includes="*.jar" />
|
||||
|
||||
<path id="external.dependencies">
|
||||
<fileset dir="${lib.dir}" erroronmissingdir="false">
|
||||
|
|
@ -205,6 +202,16 @@
|
|||
<pathelement location="${scala.classes}" />
|
||||
</path>
|
||||
|
||||
<path id="build.results">
|
||||
<!-- Ensure that GenomeAnalysisTK.jar comes first in the path, as it contains overrides for certain classes in our dependencies -->
|
||||
<pathelement location="${dist.dir}/GenomeAnalysisTK.jar" />
|
||||
<!-- After GenomeAnalysisTK.jar we include all of the other jars in the dist directory -->
|
||||
<fileset dir="${dist.dir}" erroronmissingdir="false">
|
||||
<patternset refid="dependency.mask" />
|
||||
<exclude name="GenomeAnalysisTK.jar" />
|
||||
</fileset>
|
||||
</path>
|
||||
|
||||
<fileset id="external.source.files" dir="${external.dir}" erroronmissingdir="false">
|
||||
<include name="**/*.java" />
|
||||
</fileset>
|
||||
|
|
@ -226,20 +233,20 @@
|
|||
<!-- the path for resources that need to go into the GATK jar;
|
||||
any additional resources should go into this set. -->
|
||||
<path id="gatk.resources">
|
||||
<fileset dir="${basedir}">
|
||||
<include name="${java.public.source.dir}/**/templates/*" />
|
||||
<include name="${java.private.source.dir}/**/templates/*" if="include.private" />
|
||||
<include name="${java.protected.source.dir}/**/templates/*" if="include.protected" />
|
||||
<fileset dir="${java.public.source.dir}">
|
||||
<include name="**/resources/*" />
|
||||
<include name="**/templates/*" />
|
||||
</fileset>
|
||||
<fileset dir="${java.private.source.dir}" erroronmissingdir="false">
|
||||
<include name="**/resources/*" if="include.private" />
|
||||
<include name="**/templates/*" if="include.private" />
|
||||
</fileset>
|
||||
<fileset dir="${java.protected.source.dir}" erroronmissingdir="false">
|
||||
<include name="**/resources/*" if="include.protected" />
|
||||
<include name="**/templates/*" if="include.protected" />
|
||||
</fileset>
|
||||
</path>
|
||||
|
||||
<path id="build.results">
|
||||
<fileset dir="${dist.dir}">
|
||||
<patternset refid="dependency.mask" />
|
||||
</fileset>
|
||||
</path>
|
||||
|
||||
|
||||
<!-- ******************************************************************************** -->
|
||||
<!-- Ivy Retrieve -->
|
||||
<!-- ******************************************************************************** -->
|
||||
|
|
@ -672,6 +679,24 @@
|
|||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="na12878kb.jar" depends="gatk.compile,init.jar">
|
||||
<jar jarfile="${dist.dir}/na12878kb.jar">
|
||||
<fileset dir="${java.classes}">
|
||||
<include name="org/broadinstitute/sting/utils/GenomeLocParser*.class"/>
|
||||
<include name="org/broadinstitute/sting/utils/GenomeLoc.class"/>
|
||||
<include name="org/broadinstitute/sting/utils/HasGenomeLocation.class"/>
|
||||
<include name="org/broadinstitute/sting/utils/BaseUtils.class"/>
|
||||
<include name="org/broadinstitute/sting/utils/Utils.class"/>
|
||||
<include name="org/broadinstitute/sting/utils/exceptions/**/*.class"/>
|
||||
<include name="org/broadinstitute/sting/gatk/walkers/na12878kb/core/**/*.class"/>
|
||||
<include name="net/sf/picard/reference/FastaSequenceFile.class"/>
|
||||
</fileset>
|
||||
<fileset dir="${java.private.source.dir}">
|
||||
<include name="org/broadinstitute/sting/gatk/walkers/na12878kb/core/resources/**/*"/>
|
||||
</fileset>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="gatk.jar" depends="gatk.compile, init.jar, R.script.stage" description="generate the GATK distribution">
|
||||
<jar jarfile="${dist.dir}/GenomeAnalysisTK.jar">
|
||||
<path refid="gatk.resources"/>
|
||||
|
|
@ -1103,15 +1128,10 @@
|
|||
</path>
|
||||
|
||||
<path id="testng.default.classpath">
|
||||
<pathelement location="${java.classes}" />
|
||||
<pathelement location="${scala.classes}" />
|
||||
<path refid="build.results" />
|
||||
<pathelement location="${java.contracts.dir}" />
|
||||
<pathelement location="${java.test.classes}" />
|
||||
<pathelement location="${scala.test.classes}" />
|
||||
<pathelement location="${R.tar.dir}" />
|
||||
<path refid="R.script.source.path" />
|
||||
<pathelement location="${key.dir}" />
|
||||
<path refid="external.dependencies" />
|
||||
</path>
|
||||
|
||||
<!-- Test targets -->
|
||||
|
|
@ -1119,9 +1139,6 @@
|
|||
<target name="test.init.compile">
|
||||
<mkdir dir="${java.test.classes}"/>
|
||||
<mkdir dir="${scala.test.classes}"/>
|
||||
<antcall target="resolve">
|
||||
<param name="ivy.conf" value="test"/>
|
||||
</antcall>
|
||||
</target>
|
||||
|
||||
<target name="test.java.internal.compile" depends="dist,test.init.compile">
|
||||
|
|
@ -1129,10 +1146,8 @@
|
|||
<javac fork="true" memoryMaximumSize="512m" destdir="${java.test.classes}" debug="true" optimize="on" tempdir="${java.io.tmpdir}">
|
||||
<src refid="java.test.source.path" />
|
||||
<classpath>
|
||||
<path refid="external.dependencies" />
|
||||
<pathelement location="${java.classes}"/>
|
||||
<path refid="build.results" />
|
||||
<pathelement location="${java.contracts.dir}"/>
|
||||
<pathelement location="${testng.jar}"/>
|
||||
</classpath>
|
||||
<compilerarg value="-proc:none"/>
|
||||
</javac>
|
||||
|
|
@ -1143,11 +1158,9 @@
|
|||
<javac fork="true" memoryMaximumSize="512m" destdir="${java.test.classes}" debug="true" optimize="on" tempdir="${java.io.tmpdir}" srcdir="${external.dir}">
|
||||
<include name="*/test/**/*.java"/>
|
||||
<classpath>
|
||||
<path refid="external.dependencies" />
|
||||
<path refid="build.results" />
|
||||
<pathelement location="${java.test.classes}"/>
|
||||
<pathelement location="${java.classes}"/>
|
||||
<pathelement location="${java.contracts.dir}"/>
|
||||
<pathelement location="${testng.jar}"/>
|
||||
</classpath>
|
||||
<compilerarg value="-proc:none"/>
|
||||
</javac>
|
||||
|
|
@ -1160,9 +1173,8 @@
|
|||
<scalac fork="true" jvmargs="-Xmx512m" destdir="${scala.test.classes}" deprecation="yes" unchecked="yes">
|
||||
<src refid="scala.test.source.path" />
|
||||
<classpath>
|
||||
<path refid="scala.dependencies"/>
|
||||
<path refid="build.results"/>
|
||||
<pathelement location="${java.test.classes}"/>
|
||||
<pathelement location="${testng.jar}"/>
|
||||
</classpath>
|
||||
</scalac>
|
||||
</target>
|
||||
|
|
@ -1369,14 +1381,13 @@
|
|||
|
||||
<!-- Fast test target that cuts major corners for speed. Requires that a full build has been done first. Java-only, single test class only -->
|
||||
<!-- Usage: ant fasttest -Dsingle=TestClass -->
|
||||
<target name="fasttest" depends="init.javaonly,init,test.init">
|
||||
<target name="fasttest" depends="init.javaonly,init">
|
||||
<condition property="not.clean">
|
||||
<and>
|
||||
<available file="${build.dir}" />
|
||||
<available file="${lib.dir}" />
|
||||
<available file="${dist.dir}" />
|
||||
<available file="${java.test.classes}" />
|
||||
<available file="${testng.jar}" />
|
||||
</and>
|
||||
</condition>
|
||||
<fail message="fasttest requires a NON-CLEAN working directory (INCLUDING test classes). Do a full test build using ant test.compile first." unless="not.clean" />
|
||||
|
|
@ -1394,13 +1405,27 @@
|
|||
<javac fork="true" memoryMaximumSize="512m" destdir="${java.test.classes}" debug="true" optimize="on" tempdir="${java.io.tmpdir}">
|
||||
<src refid="java.test.source.path" />
|
||||
<classpath>
|
||||
<path refid="external.dependencies" />
|
||||
<pathelement location="${java.classes}"/>
|
||||
<pathelement location="${testng.jar}"/>
|
||||
<path refid="external.dependencies" />
|
||||
</classpath>
|
||||
<compilerarg value="-proc:none"/>
|
||||
</javac>
|
||||
|
||||
<!-- fasttest uses the unpackaged class files in its test classpath to avoid having to rebuild the jars in dist/ -->
|
||||
<path id="testng.fasttest.classpath">
|
||||
<pathelement location="${java.classes}" />
|
||||
<pathelement location="${scala.classes}" />
|
||||
<pathelement location="${java.contracts.dir}" />
|
||||
<pathelement location="${java.test.classes}" />
|
||||
<pathelement location="${scala.test.classes}" />
|
||||
<pathelement location="${R.tar.dir}" />
|
||||
<path refid="R.script.source.path" />
|
||||
<pathelement location="${key.dir}" />
|
||||
<path refid="external.dependencies" />
|
||||
<path refid="java.source.path" /> <!-- Terrible hack to allow fasttest to see resource files stored in the source tree -->
|
||||
</path>
|
||||
<property name="testng.classpath" value="testng.fasttest.classpath" />
|
||||
|
||||
<run-test testtype="${single}" outputdir="${report}/${single}" runfailed="false"/>
|
||||
</target>
|
||||
</project>
|
||||
|
|
|
|||
11
ivy.xml
11
ivy.xml
|
|
@ -24,11 +24,8 @@
|
|||
|
||||
<ivy-module version="1.0">
|
||||
<info organisation="org.broadinstitute" module="Sting"/>
|
||||
<configurations defaultconfmapping="test->default">
|
||||
<configurations>
|
||||
<conf name="default" description="the core dependencies for the GATK"/>
|
||||
<conf name="test" extends="default" description="external dependencies used for testing and metrics"/>
|
||||
<conf name="scala" extends="default" description="the dependencies for scala"/>
|
||||
<conf name="queue" extends="scala" description="the dependencies for Queue"/>
|
||||
</configurations>
|
||||
<dependencies defaultconf="default">
|
||||
<dependency org="net.sf" name="sam" rev="latest.integration"/>
|
||||
|
|
@ -83,9 +80,9 @@
|
|||
<dependency org="org.scala-lang" name="scala-library" rev="2.9.2"/>
|
||||
|
||||
<!-- testing and evaluation dependencies -->
|
||||
<dependency org="org.testng" name="testng" rev="5.14.1" conf="test"/>
|
||||
<dependency org="org.uncommons" name="reportng" rev="1.1.2" conf="test"/>
|
||||
<dependency org="com.google.code.caliper" name="caliper" rev="1.0-SNAPSHOT" conf="test"/>
|
||||
<dependency org="org.testng" name="testng" rev="5.14.1"/>
|
||||
<dependency org="org.uncommons" name="reportng" rev="1.1.2"/>
|
||||
<dependency org="com.google.code.caliper" name="caliper" rev="1.0-SNAPSHOT"/>
|
||||
|
||||
<!-- Contracts for Java and dependencies -->
|
||||
<dependency org="com.google.code.cofoja" name="cofoja" rev="1.0-r139"/>
|
||||
|
|
|
|||
|
|
@ -30,12 +30,16 @@ import com.google.java.contract.Requires;
|
|||
import net.sf.samtools.Cigar;
|
||||
import net.sf.samtools.CigarElement;
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.broadinstitute.sting.gatk.walkers.annotator.VariantAnnotatorEngine;
|
||||
import org.broadinstitute.sting.gatk.walkers.genotyper.UnifiedGenotyperEngine;
|
||||
import org.broadinstitute.sting.utils.*;
|
||||
import org.broadinstitute.sting.utils.collections.Pair;
|
||||
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||
import org.broadinstitute.sting.utils.genotyper.PerReadAlleleLikelihoodMap;
|
||||
import org.broadinstitute.sting.utils.sam.GATKSAMRecord;
|
||||
import org.broadinstitute.sting.utils.variantcontext.*;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.*;
|
||||
|
||||
public class GenotypingEngine {
|
||||
|
|
@ -43,23 +47,27 @@ public class GenotypingEngine {
|
|||
private final boolean DEBUG;
|
||||
private final static List<Allele> noCall = new ArrayList<Allele>(); // used to noCall all genotypes until the exact model is applied
|
||||
private final static Allele SYMBOLIC_UNASSEMBLED_EVENT_ALLELE = Allele.create("<UNASSEMBLED_EVENT>", false);
|
||||
private final VariantAnnotatorEngine annotationEngine;
|
||||
|
||||
public GenotypingEngine( final boolean DEBUG ) {
|
||||
public GenotypingEngine( final boolean DEBUG, final VariantAnnotatorEngine annotationEngine ) {
|
||||
this.DEBUG = DEBUG;
|
||||
this.annotationEngine = annotationEngine;
|
||||
noCall.add(Allele.NO_CALL);
|
||||
}
|
||||
|
||||
// BUGBUG: Create a class to hold this complicated return type
|
||||
@Requires({"refLoc.containsP(activeRegionWindow)", "haplotypes.size() > 0"})
|
||||
public List<Pair<VariantContext, Map<Allele, List<Haplotype>>>> assignGenotypeLikelihoodsAndCallIndependentEvents( final UnifiedGenotyperEngine UG_engine,
|
||||
final List<Haplotype> haplotypes,
|
||||
final byte[] ref,
|
||||
final GenomeLoc refLoc,
|
||||
final GenomeLoc activeRegionWindow,
|
||||
final GenomeLocParser genomeLocParser,
|
||||
final List<VariantContext> activeAllelesToGenotype ) {
|
||||
public List<VariantContext> assignGenotypeLikelihoodsAndCallIndependentEvents( final UnifiedGenotyperEngine UG_engine,
|
||||
final List<Haplotype> haplotypes,
|
||||
final List<String> samples,
|
||||
final Map<String, PerReadAlleleLikelihoodMap> haplotypeReadMap,
|
||||
final Map<String, ArrayList<GATKSAMRecord>> perSampleFilteredReadList,
|
||||
final byte[] ref,
|
||||
final GenomeLoc refLoc,
|
||||
final GenomeLoc activeRegionWindow,
|
||||
final GenomeLocParser genomeLocParser,
|
||||
final List<VariantContext> activeAllelesToGenotype ) {
|
||||
|
||||
final ArrayList<Pair<VariantContext, Map<Allele, List<Haplotype>>>> returnCalls = new ArrayList<Pair<VariantContext, Map<Allele, List<Haplotype>>>>();
|
||||
final List<VariantContext> returnCalls = new ArrayList<VariantContext>();
|
||||
final boolean in_GGA_mode = !activeAllelesToGenotype.isEmpty();
|
||||
|
||||
// Using the cigar from each called haplotype figure out what events need to be written out in a VCF file
|
||||
|
|
@ -79,8 +87,8 @@ public class GenotypingEngine {
|
|||
}
|
||||
|
||||
cleanUpSymbolicUnassembledEvents( haplotypes );
|
||||
if( !in_GGA_mode && haplotypes.get(0).getSampleKeySet().size() >= 10 ) { // if not in GGA mode and have at least 10 samples try to create MNP and complex events by looking at LD structure
|
||||
mergeConsecutiveEventsBasedOnLD( haplotypes, startPosKeySet, ref, refLoc );
|
||||
if( !in_GGA_mode && samples.size() >= 10 ) { // if not in GGA mode and have at least 10 samples try to create MNP and complex events by looking at LD structure
|
||||
mergeConsecutiveEventsBasedOnLD( haplotypes, samples, haplotypeReadMap, startPosKeySet, ref, refLoc );
|
||||
}
|
||||
if( in_GGA_mode ) {
|
||||
for( final VariantContext compVC : activeAllelesToGenotype ) {
|
||||
|
|
@ -90,7 +98,7 @@ public class GenotypingEngine {
|
|||
|
||||
// Walk along each position in the key set and create each event to be outputted
|
||||
for( final int loc : startPosKeySet ) {
|
||||
if( loc >= activeRegionWindow.getStart() && loc <= activeRegionWindow.getStop() ) {
|
||||
if( loc >= activeRegionWindow.getStart() && loc <= activeRegionWindow.getStop() ) { // genotyping an event inside this active region
|
||||
final ArrayList<VariantContext> eventsAtThisLoc = new ArrayList<VariantContext>(); // the overlapping events to merge into a common reference view
|
||||
final ArrayList<String> priorityList = new ArrayList<String>(); // used to merge overlapping events into common reference view
|
||||
|
||||
|
|
@ -153,7 +161,7 @@ public class GenotypingEngine {
|
|||
if( mergedVC == null ) { continue; }
|
||||
|
||||
// let's update the Allele keys in the mapper because they can change after merging when there are complex events
|
||||
Map<Allele, List<Haplotype>> updatedAlleleMapper = new HashMap<Allele, List<Haplotype>>(alleleMapper.size());
|
||||
final Map<Allele, List<Haplotype>> updatedAlleleMapper = new HashMap<Allele, List<Haplotype>>(alleleMapper.size());
|
||||
for ( int i = 0; i < mergedVC.getNAlleles(); i++ ) {
|
||||
final Allele oldAllele = alleleOrdering.get(i);
|
||||
final Allele newAllele = mergedVC.getAlleles().get(i);
|
||||
|
|
@ -167,12 +175,14 @@ public class GenotypingEngine {
|
|||
//System.out.println("Event/haplotype allele mapping = " + alleleMapper);
|
||||
}
|
||||
|
||||
final Map<String, PerReadAlleleLikelihoodMap> alleleReadMap = convertHaplotypeReadMapToAlleleReadMap( haplotypeReadMap, alleleMapper, UG_engine.getUAC().CONTAMINATION_FRACTION, UG_engine.getUAC().contaminationLog );
|
||||
|
||||
// Grab the genotype likelihoods from the appropriate places in the haplotype likelihood matrix -- calculation performed independently per sample
|
||||
final GenotypesContext genotypes = GenotypesContext.create(haplotypes.get(0).getSampleKeySet().size());
|
||||
for( final String sample : haplotypes.get(0).getSampleKeySet() ) { // BUGBUG: assume all haplotypes saw the same samples
|
||||
final GenotypesContext genotypes = GenotypesContext.create(samples.size());
|
||||
for( final String sample : samples ) {
|
||||
final int numHaplotypes = alleleMapper.size();
|
||||
final double[] genotypeLikelihoods = new double[numHaplotypes * (numHaplotypes+1) / 2];
|
||||
final double[][] haplotypeLikelihoodMatrix = LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods(sample, alleleMapper, alleleOrdering);
|
||||
final double[][] haplotypeLikelihoodMatrix = LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods(sample, alleleReadMap, alleleOrdering);
|
||||
int glIndex = 0;
|
||||
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
||||
for( int jjj = 0; jjj <= iii; jjj++ ) {
|
||||
|
|
@ -181,27 +191,57 @@ public class GenotypingEngine {
|
|||
}
|
||||
genotypes.add( new GenotypeBuilder(sample).alleles(noCall).PL(genotypeLikelihoods).make() );
|
||||
}
|
||||
VariantContext call = UG_engine.calculateGenotypes(new VariantContextBuilder(mergedVC).genotypes(genotypes).make(), UG_engine.getUAC().GLmodel);
|
||||
final VariantContext call = UG_engine.calculateGenotypes(new VariantContextBuilder(mergedVC).genotypes(genotypes).make(), UG_engine.getUAC().GLmodel);
|
||||
if( call != null ) {
|
||||
if( call.getAlleles().size() != mergedVC.getAlleles().size() ) { // some alleles were removed so reverseTrimming might be necessary!
|
||||
final VariantContext vcCallTrim = VariantContextUtils.reverseTrimAlleles(call);
|
||||
// also, need to update the allele -> haplotype mapping
|
||||
final HashMap<Allele, List<Haplotype>> alleleHashMapTrim = new HashMap<Allele, List<Haplotype>>();
|
||||
for( int iii = 0; iii < vcCallTrim.getAlleles().size(); iii++ ) { // BUGBUG: this is assuming that the original and trimmed alleles maintain the same ordering in the VC
|
||||
alleleHashMapTrim.put(vcCallTrim.getAlleles().get(iii), alleleMapper.get(call.getAlleles().get(iii)));
|
||||
}
|
||||
final Map<String, PerReadAlleleLikelihoodMap> stratifiedReadMap = filterToOnlyOverlappingReads( genomeLocParser, alleleReadMap, perSampleFilteredReadList, call );
|
||||
VariantContext annotatedCall = annotationEngine.annotateContext(stratifiedReadMap, call);
|
||||
|
||||
call = vcCallTrim;
|
||||
alleleMapper = alleleHashMapTrim;
|
||||
if( annotatedCall.getAlleles().size() != mergedVC.getAlleles().size() ) { // some alleles were removed so reverseTrimming might be necessary!
|
||||
annotatedCall = VariantContextUtils.reverseTrimAlleles(annotatedCall);
|
||||
}
|
||||
|
||||
returnCalls.add( new Pair<VariantContext, Map<Allele,List<Haplotype>>>(call, alleleMapper) );
|
||||
returnCalls.add( annotatedCall );
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnCalls;
|
||||
}
|
||||
|
||||
private static Map<String, PerReadAlleleLikelihoodMap> filterToOnlyOverlappingReads( final GenomeLocParser parser,
|
||||
final Map<String, PerReadAlleleLikelihoodMap> perSampleReadMap,
|
||||
final Map<String, ArrayList<GATKSAMRecord>> perSampleFilteredReadList,
|
||||
final VariantContext call ) {
|
||||
|
||||
final Map<String, PerReadAlleleLikelihoodMap> returnMap = new HashMap<String, PerReadAlleleLikelihoodMap>();
|
||||
final GenomeLoc callLoc = parser.createGenomeLoc(call);
|
||||
for( final Map.Entry<String, PerReadAlleleLikelihoodMap> sample : perSampleReadMap.entrySet() ) {
|
||||
final PerReadAlleleLikelihoodMap likelihoodMap = PerReadAlleleLikelihoodMap.getBestAvailablePerReadAlleleLikelihoodMap();
|
||||
|
||||
for( final Map.Entry<GATKSAMRecord,Map<Allele,Double>> mapEntry : sample.getValue().getLikelihoodReadMap().entrySet() ) {
|
||||
// only count the read if it overlaps the event, otherwise it is not added to the output read list at all
|
||||
if( callLoc.overlapsP(parser.createGenomeLoc(mapEntry.getKey())) ) { // BUGBUG: This uses alignment start and stop, NOT soft start and soft end...
|
||||
for( final Map.Entry<Allele,Double> alleleDoubleEntry : mapEntry.getValue().entrySet() ) {
|
||||
likelihoodMap.add(mapEntry.getKey(), alleleDoubleEntry.getKey(), alleleDoubleEntry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add all filtered reads to the NO_CALL list because they weren't given any likelihoods
|
||||
for( final GATKSAMRecord read : perSampleFilteredReadList.get(sample.getKey()) ) {
|
||||
// only count the read if it overlaps the event, otherwise it is not added to the output read list at all
|
||||
if( callLoc.overlapsP(parser.createGenomeLoc(read)) ) {
|
||||
for( final Allele allele : call.getAlleles() ) {
|
||||
likelihoodMap.add(read, allele, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
returnMap.put(sample.getKey(), likelihoodMap);
|
||||
}
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
|
||||
protected static void cleanUpSymbolicUnassembledEvents( final List<Haplotype> haplotypes ) {
|
||||
final ArrayList<Haplotype> haplotypesToRemove = new ArrayList<Haplotype>();
|
||||
for( final Haplotype h : haplotypes ) {
|
||||
|
|
@ -221,7 +261,41 @@ public class GenotypingEngine {
|
|||
haplotypes.removeAll(haplotypesToRemove);
|
||||
}
|
||||
|
||||
protected void mergeConsecutiveEventsBasedOnLD( final List<Haplotype> haplotypes, final TreeSet<Integer> startPosKeySet, final byte[] ref, final GenomeLoc refLoc ) {
|
||||
// BUGBUG: ugh, too complicated
|
||||
protected Map<String, PerReadAlleleLikelihoodMap> convertHaplotypeReadMapToAlleleReadMap( final Map<String, PerReadAlleleLikelihoodMap> haplotypeReadMap,
|
||||
final Map<Allele, List<Haplotype>> alleleMapper,
|
||||
final double downsamplingFraction,
|
||||
final PrintStream downsamplingLog ) {
|
||||
|
||||
final Map<String, PerReadAlleleLikelihoodMap> alleleReadMap = new HashMap<String, PerReadAlleleLikelihoodMap>();
|
||||
for( final Map.Entry<String, PerReadAlleleLikelihoodMap> haplotypeReadMapEntry : haplotypeReadMap.entrySet() ) { // for each sample
|
||||
final PerReadAlleleLikelihoodMap perReadAlleleLikelihoodMap = PerReadAlleleLikelihoodMap.getBestAvailablePerReadAlleleLikelihoodMap();
|
||||
for( final Map.Entry<Allele, List<Haplotype>> alleleMapperEntry : alleleMapper.entrySet() ) { // for each output allele
|
||||
final List<Haplotype> mappedHaplotypes = alleleMapperEntry.getValue();
|
||||
for( final Map.Entry<GATKSAMRecord, Map<Allele,Double>> readEntry : haplotypeReadMapEntry.getValue().getLikelihoodReadMap().entrySet() ) { // for each read
|
||||
double maxLikelihood = Double.NEGATIVE_INFINITY;
|
||||
for( final Map.Entry<Allele,Double> alleleDoubleEntry : readEntry.getValue().entrySet() ) { // for each input allele
|
||||
if( mappedHaplotypes.contains( new Haplotype(alleleDoubleEntry.getKey().getBases())) ) { // exact match of haplotype base string
|
||||
maxLikelihood = Math.max( maxLikelihood, alleleDoubleEntry.getValue() );
|
||||
}
|
||||
}
|
||||
perReadAlleleLikelihoodMap.add(readEntry.getKey(), alleleMapperEntry.getKey(), maxLikelihood);
|
||||
}
|
||||
}
|
||||
perReadAlleleLikelihoodMap.performPerAlleleDownsampling(downsamplingFraction, downsamplingLog); // perform contamination downsampling
|
||||
alleleReadMap.put(haplotypeReadMapEntry.getKey(), perReadAlleleLikelihoodMap);
|
||||
}
|
||||
|
||||
return alleleReadMap;
|
||||
}
|
||||
|
||||
protected void mergeConsecutiveEventsBasedOnLD( final List<Haplotype> haplotypes,
|
||||
final List<String> samples,
|
||||
final Map<String, PerReadAlleleLikelihoodMap> haplotypeReadMap,
|
||||
final TreeSet<Integer> startPosKeySet,
|
||||
final byte[] ref,
|
||||
final GenomeLoc refLoc ) {
|
||||
|
||||
final int MAX_SIZE_TO_COMBINE = 15;
|
||||
final double MERGE_EVENTS_R2_THRESHOLD = 0.95;
|
||||
if( startPosKeySet.size() <= 1 ) { return; }
|
||||
|
|
@ -265,12 +339,13 @@ public class GenotypingEngine {
|
|||
}
|
||||
}
|
||||
// count up the co-occurrences of the events for the R^2 calculation
|
||||
final ArrayList<Haplotype> haplotypeList = new ArrayList<Haplotype>();
|
||||
haplotypeList.add(h);
|
||||
for( final String sample : haplotypes.get(0).getSampleKeySet() ) {
|
||||
for( final String sample : samples ) {
|
||||
final HashSet<String> sampleSet = new HashSet<String>(1);
|
||||
sampleSet.add(sample);
|
||||
final double haplotypeLikelihood = LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods( sampleSet, haplotypeList )[0][0];
|
||||
|
||||
final List<Allele> alleleList = new ArrayList<Allele>();
|
||||
alleleList.add(Allele.create(h.getBases()));
|
||||
final double haplotypeLikelihood = LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods( sampleSet, haplotypeReadMap, alleleList )[0][0];
|
||||
if( thisHapVC == null ) {
|
||||
if( nextHapVC == null ) { x11 = MathUtils.approximateLog10SumLog10(x11, haplotypeLikelihood); }
|
||||
else { x12 = MathUtils.approximateLog10SumLog10(x12, haplotypeLikelihood); }
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import org.broadinstitute.sting.gatk.walkers.genotyper.UnifiedArgumentCollection
|
|||
import org.broadinstitute.sting.gatk.walkers.genotyper.UnifiedGenotyperEngine;
|
||||
import org.broadinstitute.sting.gatk.walkers.genotyper.VariantCallContext;
|
||||
import org.broadinstitute.sting.utils.*;
|
||||
import org.broadinstitute.sting.utils.activeregion.ActiveRegionReadState;
|
||||
import org.broadinstitute.sting.utils.activeregion.ActivityProfileResult;
|
||||
import org.broadinstitute.sting.utils.clipping.ReadClipper;
|
||||
import org.broadinstitute.sting.utils.codecs.vcf.*;
|
||||
|
|
@ -202,9 +203,6 @@ public class HaplotypeCaller extends ActiveRegionWalker<Integer, Integer> implem
|
|||
// the genotyping engine
|
||||
private GenotypingEngine genotypingEngine = null;
|
||||
|
||||
// the annotation engine
|
||||
private VariantAnnotatorEngine annotationEngine;
|
||||
|
||||
// fasta reference reader to supplement the edges of the reference sequence
|
||||
private CachingIndexedFastaSequenceFile referenceReader;
|
||||
|
||||
|
|
@ -249,7 +247,7 @@ public class HaplotypeCaller extends ActiveRegionWalker<Integer, Integer> implem
|
|||
UG_engine_simple_genotyper = new UnifiedGenotyperEngine(getToolkit(), simpleUAC, logger, null, null, samples, VariantContextUtils.DEFAULT_PLOIDY);
|
||||
|
||||
// initialize the output VCF header
|
||||
annotationEngine = new VariantAnnotatorEngine(Arrays.asList(annotationClassesToUse), annotationsToUse, annotationsToExclude, this, getToolkit());
|
||||
final VariantAnnotatorEngine annotationEngine = new VariantAnnotatorEngine(Arrays.asList(annotationClassesToUse), annotationsToUse, annotationsToExclude, this, getToolkit());
|
||||
|
||||
Set<VCFHeaderLine> headerInfo = new HashSet<VCFHeaderLine>();
|
||||
|
||||
|
|
@ -282,7 +280,7 @@ public class HaplotypeCaller extends ActiveRegionWalker<Integer, Integer> implem
|
|||
|
||||
assemblyEngine = new SimpleDeBruijnAssembler( DEBUG, graphWriter );
|
||||
likelihoodCalculationEngine = new LikelihoodCalculationEngine( (byte)gcpHMM, DEBUG, pairHMM );
|
||||
genotypingEngine = new GenotypingEngine( DEBUG );
|
||||
genotypingEngine = new GenotypingEngine( DEBUG, annotationEngine );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
|
|
@ -295,9 +293,15 @@ public class HaplotypeCaller extends ActiveRegionWalker<Integer, Integer> implem
|
|||
@Override
|
||||
public boolean includeReadsWithDeletionAtLoci() { return true; }
|
||||
|
||||
// enable non primary reads in the active region
|
||||
// enable non primary and extended reads in the active region
|
||||
@Override
|
||||
public boolean wantsNonPrimaryReads() { return true; }
|
||||
public EnumSet<ActiveRegionReadState> desiredReadStates() {
|
||||
return EnumSet.of(
|
||||
ActiveRegionReadState.PRIMARY,
|
||||
ActiveRegionReadState.NONPRIMARY,
|
||||
ActiveRegionReadState.EXTENDED
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Ensures({"result.isActiveProb >= 0.0", "result.isActiveProb <= 1.0"})
|
||||
|
|
@ -398,21 +402,23 @@ public class HaplotypeCaller extends ActiveRegionWalker<Integer, Integer> implem
|
|||
Collections.sort( haplotypes, new Haplotype.HaplotypeBaseComparator() );
|
||||
|
||||
// evaluate each sample's reads against all haplotypes
|
||||
final HashMap<String, ArrayList<GATKSAMRecord>> perSampleReadList = splitReadsBySample( activeRegion.getReads() );
|
||||
final HashMap<String, ArrayList<GATKSAMRecord>> perSampleFilteredReadList = splitReadsBySample( filteredReads );
|
||||
likelihoodCalculationEngine.computeReadLikelihoods( haplotypes, perSampleReadList );
|
||||
final Map<String, PerReadAlleleLikelihoodMap> stratifiedReadMap = likelihoodCalculationEngine.computeReadLikelihoods( haplotypes, splitReadsBySample( activeRegion.getReads() ) );
|
||||
final Map<String, ArrayList<GATKSAMRecord>> perSampleFilteredReadList = splitReadsBySample( filteredReads );
|
||||
|
||||
// subset down to only the best haplotypes to be genotyped in all samples ( in GGA mode use all discovered haplotypes )
|
||||
final ArrayList<Haplotype> bestHaplotypes = ( UG_engine.getUAC().GenotypingMode != GenotypeLikelihoodsCalculationModel.GENOTYPING_MODE.GENOTYPE_GIVEN_ALLELES ? likelihoodCalculationEngine.selectBestHaplotypes( haplotypes ) : haplotypes );
|
||||
final ArrayList<Haplotype> bestHaplotypes = ( UG_engine.getUAC().GenotypingMode != GenotypeLikelihoodsCalculationModel.GENOTYPING_MODE.GENOTYPE_GIVEN_ALLELES ? likelihoodCalculationEngine.selectBestHaplotypes( haplotypes, stratifiedReadMap ) : haplotypes );
|
||||
|
||||
for( final Pair<VariantContext, Map<Allele, List<Haplotype>>> callResult :
|
||||
genotypingEngine.assignGenotypeLikelihoodsAndCallIndependentEvents( UG_engine, bestHaplotypes, fullReferenceWithPadding, getPaddedLoc(activeRegion), activeRegion.getLocation(), getToolkit().getGenomeLocParser(), activeAllelesToGenotype ) ) {
|
||||
if( DEBUG ) { System.out.println(callResult.getFirst().toStringWithoutGenotypes()); }
|
||||
|
||||
final Map<String, PerReadAlleleLikelihoodMap> stratifiedReadMap = LikelihoodCalculationEngine.partitionReadsBasedOnLikelihoods( getToolkit().getGenomeLocParser(), perSampleReadList, perSampleFilteredReadList, callResult, UG_engine.getUAC().CONTAMINATION_FRACTION, UG_engine.getUAC().contaminationLog );
|
||||
final VariantContext annotatedCall = annotationEngine.annotateContext(stratifiedReadMap, callResult.getFirst());
|
||||
final Map<String, Object> myAttributes = new LinkedHashMap<String, Object>(annotatedCall.getAttributes());
|
||||
vcfWriter.add( new VariantContextBuilder(annotatedCall).attributes(myAttributes).make() );
|
||||
for( final VariantContext call : genotypingEngine.assignGenotypeLikelihoodsAndCallIndependentEvents( UG_engine,
|
||||
bestHaplotypes,
|
||||
samplesList,
|
||||
stratifiedReadMap,
|
||||
perSampleFilteredReadList,
|
||||
fullReferenceWithPadding,
|
||||
getPaddedLoc(activeRegion),
|
||||
activeRegion.getLocation(),
|
||||
getToolkit().getGenomeLocParser(),
|
||||
activeAllelesToGenotype ) ) {
|
||||
vcfWriter.add( call );
|
||||
}
|
||||
|
||||
if( DEBUG ) { System.out.println("----------------------------------------------------------------------------------"); }
|
||||
|
|
@ -467,7 +473,7 @@ public class HaplotypeCaller extends ActiveRegionWalker<Integer, Integer> implem
|
|||
if( postAdapterRead != null && !postAdapterRead.isEmpty() && postAdapterRead.getCigar().getReadLength() > 0 ) {
|
||||
final GATKSAMRecord clippedRead = ReadClipper.hardClipLowQualEnds( postAdapterRead, MIN_TAIL_QUALITY );
|
||||
// protect against INTERVALS with abnormally high coverage
|
||||
// BUGBUG: remove when positinal downsampler is hooked up to ART/HC
|
||||
// BUGBUG: remove when positional downsampler is hooked up to ART/HC
|
||||
if( clippedRead.getReadLength() > 0 && activeRegion.size() < samplesList.size() * DOWNSAMPLE_PER_SAMPLE_PER_REGION ) {
|
||||
activeRegion.add(clippedRead);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,8 +71,9 @@ public class LikelihoodCalculationEngine {
|
|||
DEBUG = debug;
|
||||
}
|
||||
|
||||
public void computeReadLikelihoods( final ArrayList<Haplotype> haplotypes, final HashMap<String, ArrayList<GATKSAMRecord>> perSampleReadList ) {
|
||||
public Map<String, PerReadAlleleLikelihoodMap> computeReadLikelihoods( final ArrayList<Haplotype> haplotypes, final HashMap<String, ArrayList<GATKSAMRecord>> perSampleReadList ) {
|
||||
|
||||
final Map<String, PerReadAlleleLikelihoodMap> stratifiedReadMap = new HashMap<String, PerReadAlleleLikelihoodMap>();
|
||||
int X_METRIC_LENGTH = 0;
|
||||
for( final Map.Entry<String, ArrayList<GATKSAMRecord>> sample : perSampleReadList.entrySet() ) {
|
||||
for( final GATKSAMRecord read : sample.getValue() ) {
|
||||
|
|
@ -97,20 +98,16 @@ public class LikelihoodCalculationEngine {
|
|||
for( final Map.Entry<String, ArrayList<GATKSAMRecord>> sampleEntry : perSampleReadList.entrySet() ) {
|
||||
//if( DEBUG ) { System.out.println("Evaluating sample " + sample + " with " + perSampleReadList.get( sample ).size() + " passing reads"); }
|
||||
// evaluate the likelihood of the reads given those haplotypes
|
||||
computeReadLikelihoods( haplotypes, sampleEntry.getValue(), sampleEntry.getKey() );
|
||||
stratifiedReadMap.put(sampleEntry.getKey(), computeReadLikelihoods(haplotypes, sampleEntry.getValue(), sampleEntry.getKey()));
|
||||
}
|
||||
return stratifiedReadMap;
|
||||
}
|
||||
|
||||
private void computeReadLikelihoods( final ArrayList<Haplotype> haplotypes, final ArrayList<GATKSAMRecord> reads, final String sample ) {
|
||||
private PerReadAlleleLikelihoodMap computeReadLikelihoods( final ArrayList<Haplotype> haplotypes, final ArrayList<GATKSAMRecord> reads, final String sample ) {
|
||||
|
||||
final PerReadAlleleLikelihoodMap perReadAlleleLikelihoodMap = PerReadAlleleLikelihoodMap.getBestAvailablePerReadAlleleLikelihoodMap();
|
||||
final int numHaplotypes = haplotypes.size();
|
||||
final int numReads = reads.size();
|
||||
final double[][] readLikelihoods = new double[numHaplotypes][numReads];
|
||||
final int[][] readCounts = new int[numHaplotypes][numReads];
|
||||
for( int iii = 0; iii < numReads; iii++ ) {
|
||||
final GATKSAMRecord read = reads.get(iii);
|
||||
final int readCount = ReadUtils.getMeanRepresentativeReadCount(read);
|
||||
|
||||
for( final GATKSAMRecord read : reads ) {
|
||||
final byte[] overallGCP = new byte[read.getReadLength()];
|
||||
Arrays.fill( overallGCP, constantGCP ); // Is there a way to derive empirical estimates for this from the data?
|
||||
Haplotype previousHaplotypeSeen = null;
|
||||
|
|
@ -129,14 +126,12 @@ public class LikelihoodCalculationEngine {
|
|||
final int haplotypeStart = ( previousHaplotypeSeen == null ? 0 : computeFirstDifferingPosition(haplotype.getBases(), previousHaplotypeSeen.getBases()) );
|
||||
previousHaplotypeSeen = haplotype;
|
||||
|
||||
readLikelihoods[jjj][iii] = pairHMM.computeReadLikelihoodGivenHaplotypeLog10(haplotype.getBases(), read.getReadBases(),
|
||||
readQuals, readInsQuals, readDelQuals, overallGCP, haplotypeStart, jjj == 0);
|
||||
readCounts[jjj][iii] = readCount;
|
||||
perReadAlleleLikelihoodMap.add(read, Allele.create(haplotype.getBases()),
|
||||
pairHMM.computeReadLikelihoodGivenHaplotypeLog10(haplotype.getBases(), read.getReadBases(),
|
||||
readQuals, readInsQuals, readDelQuals, overallGCP, haplotypeStart, jjj == 0));
|
||||
}
|
||||
}
|
||||
for( int jjj = 0; jjj < numHaplotypes; jjj++ ) {
|
||||
haplotypes.get(jjj).addReadLikelihoods( sample, readLikelihoods[jjj], readCounts[jjj] );
|
||||
}
|
||||
return perReadAlleleLikelihoodMap;
|
||||
}
|
||||
|
||||
private static int computeFirstDifferingPosition( final byte[] b1, final byte[] b2 ) {
|
||||
|
|
@ -148,19 +143,21 @@ public class LikelihoodCalculationEngine {
|
|||
return Math.min(b1.length, b2.length);
|
||||
}
|
||||
|
||||
// This function takes just a single sample and a haplotypeMapping
|
||||
@Requires({"haplotypeMapping.size() > 0"})
|
||||
@Ensures({"result.length == result[0].length", "result.length == haplotypeMapping.size()"})
|
||||
public static double[][] computeDiploidHaplotypeLikelihoods( final String sample, final Map<Allele, List<Haplotype>> haplotypeMapping, final List<Allele> alleleOrdering ) {
|
||||
@Requires({"alleleOrdering.size() > 0"})
|
||||
@Ensures({"result.length == result[0].length", "result.length == alleleOrdering.size()"})
|
||||
public static double[][] computeDiploidHaplotypeLikelihoods( final String sample,
|
||||
final Map<String, PerReadAlleleLikelihoodMap> stratifiedReadMap,
|
||||
final List<Allele> alleleOrdering ) {
|
||||
final TreeSet<String> sampleSet = new TreeSet<String>();
|
||||
sampleSet.add(sample);
|
||||
return computeDiploidHaplotypeLikelihoods(sampleSet, haplotypeMapping, alleleOrdering);
|
||||
return computeDiploidHaplotypeLikelihoods(sampleSet, stratifiedReadMap, alleleOrdering);
|
||||
}
|
||||
|
||||
// This function takes a set of samples to pool over and a haplotypeMapping
|
||||
@Requires({"haplotypeMapping.size() > 0"})
|
||||
@Ensures({"result.length == result[0].length", "result.length == haplotypeMapping.size()"})
|
||||
public static double[][] computeDiploidHaplotypeLikelihoods( final Set<String> samples, final Map<Allele, List<Haplotype>> haplotypeMapping, final List<Allele> alleleOrdering ) {
|
||||
@Requires({"alleleOrdering.size() > 0"})
|
||||
@Ensures({"result.length == result[0].length", "result.length == alleleOrdering.size()"})
|
||||
public static double[][] computeDiploidHaplotypeLikelihoods( final Set<String> samples,
|
||||
final Map<String, PerReadAlleleLikelihoodMap> stratifiedReadMap,
|
||||
final List<Allele> alleleOrdering ) {
|
||||
|
||||
final int numHaplotypes = alleleOrdering.size();
|
||||
final double[][] haplotypeLikelihoodMatrix = new double[numHaplotypes][numHaplotypes];
|
||||
|
|
@ -170,59 +167,19 @@ public class LikelihoodCalculationEngine {
|
|||
|
||||
// compute the diploid haplotype likelihoods
|
||||
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
||||
final Allele iii_allele = alleleOrdering.get(iii);
|
||||
for( int jjj = 0; jjj <= iii; jjj++ ) {
|
||||
for( final Haplotype iii_mapped : haplotypeMapping.get(alleleOrdering.get(iii)) ) {
|
||||
for( final Haplotype jjj_mapped : haplotypeMapping.get(alleleOrdering.get(jjj)) ) {
|
||||
double haplotypeLikelihood = 0.0;
|
||||
for( final String sample : samples ) {
|
||||
final double[] readLikelihoods_iii = iii_mapped.getReadLikelihoods(sample);
|
||||
final int[] readCounts_iii = iii_mapped.getReadCounts(sample);
|
||||
final double[] readLikelihoods_jjj = jjj_mapped.getReadLikelihoods(sample);
|
||||
for( int kkk = 0; kkk < readLikelihoods_iii.length; kkk++ ) {
|
||||
// Compute log10(10^x1/2 + 10^x2/2) = log10(10^x1+10^x2)-log10(2)
|
||||
// First term is approximated by Jacobian log with table lookup.
|
||||
haplotypeLikelihood += readCounts_iii[kkk] * ( MathUtils.approximateLog10SumLog10(readLikelihoods_iii[kkk], readLikelihoods_jjj[kkk]) + LOG_ONE_HALF );
|
||||
}
|
||||
}
|
||||
haplotypeLikelihoodMatrix[iii][jjj] = Math.max(haplotypeLikelihoodMatrix[iii][jjj], haplotypeLikelihood);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// normalize the diploid likelihoods matrix
|
||||
return normalizeDiploidLikelihoodMatrixFromLog10( haplotypeLikelihoodMatrix );
|
||||
}
|
||||
|
||||
// This function takes a set of samples to pool over and a haplotypeMapping
|
||||
@Requires({"haplotypeList.size() > 0"})
|
||||
@Ensures({"result.length == result[0].length", "result.length == haplotypeList.size()"})
|
||||
public static double[][] computeDiploidHaplotypeLikelihoods( final Set<String> samples, final List<Haplotype> haplotypeList ) {
|
||||
|
||||
final int numHaplotypes = haplotypeList.size();
|
||||
final double[][] haplotypeLikelihoodMatrix = new double[numHaplotypes][numHaplotypes];
|
||||
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
||||
Arrays.fill(haplotypeLikelihoodMatrix[iii], Double.NEGATIVE_INFINITY);
|
||||
}
|
||||
|
||||
// compute the diploid haplotype likelihoods
|
||||
// todo - needs to be generalized to arbitrary ploidy, cleaned and merged with PairHMMIndelErrorModel code
|
||||
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
||||
final Haplotype iii_haplotype = haplotypeList.get(iii);
|
||||
for( int jjj = 0; jjj <= iii; jjj++ ) {
|
||||
final Haplotype jjj_haplotype = haplotypeList.get(jjj);
|
||||
final Allele jjj_allele = alleleOrdering.get(jjj);
|
||||
double haplotypeLikelihood = 0.0;
|
||||
for( final String sample : samples ) {
|
||||
final double[] readLikelihoods_iii = iii_haplotype.getReadLikelihoods(sample);
|
||||
final int[] readCounts_iii = iii_haplotype.getReadCounts(sample);
|
||||
final double[] readLikelihoods_jjj = jjj_haplotype.getReadLikelihoods(sample);
|
||||
for( int kkk = 0; kkk < readLikelihoods_iii.length; kkk++ ) {
|
||||
for( final Map.Entry<GATKSAMRecord, Map<Allele,Double>> entry : stratifiedReadMap.get(sample).getLikelihoodReadMap().entrySet() ) {
|
||||
// Compute log10(10^x1/2 + 10^x2/2) = log10(10^x1+10^x2)-log10(2)
|
||||
// First term is approximated by Jacobian log with table lookup.
|
||||
haplotypeLikelihood += readCounts_iii[kkk] * ( MathUtils.approximateLog10SumLog10(readLikelihoods_iii[kkk], readLikelihoods_jjj[kkk]) + LOG_ONE_HALF );
|
||||
haplotypeLikelihood += ReadUtils.getMeanRepresentativeReadCount( entry.getKey() ) *
|
||||
( MathUtils.approximateLog10SumLog10(entry.getValue().get(iii_allele), entry.getValue().get(jjj_allele)) + LOG_ONE_HALF );
|
||||
}
|
||||
}
|
||||
haplotypeLikelihoodMatrix[iii][jjj] = Math.max(haplotypeLikelihoodMatrix[iii][jjj], haplotypeLikelihood);
|
||||
haplotypeLikelihoodMatrix[iii][jjj] = haplotypeLikelihood;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -312,13 +269,16 @@ public class LikelihoodCalculationEngine {
|
|||
|
||||
@Requires({"haplotypes.size() > 0"})
|
||||
@Ensures({"result.size() <= haplotypes.size()"})
|
||||
public ArrayList<Haplotype> selectBestHaplotypes( final ArrayList<Haplotype> haplotypes ) {
|
||||
public ArrayList<Haplotype> selectBestHaplotypes( final ArrayList<Haplotype> haplotypes, final Map<String, PerReadAlleleLikelihoodMap> stratifiedReadMap ) {
|
||||
|
||||
final int numHaplotypes = haplotypes.size();
|
||||
final Set<String> sampleKeySet = haplotypes.get(0).getSampleKeySet(); // BUGBUG: assume all haplotypes saw the same samples
|
||||
final Set<String> sampleKeySet = stratifiedReadMap.keySet();
|
||||
final ArrayList<Integer> bestHaplotypesIndexList = new ArrayList<Integer>();
|
||||
bestHaplotypesIndexList.add( findReferenceIndex(haplotypes) ); // always start with the reference haplotype
|
||||
final double[][] haplotypeLikelihoodMatrix = computeDiploidHaplotypeLikelihoods( sampleKeySet, haplotypes ); // all samples pooled together
|
||||
final List<Allele> haplotypesAsAlleles = new ArrayList<Allele>();
|
||||
for( final Haplotype h : haplotypes ) { haplotypesAsAlleles.add(Allele.create(h.getBases())); }
|
||||
|
||||
final double[][] haplotypeLikelihoodMatrix = computeDiploidHaplotypeLikelihoods( sampleKeySet, stratifiedReadMap, haplotypesAsAlleles ); // all samples pooled together
|
||||
|
||||
int hap1 = 0;
|
||||
int hap2 = 0;
|
||||
|
|
@ -358,52 +318,4 @@ public class LikelihoodCalculationEngine {
|
|||
}
|
||||
throw new ReviewedStingException( "No reference haplotype found in the list of haplotypes!" );
|
||||
}
|
||||
|
||||
public static Map<String, PerReadAlleleLikelihoodMap> partitionReadsBasedOnLikelihoods( final GenomeLocParser parser,
|
||||
final HashMap<String, ArrayList<GATKSAMRecord>> perSampleReadList,
|
||||
final HashMap<String, ArrayList<GATKSAMRecord>> perSampleFilteredReadList,
|
||||
final Pair<VariantContext, Map<Allele,List<Haplotype>>> call,
|
||||
final double downsamplingFraction,
|
||||
final PrintStream downsamplingLog ) {
|
||||
final Map<String, PerReadAlleleLikelihoodMap> returnMap = new HashMap<String, PerReadAlleleLikelihoodMap>();
|
||||
final GenomeLoc callLoc = parser.createGenomeLoc(call.getFirst());
|
||||
for( final Map.Entry<String, ArrayList<GATKSAMRecord>> sample : perSampleReadList.entrySet() ) {
|
||||
final PerReadAlleleLikelihoodMap likelihoodMap = PerReadAlleleLikelihoodMap.getBestAvailablePerReadAlleleLikelihoodMap();
|
||||
|
||||
final ArrayList<GATKSAMRecord> readsForThisSample = sample.getValue();
|
||||
for( int iii = 0; iii < readsForThisSample.size(); iii++ ) {
|
||||
final GATKSAMRecord read = readsForThisSample.get(iii); // BUGBUG: assumes read order in this list and haplotype likelihood list are the same!
|
||||
// only count the read if it overlaps the event, otherwise it is not added to the output read list at all
|
||||
if( callLoc.overlapsP(parser.createGenomeLoc(read)) ) {
|
||||
for( final Allele a : call.getFirst().getAlleles() ) {
|
||||
double maxLikelihood = Double.NEGATIVE_INFINITY;
|
||||
for( final Haplotype h : call.getSecond().get(a) ) { // use the max likelihood from all the haplotypes which mapped to this allele (achieved via the haplotype mapper object)
|
||||
final double likelihood = h.getReadLikelihoods(sample.getKey())[iii];
|
||||
if( likelihood > maxLikelihood ) {
|
||||
maxLikelihood = likelihood;
|
||||
}
|
||||
}
|
||||
likelihoodMap.add(read, a, maxLikelihood);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// down-sample before adding filtered reads
|
||||
likelihoodMap.performPerAlleleDownsampling(downsamplingFraction, downsamplingLog);
|
||||
|
||||
// add all filtered reads to the NO_CALL list because they weren't given any likelihoods
|
||||
for( final GATKSAMRecord read : perSampleFilteredReadList.get(sample.getKey()) ) {
|
||||
// only count the read if it overlaps the event, otherwise it is not added to the output read list at all
|
||||
if( callLoc.overlapsP(parser.createGenomeLoc(read)) ) {
|
||||
for( final Allele a : call.getFirst().getAlleles() ) {
|
||||
likelihoodMap.add(read, a, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
returnMap.put(sample.getKey(), likelihoodMap);
|
||||
|
||||
}
|
||||
return returnMap;
|
||||
}
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@ public class BQSRIntegrationTest extends WalkerTest {
|
|||
" -L " + interval +
|
||||
args +
|
||||
" -knownSites " + (reference.equals(b36KGReference) ? b36dbSNP129 : hg18dbSNP132) +
|
||||
" --allow_potentially_misencoded_quality_scores" + // TODO -- remove me when we get new SOLiD bams
|
||||
" -o %s";
|
||||
}
|
||||
|
||||
|
|
@ -112,6 +113,7 @@ public class BQSRIntegrationTest extends WalkerTest {
|
|||
" -R " + b36KGReference +
|
||||
" -I " + privateTestDir + "NA19240.chr1.BFAST.SOLID.hasCSNoCall.bam" +
|
||||
" -L 1:50,000-80,000" +
|
||||
" --allow_potentially_misencoded_quality_scores" + // TODO -- remove me when we get new SOLiD bams
|
||||
" -o %s",
|
||||
1, // just one output file
|
||||
UserException.class);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ public class UnifiedGenotyperIntegrationTest extends WalkerTest {
|
|||
public void testMultipleSNPAlleles() {
|
||||
WalkerTest.WalkerTestSpec spec = new WalkerTest.WalkerTestSpec(
|
||||
"-T UnifiedGenotyper -R " + b37KGReference + " --no_cmdline_in_header -glm BOTH --dbsnp " + b37dbSNP129 + " -I " + privateTestDir + "multiallelic.snps.bam -o %s -L " + privateTestDir + "multiallelic.snps.intervals", 1,
|
||||
Arrays.asList("704888987baacff8c7b273b8ab9938d0"));
|
||||
Arrays.asList("d20c7a143b899f0239bf64b652ad3edb"));
|
||||
executeTest("test Multiple SNP alleles", spec);
|
||||
}
|
||||
|
||||
|
|
@ -177,7 +177,7 @@ public class UnifiedGenotyperIntegrationTest extends WalkerTest {
|
|||
executeTest("test using comp track", spec);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false) // EB: for some reason this test crashes whenever I run it on my local machine
|
||||
public void testNoCmdLineHeaderStdout() {
|
||||
WalkerTest.WalkerTestSpec spec = new WalkerTest.WalkerTestSpec(
|
||||
baseCommandNoCmdLineHeaderStdout + " -glm INDEL -L 1:67,225,396-67,288,518", 0,
|
||||
|
|
@ -197,7 +197,7 @@ public class UnifiedGenotyperIntegrationTest extends WalkerTest {
|
|||
|
||||
@Test
|
||||
public void testOutputParameterAllSites() {
|
||||
testOutputParameters("--output_mode EMIT_ALL_SITES", "81fff490c0f59890f1e75dc290833434");
|
||||
testOutputParameters("--output_mode EMIT_ALL_SITES", "8b26088a035e579c4afd3b46737291e4");
|
||||
}
|
||||
|
||||
private void testOutputParameters(final String args, final String md5) {
|
||||
|
|
@ -345,13 +345,13 @@ public class UnifiedGenotyperIntegrationTest extends WalkerTest {
|
|||
public void testMultiSampleIndels1() {
|
||||
WalkerTest.WalkerTestSpec spec1 = new WalkerTest.WalkerTestSpec(
|
||||
baseCommandIndels + " -I " + validationDataLocation + "low_coverage_CEU.chr1.10k-11k.bam -o %s -L 1:10450700-10551000", 1,
|
||||
Arrays.asList("a4761d7f25e7a62f34494801c98a0da7"));
|
||||
Arrays.asList("69df7a00f800204564ca3726e1871132"));
|
||||
List<File> result = executeTest("test MultiSample Pilot1 CEU indels", spec1).getFirst();
|
||||
|
||||
WalkerTest.WalkerTestSpec spec2 = new WalkerTest.WalkerTestSpec(
|
||||
baseCommandIndels + " --genotyping_mode GENOTYPE_GIVEN_ALLELES -alleles " + result.get(0).getAbsolutePath() + " -I " + validationDataLocation +
|
||||
"low_coverage_CEU.chr1.10k-11k.bam -o %s -L 1:10450700-10551000", 1,
|
||||
Arrays.asList("c526c234947482d1cd2ffc5102083a08"));
|
||||
Arrays.asList("1256a7eceff2c2374c231ff981df486d"));
|
||||
executeTest("test MultiSample Pilot1 CEU indels using GENOTYPE_GIVEN_ALLELES", spec2);
|
||||
}
|
||||
|
||||
|
|
@ -436,8 +436,8 @@ public class UnifiedGenotyperIntegrationTest extends WalkerTest {
|
|||
@Test
|
||||
public void testNsInCigar() {
|
||||
WalkerTest.WalkerTestSpec spec = new WalkerTest.WalkerTestSpec(
|
||||
"-T UnifiedGenotyper -R " + b37KGReference + " --no_cmdline_in_header -I " + validationDataLocation + "testWithNs.bam -o %s -L 8:141799600-141814700", 1,
|
||||
Arrays.asList("d6d40bacd540a41f305420dfea35e04a"));
|
||||
"-T UnifiedGenotyper -R " + b37KGReference + " --no_cmdline_in_header -I " + privateTestDir + "testWithNs.bam -o %s -L 8:141813600-141813700 -out_mode EMIT_ALL_SITES", 1,
|
||||
Arrays.asList("32f18ba50406cd8c8069ba07f2f89558"));
|
||||
executeTest("test calling on reads with Ns in CIGAR", spec);
|
||||
}
|
||||
|
||||
|
|
@ -457,7 +457,7 @@ public class UnifiedGenotyperIntegrationTest extends WalkerTest {
|
|||
|
||||
@Test
|
||||
public void testReducedBamSNPs() {
|
||||
testReducedCalling("SNP", "f5ccbc96d0d66832dd9b3c5cb6507db4");
|
||||
testReducedCalling("SNP", "dee6590e3b7079890bc3a9cb372c297e");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -2,16 +2,14 @@ package org.broadinstitute.sting.gatk.walkers.genotyper.afcalc;
|
|||
|
||||
import org.broadinstitute.sting.BaseTest;
|
||||
import org.broadinstitute.sting.utils.MathUtils;
|
||||
import org.broadinstitute.sting.utils.QualityUtils;
|
||||
import org.broadinstitute.sting.utils.Utils;
|
||||
import org.broadinstitute.sting.utils.variantcontext.Allele;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class AFCalcResultUnitTest extends BaseTest {
|
||||
private static class MyTest {
|
||||
|
|
@ -79,4 +77,54 @@ public class AFCalcResultUnitTest extends BaseTest {
|
|||
final double[] actualPosteriors = new double[]{result.getLog10PosteriorOfAFEq0(), result.getLog10PosteriorOfAFGT0()};
|
||||
Assert.assertEquals(MathUtils.sumLog10(actualPosteriors), 1.0, 1e-3, "Posteriors don't sum to 1 with 1e-3 precision");
|
||||
}
|
||||
|
||||
@DataProvider(name = "TestIsPolymorphic")
|
||||
public Object[][] makeTestIsPolymorphic() {
|
||||
List<Object[]> tests = new ArrayList<Object[]>();
|
||||
|
||||
final List<Double> pValues = new LinkedList<Double>();
|
||||
for ( final double p : Arrays.asList(0.01, 0.1, 0.9, 0.99, 0.999) )
|
||||
for ( final double espilon : Arrays.asList(-1e-5, 0.0, 1e-5) )
|
||||
pValues.add(p + espilon);
|
||||
|
||||
for ( final double pNonRef : pValues ) {
|
||||
for ( final double pThreshold : pValues ) {
|
||||
final boolean shouldBePoly = pNonRef >= pThreshold;
|
||||
if ( pNonRef != pThreshold)
|
||||
// let's not deal with numerical instability
|
||||
tests.add(new Object[]{ pNonRef, pThreshold, shouldBePoly });
|
||||
}
|
||||
}
|
||||
|
||||
return tests.toArray(new Object[][]{});
|
||||
}
|
||||
|
||||
private AFCalcResult makePolymorphicTestData(final double pNonRef) {
|
||||
return new AFCalcResult(
|
||||
new int[]{0},
|
||||
1,
|
||||
alleles,
|
||||
MathUtils.normalizeFromLog10(new double[]{1 - pNonRef, pNonRef}, true, false),
|
||||
log10Even,
|
||||
Collections.singletonMap(C, Math.log10(pNonRef)));
|
||||
}
|
||||
|
||||
@Test(enabled = true, dataProvider = "TestIsPolymorphic")
|
||||
private void testIsPolymorphic(final double pNonRef, final double pThreshold, final boolean shouldBePoly) {
|
||||
final AFCalcResult result = makePolymorphicTestData(pNonRef);
|
||||
final boolean actualIsPoly = result.isPolymorphic(C, Math.log10(pThreshold));
|
||||
Assert.assertEquals(actualIsPoly, shouldBePoly,
|
||||
"isPolymorphic with pNonRef " + pNonRef + " and threshold " + pThreshold + " returned "
|
||||
+ actualIsPoly + " but the expected result is " + shouldBePoly);
|
||||
}
|
||||
|
||||
@Test(enabled = true, dataProvider = "TestIsPolymorphic")
|
||||
private void testIsPolymorphicQual(final double pNonRef, final double pThreshold, final boolean shouldBePoly) {
|
||||
final AFCalcResult result = makePolymorphicTestData(pNonRef);
|
||||
final double qual = QualityUtils.phredScaleCorrectRate(pThreshold);
|
||||
final boolean actualIsPoly = result.isPolymorphicPhredScaledQual(C, qual);
|
||||
Assert.assertEquals(actualIsPoly, shouldBePoly,
|
||||
"isPolymorphic with pNonRef " + pNonRef + " and threshold " + pThreshold + " returned "
|
||||
+ actualIsPoly + " but the expected result is " + shouldBePoly);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,19 +21,19 @@ public class HaplotypeCallerIntegrationTest extends WalkerTest {
|
|||
|
||||
@Test
|
||||
public void testHaplotypeCallerMultiSample() {
|
||||
HCTest(CEUTRIO_BAM, "", "2b39732ff8e0de5bc2ae949aaf7a6f21");
|
||||
HCTest(CEUTRIO_BAM, "", "d602d40852ad6d2d094be07e60cf95bd");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHaplotypeCallerSingleSample() {
|
||||
HCTest(NA12878_BAM, "", "8b217638ff585effb9cc70e9a9aa544f");
|
||||
HCTest(NA12878_BAM, "", "70ad9d53dda4d302b879ca2b7dd5b368");
|
||||
}
|
||||
|
||||
// TODO -- add more tests for GGA mode, especially with input alleles that are complex variants and/or not trimmed
|
||||
@Test
|
||||
public void testHaplotypeCallerMultiSampleGGA() {
|
||||
HCTest(CEUTRIO_BAM, "--max_alternate_alleles 3 -gt_mode GENOTYPE_GIVEN_ALLELES -alleles " + validationDataLocation + "combined.phase1.chr20.raw.indels.sites.vcf",
|
||||
"541aa8291f03ba33bd1ad3d731fd5657");
|
||||
HCTest(CEUTRIO_BAM, "--max_alternate_alleles 3 -gt_mode GENOTYPE_GIVEN_ALLELES -out_mode EMIT_ALL_SITES -alleles " + validationDataLocation + "combined.phase1.chr20.raw.indels.sites.vcf",
|
||||
"e2b3bf420c45c677956a2e4a56d75ea2");
|
||||
}
|
||||
|
||||
private void HCTestComplexVariants(String bam, String args, String md5) {
|
||||
|
|
@ -44,18 +44,18 @@ public class HaplotypeCallerIntegrationTest extends WalkerTest {
|
|||
|
||||
@Test
|
||||
public void testHaplotypeCallerMultiSampleComplex() {
|
||||
HCTestComplexVariants(privateTestDir + "AFR.complex.variants.bam", "", "fd7170cbde7df04d4fbe1da7903c31c6");
|
||||
HCTestComplexVariants(privateTestDir + "AFR.complex.variants.bam", "", "883871f8bb4099f69fd804f8a6181954");
|
||||
}
|
||||
|
||||
private void HCTestSymbolicVariants(String bam, String args, String md5) {
|
||||
final String base = String.format("-T HaplotypeCaller -R %s -I %s", REF, bam) + " -L 20:5947969-5948369 -L 20:61091236-61091636 --no_cmdline_in_header -o %s -minPruning 2";
|
||||
final String base = String.format("-T HaplotypeCaller -R %s -I %s", REF, bam) + " -L 20:5947969-5948369 -L 20:61091236-61091636 --no_cmdline_in_header -o %s -minPruning 1";
|
||||
final WalkerTestSpec spec = new WalkerTestSpec(base + " " + args, Arrays.asList(md5));
|
||||
executeTest("testHaplotypeCallerSymbolicVariants: args=" + args, spec);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHaplotypeCallerSingleSampleSymbolic() {
|
||||
HCTestSymbolicVariants(NA12878_CHR20_BAM, "", "99456fc7207c1fe9f367a0d0afae87cd");
|
||||
HCTestSymbolicVariants(NA12878_CHR20_BAM, "", "338ab3b7dc3d54df8af94c0811028a75");
|
||||
}
|
||||
|
||||
private void HCTestIndelQualityScores(String bam, String args, String md5) {
|
||||
|
|
@ -66,20 +66,20 @@ public class HaplotypeCallerIntegrationTest extends WalkerTest {
|
|||
|
||||
@Test
|
||||
public void testHaplotypeCallerSingleSampleIndelQualityScores() {
|
||||
HCTestIndelQualityScores(NA12878_RECALIBRATED_BAM, "", "6c1631785b3f832aecab1a99f0454762");
|
||||
HCTestIndelQualityScores(NA12878_RECALIBRATED_BAM, "", "aff11b014ca42bfa301bcced5f5e54dd");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void HCTestProblematicReadsModifiedInActiveRegions() {
|
||||
final String base = String.format("-T HaplotypeCaller -R %s -I %s", REF, privateTestDir + "haplotype-problem-4.bam") + " --no_cmdline_in_header -o %s -minPruning 3 -L 4:49139026-49139965";
|
||||
final WalkerTestSpec spec = new WalkerTestSpec(base, Arrays.asList("ec437d2d9f3ae07d155983be0155c8ed"));
|
||||
final WalkerTestSpec spec = new WalkerTestSpec(base, Arrays.asList("2f4ed6dc969bee041215944a9b24328f"));
|
||||
executeTest("HCTestProblematicReadsModifiedInActiveRegions: ", spec);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void HCTestStructuralIndels() {
|
||||
final String base = String.format("-T HaplotypeCaller -R %s -I %s", REF, privateTestDir + "AFR.structural.indels.bam") + " --no_cmdline_in_header -o %s -minPruning 6 -L 20:8187565-8187800 -L 20:18670537-18670730";
|
||||
final WalkerTestSpec spec = new WalkerTestSpec(base, Arrays.asList("237601bbc39694c7413a332cbb656c8e"));
|
||||
final WalkerTestSpec spec = new WalkerTestSpec(base, Arrays.asList("d8d6f2ebe79bca81c8a0911daa153b89"));
|
||||
executeTest("HCTestStructuralIndels: ", spec);
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ public class HaplotypeCallerIntegrationTest extends WalkerTest {
|
|||
public void HCTestReducedBam() {
|
||||
WalkerTest.WalkerTestSpec spec = new WalkerTest.WalkerTestSpec(
|
||||
"-T HaplotypeCaller -R " + b37KGReference + " --no_cmdline_in_header -I " + privateTestDir + "bamExample.ReducedRead.ADAnnotation.bam -o %s -L 1:67,225,396-67,288,518", 1,
|
||||
Arrays.asList("40bf739fb2b1743642498efe79ea6342"));
|
||||
Arrays.asList("d01cb5f77ed5aca1d228cfbce9364c21"));
|
||||
executeTest("HC calling on a ReducedRead BAM", spec);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ public class LikelihoodCalculationEngineUnitTest extends BaseTest {
|
|||
Assert.assertTrue(compareDoubleArrays(LikelihoodCalculationEngine.normalizeDiploidLikelihoodMatrixFromLog10(likelihoodMatrix2), normalizedMatrix2));
|
||||
}
|
||||
|
||||
// BUGBUG: LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods has changed! Need to make new unit tests!
|
||||
/*
|
||||
private class BasicLikelihoodTestProvider extends TestDataProvider {
|
||||
public Double readLikelihoodForHaplotype1;
|
||||
public Double readLikelihoodForHaplotype2;
|
||||
|
|
@ -152,10 +154,9 @@ public class LikelihoodCalculationEngineUnitTest extends BaseTest {
|
|||
logger.warn(String.format("Test: %s", cfg.toString()));
|
||||
Assert.assertTrue(compareDoubleArrays(calculatedMatrix, expectedMatrix));
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Private function to compare 2d arrays
|
||||
*/
|
||||
//Private function to compare 2d arrays
|
||||
private boolean compareDoubleArrays(double[][] b1, double[][] b2) {
|
||||
if( b1.length != b2.length ) {
|
||||
return false; // sanity check
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import org.broadinstitute.sting.gatk.CommandLineGATK;
|
|||
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||
import org.broadinstitute.sting.utils.help.ApplicationDetails;
|
||||
import org.broadinstitute.sting.utils.help.HelpFormatter;
|
||||
import org.broadinstitute.sting.utils.help.HelpUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
|
@ -288,7 +289,7 @@ public abstract class CommandLineProgram {
|
|||
*/
|
||||
private static void printDocumentationReference() {
|
||||
errorPrintf("Visit our website and forum for extensive documentation and answers to %n");
|
||||
errorPrintf("commonly asked questions http://www.broadinstitute.org/gatk%n");
|
||||
errorPrintf("commonly asked questions " + HelpUtils.BASE_GATK_URL + "%n");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import org.broadinstitute.sting.utils.exceptions.UserException;
|
|||
import org.broadinstitute.sting.utils.help.ApplicationDetails;
|
||||
import org.broadinstitute.sting.utils.help.DocumentedGATKFeature;
|
||||
import org.broadinstitute.sting.utils.help.GATKDocUtils;
|
||||
import org.broadinstitute.sting.utils.help.HelpUtils;
|
||||
import org.broadinstitute.sting.utils.text.TextFormattingUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
|
@ -160,7 +161,7 @@ public class CommandLineGATK extends CommandLineExecutable {
|
|||
List<String> header = new ArrayList<String>();
|
||||
header.add(String.format("The Genome Analysis Toolkit (GATK) v%s, Compiled %s",getVersionNumber(), getBuildTime()));
|
||||
header.add("Copyright (c) 2010 The Broad Institute");
|
||||
header.add("For support and documentation go to http://www.broadinstitute.org/gatk");
|
||||
header.add("For support and documentation go to " + HelpUtils.BASE_GATK_URL);
|
||||
return header;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -206,6 +206,22 @@ public class GATKArgumentCollection {
|
|||
@Argument(fullName = "baqGapOpenPenalty", shortName="baqGOP", doc="BAQ gap open penalty (Phred Scaled). Default value is 40. 30 is perhaps better for whole genome call sets", required = false)
|
||||
public double BAQGOP = BAQ.DEFAULT_GOP;
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// quality encoding checking arguments
|
||||
//
|
||||
// --------------------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Q0 == ASCII 33 according to the SAM specification, whereas Illumina encoding starts at Q64. The idea here is
|
||||
* simple: we just iterate over all reads and subtract 31 from every quality score.
|
||||
*/
|
||||
@Argument(fullName = "fix_misencoded_quality_scores", shortName="fixMisencodedQuals", doc="Fix mis-encoded base quality scores", required = false)
|
||||
public boolean FIX_MISENCODED_QUALS = false;
|
||||
|
||||
@Argument(fullName = "allow_potentially_misencoded_quality_scores", shortName="allowPotentiallyMisencodedQuals", doc="Do not fail when encountered base qualities that are too high and seemingly indicate a problem with the base quality encoding of the BAM file", required = false)
|
||||
public boolean ALLOW_POTENTIALLY_MISENCODED_QUALS = false;
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// performance log arguments
|
||||
|
|
|
|||
|
|
@ -30,12 +30,10 @@ import net.sf.samtools.*;
|
|||
import net.sf.samtools.util.CloseableIterator;
|
||||
import net.sf.samtools.util.RuntimeIOException;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.broadinstitute.sting.gatk.downsampling.*;
|
||||
import org.broadinstitute.sting.gatk.downsampling.DownsampleType;
|
||||
import org.broadinstitute.sting.gatk.downsampling.DownsamplingMethod;
|
||||
import org.broadinstitute.sting.gatk.ReadMetrics;
|
||||
import org.broadinstitute.sting.gatk.ReadProperties;
|
||||
import org.broadinstitute.sting.gatk.arguments.ValidationExclusion;
|
||||
import org.broadinstitute.sting.gatk.downsampling.*;
|
||||
import org.broadinstitute.sting.gatk.filters.CountingFilteringIterator;
|
||||
import org.broadinstitute.sting.gatk.filters.ReadFilter;
|
||||
import org.broadinstitute.sting.gatk.iterators.*;
|
||||
|
|
@ -567,7 +565,7 @@ public class SAMDataSource {
|
|||
*
|
||||
* @return the start positions of the first chunk of reads for all BAM files
|
||||
*/
|
||||
public Map<SAMReaderID, GATKBAMFileSpan> getInitialReaderPositions() {
|
||||
protected Map<SAMReaderID, GATKBAMFileSpan> getInitialReaderPositions() {
|
||||
Map<SAMReaderID, GATKBAMFileSpan> initialPositions = new HashMap<SAMReaderID, GATKBAMFileSpan>();
|
||||
SAMReaders readers = resourcePool.getAvailableReaders();
|
||||
|
||||
|
|
@ -585,7 +583,7 @@ public class SAMDataSource {
|
|||
* @param shard The shard specifying the data limits.
|
||||
* @return An iterator over the selected data.
|
||||
*/
|
||||
public StingSAMIterator getIterator( Shard shard ) {
|
||||
protected StingSAMIterator getIterator( Shard shard ) {
|
||||
return getIterator(resourcePool.getAvailableReaders(), shard, shard instanceof ReadShard);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ import org.broadinstitute.sting.utils.AutoFormattingTime;
|
|||
import org.broadinstitute.sting.utils.MathUtils;
|
||||
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||
import org.broadinstitute.sting.utils.exceptions.UserException;
|
||||
import org.broadinstitute.sting.utils.nanoScheduler.NanoScheduler;
|
||||
import org.broadinstitute.sting.utils.progressmeter.ProgressMeter;
|
||||
import org.broadinstitute.sting.utils.threading.ThreadEfficiencyMonitor;
|
||||
|
||||
|
|
@ -346,9 +345,6 @@ public abstract class MicroScheduler implements MicroSchedulerMBean {
|
|||
for ( final TraversalEngine te : allCreatedTraversalEngines)
|
||||
te.shutdown();
|
||||
|
||||
// horrible hack to print nano scheduling information across all nano schedulers, if any were used
|
||||
NanoScheduler.printCombinedRuntimeProfile();
|
||||
|
||||
allCreatedTraversalEngines.clear();
|
||||
availableTraversalEngines.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,11 +25,9 @@
|
|||
|
||||
package org.broadinstitute.sting.gatk.filters;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Collections2;
|
||||
import org.broadinstitute.sting.utils.Utils;
|
||||
import org.broadinstitute.sting.utils.classloader.PluginManager;
|
||||
import org.broadinstitute.sting.utils.help.GATKDocUtils;
|
||||
import org.broadinstitute.sting.utils.help.HelpUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
|
@ -73,7 +71,7 @@ public class FilterManager extends PluginManager<ReadFilter> {
|
|||
|
||||
return String.format("Read filter %s not found. Available read filters:%n%n%s%n%n%s",pluginName,
|
||||
userFriendlyListofReadFilters(availableFilters),
|
||||
"Please consult the GATK Documentation (http://www.broadinstitute.org/gatk/gatkdocs/) for more information.");
|
||||
"Please consult the GATK Documentation (" + HelpUtils.GATK_DOCS_URL + ") for more information.");
|
||||
}
|
||||
|
||||
private String userFriendlyListofReadFilters(List<Class<? extends ReadFilter>> filters) {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ abstract public class ReadTransformer {
|
|||
protected ReadTransformer() {}
|
||||
|
||||
/**
|
||||
* Master initialization routine. Called to setup a ReadTransform, using it's overloaded initialialSub routine.
|
||||
* Master initialization routine. Called to setup a ReadTransform, using it's overloaded initializeSub routine.
|
||||
*
|
||||
* @param overrideTime if not null, we will run this ReadTransform at the time provided, regardless of the timing of this read transformer itself
|
||||
* @param engine the engine, for initializing values
|
||||
|
|
@ -59,7 +59,7 @@ abstract public class ReadTransformer {
|
|||
}
|
||||
|
||||
/**
|
||||
* Subclasses must override this to initialize themeselves
|
||||
* Subclasses must override this to initialize themselves
|
||||
*
|
||||
* @param engine the engine, for initializing values
|
||||
* @param walker the walker we intend to run
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ public class GATKReport {
|
|||
|
||||
GATKReportTable table = tables.firstEntry().getValue();
|
||||
if ( table.getNumColumns() != values.length )
|
||||
throw new ReviewedStingException("The number of arguments in writeRow() must match the number of columns in the table");
|
||||
throw new ReviewedStingException("The number of arguments in writeRow() " + values.length + " must match the number of columns in the table" + table.getNumColumns());
|
||||
|
||||
final int rowIndex = table.getNumRows();
|
||||
for ( int i = 0; i < values.length; i++ )
|
||||
|
|
|
|||
|
|
@ -258,13 +258,23 @@ public class TraverseActiveRegions <M,T> extends TraversalEngine<M,T,ActiveRegio
|
|||
activeRegion.add( read );
|
||||
}
|
||||
for( final ActiveRegion otherRegionToTest : workQueue ) {
|
||||
if( !bestRegion.equals(otherRegionToTest) && otherRegionToTest.getExtendedLoc().overlapsP( readLoc ) ) {
|
||||
otherRegionToTest.add( read );
|
||||
if( !bestRegion.equals(otherRegionToTest) ) {
|
||||
// check for non-primary vs. extended
|
||||
if ( otherRegionToTest.getLocation().overlapsP( readLoc ) ) {
|
||||
otherRegionToTest.add( read );
|
||||
} else if ( walker.wantsExtendedReads() && otherRegionToTest.getExtendedLoc().overlapsP( readLoc ) ) {
|
||||
otherRegionToTest.add( read );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
placedReads.add( read );
|
||||
} else if( activeRegion.getExtendedLoc().overlapsP( readLoc ) && walker.wantsNonPrimaryReads() ) {
|
||||
// check for non-primary vs. extended
|
||||
} else if( activeRegion.getLocation().overlapsP( readLoc ) ) {
|
||||
if ( walker.wantsNonPrimaryReads() ) {
|
||||
activeRegion.add( read );
|
||||
}
|
||||
} else if( walker.wantsExtendedReads() && activeRegion.getExtendedLoc().overlapsP( readLoc )) {
|
||||
activeRegion.add( read );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package org.broadinstitute.sting.gatk.walkers;
|
||||
|
||||
import com.google.java.contract.Ensures;
|
||||
import net.sf.picard.reference.IndexedFastaSequenceFile;
|
||||
import org.broad.tribble.Feature;
|
||||
import org.broadinstitute.sting.commandline.Input;
|
||||
|
|
@ -13,14 +14,14 @@ import org.broadinstitute.sting.utils.GenomeLoc;
|
|||
import org.broadinstitute.sting.utils.GenomeLocParser;
|
||||
import org.broadinstitute.sting.utils.GenomeLocSortedSet;
|
||||
import org.broadinstitute.sting.utils.activeregion.ActiveRegion;
|
||||
import org.broadinstitute.sting.utils.activeregion.ActiveRegionReadState;
|
||||
import org.broadinstitute.sting.utils.activeregion.ActivityProfileResult;
|
||||
import org.broadinstitute.sting.utils.interval.IntervalMergingRule;
|
||||
import org.broadinstitute.sting.utils.interval.IntervalSetRule;
|
||||
import org.broadinstitute.sting.utils.interval.IntervalUtils;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Base class for all the Active Region Walkers.
|
||||
|
|
@ -70,11 +71,24 @@ public abstract class ActiveRegionWalker<MapType, ReduceType> extends Walker<Map
|
|||
return true; // We are keeping all the reads
|
||||
}
|
||||
|
||||
public boolean wantsNonPrimaryReads() {
|
||||
return false;
|
||||
public EnumSet<ActiveRegionReadState> desiredReadStates() {
|
||||
return EnumSet.of(ActiveRegionReadState.PRIMARY);
|
||||
}
|
||||
|
||||
public final boolean wantsNonPrimaryReads() {
|
||||
return desiredReadStates().contains(ActiveRegionReadState.NONPRIMARY);
|
||||
}
|
||||
|
||||
public boolean wantsExtendedReads() {
|
||||
return desiredReadStates().contains(ActiveRegionReadState.EXTENDED);
|
||||
}
|
||||
|
||||
public boolean wantsUnmappedReads() {
|
||||
return desiredReadStates().contains(ActiveRegionReadState.UNMAPPED);
|
||||
}
|
||||
|
||||
// Determine probability of active status over the AlignmentContext
|
||||
@Ensures({"result.isActiveProb >= 0.0", "result.isActiveProb <= 1.0"})
|
||||
public abstract ActivityProfileResult isActive(final RefMetaDataTracker tracker, final ReferenceContext ref, final AlignmentContext context);
|
||||
|
||||
// Map over the ActiveRegion
|
||||
|
|
|
|||
|
|
@ -276,6 +276,12 @@ public class FisherStrand extends InfoFieldAnnotation implements StandardAnnotat
|
|||
|
||||
for ( Map.Entry<String, AlignmentContext> sample : stratifiedContexts.entrySet() ) {
|
||||
for (PileupElement p : sample.getValue().getBasePileup()) {
|
||||
|
||||
// ignore reduced reads because they are always on the forward strand!
|
||||
// TODO -- when het compression is enabled in RR, we somehow need to allow those reads through into the Fisher test
|
||||
if ( p.getRead().isReducedRead() )
|
||||
continue;
|
||||
|
||||
if ( ! RankSumTest.isUsableBase(p, false) ) // ignore deletions
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -282,6 +282,7 @@ public class DiffEngine {
|
|||
// now that we have a specific list of values we want to show, display them
|
||||
GATKReport report = new GATKReport();
|
||||
final String tableName = "differences";
|
||||
// TODO for Geraldine -- link needs to be updated below
|
||||
report.addTable(tableName, "Summarized differences between the master and test files. See http://www.broadinstitute.org/gsa/wiki/index.php/DiffEngine for more information", 3);
|
||||
final GATKReportTable table = report.getTable(tableName);
|
||||
table.addColumn("Difference");
|
||||
|
|
|
|||
|
|
@ -138,7 +138,8 @@ public class DiffObjects extends RodWalker<Integer, Integer> {
|
|||
/**
|
||||
* Writes out a file of the DiffEngine format:
|
||||
*
|
||||
* http://www.broadinstitute.org/gsa/wiki/index.php/DiffEngine
|
||||
* TODO for Geraldine -- link needs to be updated below (and also in SelectVariants and RefSeqCodec GATK docs)
|
||||
* http://www.broadinstitute.org/gsa/wiki/index.php/DiffEngine
|
||||
*/
|
||||
@Output(doc="File to which results should be written",required=true)
|
||||
protected PrintStream out;
|
||||
|
|
|
|||
|
|
@ -382,11 +382,9 @@ public class UnifiedGenotyperEngine {
|
|||
if ( alternateAllele.isReference() )
|
||||
continue;
|
||||
|
||||
// we are non-ref if the probability of being non-ref > the emit confidence.
|
||||
// the emit confidence is phred-scaled, say 30 => 10^-3.
|
||||
// the posterior AF > 0 is log10: -5 => 10^-5
|
||||
// we are non-ref if 10^-5 < 10^-3 => -5 < -3
|
||||
final boolean isNonRef = AFresult.isPolymorphic(alternateAllele, UAC.STANDARD_CONFIDENCE_FOR_EMITTING / -10.0);
|
||||
// Compute if the site is considered polymorphic with sufficient confidence relative to our
|
||||
// phred-scaled emission QUAL
|
||||
final boolean isNonRef = AFresult.isPolymorphicPhredScaledQual(alternateAllele, UAC.STANDARD_CONFIDENCE_FOR_EMITTING);
|
||||
|
||||
// if the most likely AC is not 0, then this is a good alternate allele to use
|
||||
if ( isNonRef ) {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ package org.broadinstitute.sting.gatk.walkers.genotyper.afcalc;
|
|||
import com.google.java.contract.Ensures;
|
||||
import com.google.java.contract.Requires;
|
||||
import org.broadinstitute.sting.utils.MathUtils;
|
||||
import org.broadinstitute.sting.utils.QualityUtils;
|
||||
import org.broadinstitute.sting.utils.Utils;
|
||||
import org.broadinstitute.sting.utils.variantcontext.Allele;
|
||||
|
||||
|
|
@ -234,10 +235,20 @@ public class AFCalcResult {
|
|||
*
|
||||
* @return true if there's enough confidence (relative to log10minPNonRef) to reject AF == 0
|
||||
*/
|
||||
@Requires("MathUtils.goodLog10Probability(log10minPNonRef)")
|
||||
public boolean isPolymorphic(final Allele allele, final double log10minPNonRef) {
|
||||
return getLog10PosteriorOfAFGt0ForAllele(allele) >= log10minPNonRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as #isPolymorphic but takes a phred-scaled quality score as input
|
||||
*/
|
||||
public boolean isPolymorphicPhredScaledQual(final Allele allele, final double minPNonRefPhredScaledQual) {
|
||||
if ( minPNonRefPhredScaledQual < 0 ) throw new IllegalArgumentException("phredScaledQual " + minPNonRefPhredScaledQual + " < 0 ");
|
||||
final double log10Threshold = Math.log10(QualityUtils.qualToProb(minPNonRefPhredScaledQual));
|
||||
return isPolymorphic(allele, log10Threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Are any of the alleles polymorphic w.r.t. #isPolymorphic?
|
||||
*
|
||||
|
|
|
|||
|
|
@ -329,7 +329,6 @@ public class PairHMMIndelErrorModel {
|
|||
getContextHomopolymerLength(readBases,hrunProfile);
|
||||
fillGapProbabilities(hrunProfile, contextLogGapOpenProbabilities, contextLogGapContinuationProbabilities);
|
||||
|
||||
|
||||
for (Allele a: haplotypeMap.keySet()) {
|
||||
|
||||
Haplotype haplotype = haplotypeMap.get(a);
|
||||
|
|
|
|||
|
|
@ -95,7 +95,8 @@ import static org.broadinstitute.sting.utils.codecs.vcf.VCFUtils.getVCFHeadersFr
|
|||
|
||||
@DocumentedGATKFeature( groupName = "Variant Discovery Tools", extraDocs = {CommandLineGATK.class} )
|
||||
public class ReadBackedPhasing extends RodWalker<PhasingStatsAndOutput, PhasingStats> {
|
||||
private static final boolean DEBUG = false;
|
||||
@Argument(fullName="debug", shortName="debug", doc="If specified, print out very verbose debug information (if -l DEBUG is also specified)", required = false)
|
||||
protected boolean DEBUG = false;
|
||||
/**
|
||||
* The VCF file we are phasing variants from.
|
||||
*
|
||||
|
|
@ -949,7 +950,7 @@ public class ReadBackedPhasing extends RodWalker<PhasingStatsAndOutput, PhasingS
|
|||
}
|
||||
|
||||
if (DEBUG) logger.debug("\nPhasing table [AFTER CALCULATION]:\n" + sampleHaps + "\n");
|
||||
MaxHaplotypeAndQuality maxHapQual = new MaxHaplotypeAndQuality(sampleHaps, true);
|
||||
MaxHaplotypeAndQuality maxHapQual = new MaxHaplotypeAndQuality(sampleHaps, DEBUG);
|
||||
double posteriorProb = maxHapQual.maxEntry.getScore().getValue();
|
||||
|
||||
if (DEBUG)
|
||||
|
|
@ -971,7 +972,7 @@ public class ReadBackedPhasing extends RodWalker<PhasingStatsAndOutput, PhasingS
|
|||
public MaxHaplotypeAndQuality(PhasingTable hapTable, boolean printDebug) {
|
||||
// Marginalize each haplotype to its first 2 positions:
|
||||
hapTable = HaplotypeTableCreator.marginalizeAsNewTable(hapTable);
|
||||
if (DEBUG && printDebug)
|
||||
if (printDebug)
|
||||
logger.debug("\nPhasing table [AFTER MAPPING]:\n" + hapTable + "\n");
|
||||
|
||||
calculateMaxHapAndPhasingQuality(hapTable, printDebug);
|
||||
|
|
@ -981,7 +982,7 @@ public class ReadBackedPhasing extends RodWalker<PhasingStatsAndOutput, PhasingS
|
|||
|
||||
private void calculateMaxHapAndPhasingQuality(PhasingTable hapTable, boolean printDebug) {
|
||||
hapTable.normalizeScores();
|
||||
if (DEBUG && printDebug)
|
||||
if (printDebug)
|
||||
logger.debug("\nPhasing table [AFTER NORMALIZATION]:\n" + hapTable + "\n");
|
||||
|
||||
// Determine the phase at this position:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import java.util.Set;
|
|||
/**
|
||||
* Stratifies the eval RODs by user-supplied JEXL expressions
|
||||
*
|
||||
* See http://www.broadinstitute.org/gsa/wiki/index.php/Using_JEXL_expressions for more details
|
||||
* See http://gatkforums.broadinstitute.org/discussion/1255/what-are-jexl-expressions-and-how-can-i-use-them-with-the-gatk for more details
|
||||
*/
|
||||
public class JexlExpression extends VariantStratifier implements StandardStratification {
|
||||
// needs to know the jexl expressions
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.broadinstitute.sting.utils.GenomeLoc;
|
|||
import org.broadinstitute.sting.utils.MathUtils;
|
||||
import org.broadinstitute.sting.utils.codecs.vcf.VCFConstants;
|
||||
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||
import org.broadinstitute.sting.utils.help.HelpUtils;
|
||||
import org.broadinstitute.sting.utils.variantcontext.writer.VariantContextWriter;
|
||||
import org.broadinstitute.sting.utils.collections.ExpandingArrayList;
|
||||
import org.broadinstitute.sting.utils.exceptions.UserException;
|
||||
|
|
@ -80,7 +81,7 @@ public class VariantDataManager {
|
|||
final double theSTD = standardDeviation(theMean, iii);
|
||||
logger.info( annotationKeys.get(iii) + String.format(": \t mean = %.2f\t standard deviation = %.2f", theMean, theSTD) );
|
||||
if( Double.isNaN(theMean) ) {
|
||||
throw new UserException.BadInput("Values for " + annotationKeys.get(iii) + " annotation not detected for ANY training variant in the input callset. VariantAnnotator may be used to add these annotations. See http://www.broadinstitute.org/gsa/wiki/index.php/VariantAnnotator");
|
||||
throw new UserException.BadInput("Values for " + annotationKeys.get(iii) + " annotation not detected for ANY training variant in the input callset. VariantAnnotator may be used to add these annotations. See " + HelpUtils.forumPost("discussion/49/using-variant-annotator"));
|
||||
}
|
||||
|
||||
foundZeroVarianceAnnotation = foundZeroVarianceAnnotation || (theSTD < 1E-6);
|
||||
|
|
|
|||
|
|
@ -51,8 +51,7 @@ import java.util.*;
|
|||
* The Variant Validation Assessor is a tool for vetting/assessing validation data (containing genotypes).
|
||||
* The tool produces a VCF that is annotated with information pertaining to plate quality control and by
|
||||
* default is soft-filtered by high no-call rate or low Hardy-Weinberg probability.
|
||||
* If you have .ped files, please first convert them to VCF format
|
||||
* (see http://www.broadinstitute.org/gsa/wiki/index.php/Converting_ped_to_vcf).
|
||||
* If you have .ped files, please first convert them to VCF format.
|
||||
*
|
||||
* <h2>Input</h2>
|
||||
* <p>
|
||||
|
|
|
|||
|
|
@ -210,13 +210,23 @@ public class JnaSession implements Session {
|
|||
}
|
||||
|
||||
public static void setAttribute(Pointer jt, String name, String value) throws DrmaaException {
|
||||
checkError(LibDrmaa.drmaa_set_attribute(jt, name, value, getError(), LibDrmaa.DRMAA_ERROR_STRING_BUFFER_LEN));
|
||||
if (getAttrNames().contains(name)) {
|
||||
checkError(LibDrmaa.drmaa_set_attribute(jt, name, value, getError(), LibDrmaa.DRMAA_ERROR_STRING_BUFFER_LEN));
|
||||
}
|
||||
else {
|
||||
throw new InvalidAttributeValueException("Attribute " + name + " is not supported by this implementation of DRMAA");
|
||||
}
|
||||
}
|
||||
|
||||
public static String getAttribute(Pointer jt, String name) throws DrmaaException {
|
||||
Memory attrBuffer = new Memory(LibDrmaa.DRMAA_ATTR_BUFFER);
|
||||
checkError(LibDrmaa.drmaa_get_attribute(jt, name, attrBuffer, LibDrmaa.DRMAA_ATTR_BUFFER_LEN, getError(), LibDrmaa.DRMAA_ERROR_STRING_BUFFER_LEN));
|
||||
return attrBuffer.getString(0);
|
||||
if (getAttrNames().contains(name)) {
|
||||
Memory attrBuffer = new Memory(LibDrmaa.DRMAA_ATTR_BUFFER);
|
||||
checkError(LibDrmaa.drmaa_get_attribute(jt, name, attrBuffer, LibDrmaa.DRMAA_ATTR_BUFFER_LEN, getError(), LibDrmaa.DRMAA_ERROR_STRING_BUFFER_LEN));
|
||||
return attrBuffer.getString(0);
|
||||
}
|
||||
else {
|
||||
throw new InvalidAttributeValueException("Attribute " + name + " is not supported by this implementation of DRMAA");
|
||||
}
|
||||
}
|
||||
|
||||
public static void setVectorAttribute(Pointer jt, String name, Collection<String> values) throws DrmaaException {
|
||||
|
|
|
|||
|
|
@ -495,4 +495,14 @@ public class GenomeLoc implements Comparable<GenomeLoc>, Serializable, HasGenome
|
|||
public long sizeOfOverlap( final GenomeLoc that ) {
|
||||
return ( this.overlapsP(that) ? Math.min( getStop(), that.getStop() ) - Math.max( getStart(), that.getStart() ) + 1L : 0L );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum GenomeLoc of this and other
|
||||
* @param other another non-null genome loc
|
||||
* @return the max of this and other
|
||||
*/
|
||||
public GenomeLoc max(final GenomeLoc other) {
|
||||
final int cmp = this.compareTo(other);
|
||||
return cmp == -1 ? other : this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -374,7 +374,7 @@ public final class GenomeLocParser {
|
|||
int start = 1;
|
||||
int stop = -1;
|
||||
|
||||
final int colonIndex = str.indexOf(":");
|
||||
final int colonIndex = str.lastIndexOf(":");
|
||||
if(colonIndex == -1) {
|
||||
contig = str.substring(0, str.length()); // chr1
|
||||
stop = Integer.MAX_VALUE;
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ public class Haplotype {
|
|||
protected final byte[] bases;
|
||||
protected final double[] quals;
|
||||
private GenomeLoc genomeLocation = null;
|
||||
private HashMap<String, double[]> readLikelihoodsPerSample = null;
|
||||
private HashMap<String, int[]> readCountsPerSample = null;
|
||||
private HashMap<Integer, VariantContext> eventMap = null;
|
||||
private boolean isRef = false;
|
||||
private Cigar cigar;
|
||||
|
|
@ -94,31 +92,6 @@ public class Haplotype {
|
|||
return Arrays.hashCode(bases);
|
||||
}
|
||||
|
||||
public void addReadLikelihoods( final String sample, final double[] readLikelihoods, final int[] readCounts ) {
|
||||
if( readLikelihoodsPerSample == null ) {
|
||||
readLikelihoodsPerSample = new HashMap<String, double[]>();
|
||||
}
|
||||
readLikelihoodsPerSample.put(sample, readLikelihoods);
|
||||
if( readCountsPerSample == null ) {
|
||||
readCountsPerSample = new HashMap<String, int[]>();
|
||||
}
|
||||
readCountsPerSample.put(sample, readCounts);
|
||||
}
|
||||
|
||||
@Ensures({"result != null"})
|
||||
public double[] getReadLikelihoods( final String sample ) {
|
||||
return readLikelihoodsPerSample.get(sample);
|
||||
}
|
||||
|
||||
@Ensures({"result != null"})
|
||||
public int[] getReadCounts( final String sample ) {
|
||||
return readCountsPerSample.get(sample);
|
||||
}
|
||||
|
||||
public Set<String> getSampleKeySet() {
|
||||
return readLikelihoodsPerSample.keySet();
|
||||
}
|
||||
|
||||
public HashMap<Integer, VariantContext> getEventMap() {
|
||||
return eventMap;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@ import net.sf.samtools.SAMUtils;
|
|||
* @author Kiran Garimella
|
||||
*/
|
||||
public class QualityUtils {
|
||||
public final static byte MAX_RECALIBRATED_Q_SCORE = 93;
|
||||
public final static byte MAX_RECALIBRATED_Q_SCORE = SAMUtils.MAX_PHRED_SCORE;
|
||||
public final static byte MAX_QUAL_SCORE = SAMUtils.MAX_PHRED_SCORE;
|
||||
public final static double ERROR_RATE_OF_MAX_QUAL_SCORE = qualToErrorProbRaw(MAX_QUAL_SCORE);
|
||||
|
||||
public final static double MIN_REASONABLE_ERROR = 0.0001;
|
||||
public final static byte MAX_REASONABLE_Q_SCORE = 40;
|
||||
public final static byte MAX_REASONABLE_Q_SCORE = 60; // quals above this value are extremely suspicious
|
||||
public final static byte MIN_USABLE_Q_SCORE = 6;
|
||||
public final static int MAPPING_QUALITY_UNAVAILABLE = 255;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package org.broadinstitute.sting.utils.activeregion;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: thibault
|
||||
* Date: 11/26/12
|
||||
* Time: 2:35 PM
|
||||
*
|
||||
* Describes how a read relates to an assigned ActiveRegion
|
||||
*/
|
||||
public enum ActiveRegionReadState {
|
||||
PRIMARY, // This is the read's primary region
|
||||
NONPRIMARY, // This region overlaps the read, but it is not primary
|
||||
EXTENDED, // This region would overlap the read if it were extended
|
||||
UNMAPPED // This read is not mapped
|
||||
}
|
||||
|
|
@ -406,10 +406,15 @@ public class BAQ {
|
|||
// so BQi = Qi - BAQi + 64
|
||||
byte[] bqTag = new byte[baq.length];
|
||||
for ( int i = 0; i < bqTag.length; i++) {
|
||||
int bq = (int)read.getBaseQualities()[i] + 64;
|
||||
int baq_i = (int)baq[i];
|
||||
int tag = bq - baq_i;
|
||||
if ( tag < 0 ) throw new ReviewedStingException("BAQ tag calculation error. BAQ value above base quality at " + read);
|
||||
final int bq = (int)read.getBaseQualities()[i] + 64;
|
||||
final int baq_i = (int)baq[i];
|
||||
final int tag = bq - baq_i;
|
||||
// problem with the calculation of the correction factor; this is our problem
|
||||
if ( tag < 0 )
|
||||
throw new ReviewedStingException("BAQ tag calculation error. BAQ value above base quality at " + read);
|
||||
// the original quality is too high, almost certainly due to using the wrong encoding in the BAM file
|
||||
if ( tag > Byte.MAX_VALUE )
|
||||
throw new UserException.MisencodedBAM(read, "we encountered an extremely high quality score (" + (int)read.getBaseQualities()[i] + ") with BAQ correction factor of " + baq_i);
|
||||
bqTag[i] = (byte)tag;
|
||||
}
|
||||
return new String(bqTag);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import net.sf.samtools.SAMSequenceDictionary;
|
|||
import org.broadinstitute.sting.gatk.phonehome.GATKRunReport;
|
||||
import org.broadinstitute.sting.utils.GenomeLoc;
|
||||
import org.broadinstitute.sting.utils.help.DocumentedGATKFeature;
|
||||
import org.broadinstitute.sting.utils.help.HelpUtils;
|
||||
import org.broadinstitute.sting.utils.sam.ReadUtils;
|
||||
import org.broadinstitute.sting.utils.variantcontext.VariantContext;
|
||||
|
||||
|
|
@ -239,6 +240,16 @@ public class UserException extends ReviewedStingException {
|
|||
}
|
||||
}
|
||||
|
||||
public static class MisencodedBAM extends UserException {
|
||||
public MisencodedBAM(SAMRecord read, String message) {
|
||||
this(read.getFileSource() != null ? read.getFileSource().getReader().toString() : "(none)", message);
|
||||
}
|
||||
|
||||
public MisencodedBAM(String source, String message) {
|
||||
super(String.format("SAM/BAM file %s appears to be using the wrong encoding for quality scores: %s; please see the GATK --help documentation for options related to this error", source, message));
|
||||
}
|
||||
}
|
||||
|
||||
public static class MalformedVCF extends UserException {
|
||||
public MalformedVCF(String message, String line) {
|
||||
super(String.format("The provided VCF file is malformed at line %s: %s", line, message));
|
||||
|
|
@ -267,7 +278,7 @@ public class UserException extends ReviewedStingException {
|
|||
|
||||
public static class ReadMissingReadGroup extends MalformedBAM {
|
||||
public ReadMissingReadGroup(SAMRecord read) {
|
||||
super(read, String.format("Read %s is either missing the read group or its read group is not defined in the BAM header, both of which are required by the GATK. Please use http://www.broadinstitute.org/gsa/wiki/index.php/ReplaceReadGroups to fix this problem", read.getReadName()));
|
||||
super(read, String.format("Read %s is either missing the read group or its read group is not defined in the BAM header, both of which are required by the GATK. Please use " + HelpUtils.forumPost("discussion/59/companion-utilities-replacereadgroups to fix this problem"), read.getReadName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -343,7 +354,7 @@ public class UserException extends ReviewedStingException {
|
|||
super(String.format("Lexicographically sorted human genome sequence detected in %s."
|
||||
+ "\nFor safety's sake the GATK requires human contigs in karyotypic order: 1, 2, ..., 10, 11, ..., 20, 21, 22, X, Y with M either leading or trailing these contigs."
|
||||
+ "\nThis is because all distributed GATK resources are sorted in karyotypic order, and your processing will fail when you need to use these files."
|
||||
+ "\nYou can use the ReorderSam utility to fix this problem: http://www.broadinstitute.org/gsa/wiki/index.php/ReorderSam"
|
||||
+ "\nYou can use the ReorderSam utility to fix this problem: " + HelpUtils.forumPost("discussion/58/companion-utilities-reordersam")
|
||||
+ "\n %s contigs = %s",
|
||||
name, name, ReadUtils.prettyPrintSequenceRecords(dict)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,10 +38,10 @@ import java.util.*;
|
|||
|
||||
public abstract class PerReadAlleleLikelihoodMap {
|
||||
|
||||
public static final double INDEL_LIKELIHOOD_THRESH = 0.1;
|
||||
public static final double INFORMATIVE_LIKELIHOOD_THRESHOLD = 0.1;
|
||||
|
||||
protected List<Allele> alleles;
|
||||
protected Map<GATKSAMRecord,Map<Allele,Double>> likelihoodReadMap;
|
||||
protected Map<GATKSAMRecord, Map<Allele, Double>> likelihoodReadMap;
|
||||
|
||||
public abstract void performPerAlleleDownsampling(final double downsamplingFraction, final PrintStream log);
|
||||
public abstract ReadBackedPileup createPerAlleleDownsampledBasePileup(final ReadBackedPileup pileup, final double downsamplingFraction, final PrintStream log);
|
||||
|
|
@ -68,7 +68,7 @@ public abstract class PerReadAlleleLikelihoodMap {
|
|||
}
|
||||
|
||||
public void add(PileupElement p, Allele a, Double likelihood) {
|
||||
add(p.getRead(),a,likelihood);
|
||||
add(p.getRead(), a, likelihood);
|
||||
}
|
||||
|
||||
public boolean containsPileupElement(PileupElement p) {
|
||||
|
|
@ -120,7 +120,7 @@ public abstract class PerReadAlleleLikelihoodMap {
|
|||
prevMaxLike = el.getValue();
|
||||
}
|
||||
}
|
||||
return (maxLike - prevMaxLike > INDEL_LIKELIHOOD_THRESH ? mostLikelyAllele : Allele.NO_CALL );
|
||||
return (maxLike - prevMaxLike > INFORMATIVE_LIKELIHOOD_THRESHOLD ? mostLikelyAllele : Allele.NO_CALL );
|
||||
}
|
||||
|
||||
public static PerReadAlleleLikelihoodMap getBestAvailablePerReadAlleleLikelihoodMap() {
|
||||
|
|
|
|||
|
|
@ -44,14 +44,13 @@ public class ForumAPIUtils {
|
|||
/**
|
||||
* How we post to the forum
|
||||
*/
|
||||
private final static String API_URL = "https://gatkforums.broadinstitute.org/api/v1/";
|
||||
final private static String ACCESS_TOKEN = "access_token=";
|
||||
|
||||
public static List<String> getPostedTools(String forumKey) {
|
||||
Gson gson = new Gson();
|
||||
List<String> output = new ArrayList<String>();
|
||||
|
||||
String text = httpGet(API_URL + "categories.json?CategoryIdentifier=tool-bulletin&page=1-100000&" + ACCESS_TOKEN + forumKey);
|
||||
String text = httpGet(HelpUtils.GATK_FORUM_API_URL + "categories.json?CategoryIdentifier=tool-bulletin&page=1-100000&" + ACCESS_TOKEN + forumKey);
|
||||
|
||||
APIQuery details = gson.fromJson(text, APIQuery.class);
|
||||
ForumDiscussion[] discussions = details.Discussions;
|
||||
|
|
@ -159,7 +158,7 @@ public class ForumAPIUtils {
|
|||
Gson gson = new Gson();
|
||||
|
||||
String data = gson.toJson(post.getPostData());
|
||||
httpPost(data, API_URL + "post/discussion.json?" + ACCESS_TOKEN + forumKey);
|
||||
httpPost(data, HelpUtils.GATK_FORUM_API_URL + "post/discussion.json?" + ACCESS_TOKEN + forumKey);
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -167,8 +166,7 @@ public class ForumAPIUtils {
|
|||
class APIQuery {
|
||||
ForumDiscussion[] Discussions;
|
||||
|
||||
public APIQuery() {
|
||||
}
|
||||
public APIQuery() {}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public class GATKDocUtils {
|
|||
/**
|
||||
* The URL root for RELEASED GATKDOC units
|
||||
*/
|
||||
public final static String URL_ROOT_FOR_RELEASE_GATKDOCS = "http://www.broadinstitute.org/gatk/gatkdocs/";
|
||||
public final static String URL_ROOT_FOR_RELEASE_GATKDOCS = HelpUtils.GATK_DOCS_URL;
|
||||
/**
|
||||
* The URL root for STABLE GATKDOC units
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -32,6 +32,16 @@ import org.broadinstitute.sting.utils.classloader.JVMUtils;
|
|||
import java.lang.reflect.Field;
|
||||
|
||||
public class HelpUtils {
|
||||
|
||||
public final static String BASE_GATK_URL = "http://www.broadinstitute.org/gatk";
|
||||
public final static String GATK_DOCS_URL = BASE_GATK_URL + "/gatkdocs/";
|
||||
public final static String GATK_FORUM_URL = "http://gatkforums.broadinstitute.org/";
|
||||
public final static String GATK_FORUM_API_URL = "https://gatkforums.broadinstitute.org/api/v1/";
|
||||
|
||||
public static String forumPost(String post) {
|
||||
return GATK_FORUM_URL + post;
|
||||
}
|
||||
|
||||
protected static boolean assignableToClass(ProgramElementDoc classDoc, Class lhsClass, boolean requireConcrete) {
|
||||
try {
|
||||
Class type = getClassForDoc(classDoc);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package org.broadinstitute.sting.utils.nanoScheduler;
|
|||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.broadinstitute.sting.utils.MultiThreadedErrorTracker;
|
||||
import org.broadinstitute.sting.utils.SimpleTimer;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
|
@ -19,11 +18,6 @@ class InputProducer<InputType> implements Runnable {
|
|||
*/
|
||||
final Iterator<InputType> inputReader;
|
||||
|
||||
/**
|
||||
* Our timer (may be null) that we use to track our input costs
|
||||
*/
|
||||
final SimpleTimer inputTimer;
|
||||
|
||||
/**
|
||||
* Where we put our input values for consumption
|
||||
*/
|
||||
|
|
@ -51,16 +45,13 @@ class InputProducer<InputType> implements Runnable {
|
|||
|
||||
public InputProducer(final Iterator<InputType> inputReader,
|
||||
final MultiThreadedErrorTracker errorTracker,
|
||||
final SimpleTimer inputTimer,
|
||||
final BlockingQueue<InputValue> outputQueue) {
|
||||
if ( inputReader == null ) throw new IllegalArgumentException("inputReader cannot be null");
|
||||
if ( errorTracker == null ) throw new IllegalArgumentException("errorTracker cannot be null");
|
||||
if ( inputTimer == null ) throw new IllegalArgumentException("inputTimer cannot be null");
|
||||
if ( outputQueue == null ) throw new IllegalArgumentException("OutputQueue cannot be null");
|
||||
|
||||
this.inputReader = inputReader;
|
||||
this.errorTracker = errorTracker;
|
||||
this.inputTimer = inputTimer;
|
||||
this.outputQueue = outputQueue;
|
||||
}
|
||||
|
||||
|
|
@ -94,16 +85,15 @@ class InputProducer<InputType> implements Runnable {
|
|||
* @throws InterruptedException
|
||||
*/
|
||||
private synchronized InputType readNextItem() throws InterruptedException {
|
||||
inputTimer.restart();
|
||||
if ( ! inputReader.hasNext() ) {
|
||||
// we are done, mark ourselves as such and return null
|
||||
readLastValue = true;
|
||||
inputTimer.stop();
|
||||
return null;
|
||||
} else {
|
||||
// get the next value, and return it
|
||||
final InputType input = inputReader.next();
|
||||
inputTimer.stop();
|
||||
if ( input == null )
|
||||
throw new IllegalStateException("inputReader.next() returned a null value, breaking our contract");
|
||||
nRead++;
|
||||
return input;
|
||||
}
|
||||
|
|
@ -121,6 +111,9 @@ class InputProducer<InputType> implements Runnable {
|
|||
final InputType value = readNextItem();
|
||||
|
||||
if ( value == null ) {
|
||||
if ( ! readLastValue )
|
||||
throw new IllegalStateException("value == null but readLastValue is false!");
|
||||
|
||||
// add the EOF object so our consumer knows we are done in all inputs
|
||||
// note that we do not increase inputID here, so that variable indicates the ID
|
||||
// of the last real value read from the queue
|
||||
|
|
@ -133,8 +126,10 @@ class InputProducer<InputType> implements Runnable {
|
|||
}
|
||||
|
||||
latch.countDown();
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
errorTracker.notifyOfError(ex);
|
||||
} finally {
|
||||
// logger.info("Exiting input thread readLastValue = " + readLastValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
package org.broadinstitute.sting.utils.nanoScheduler;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.broadinstitute.sting.utils.AutoFormattingTime;
|
||||
import org.broadinstitute.sting.utils.SimpleTimer;
|
||||
|
||||
/**
|
||||
* Holds runtime profile (input, read, map) times as tracked by NanoScheduler
|
||||
*
|
||||
* User: depristo
|
||||
* Date: 9/10/12
|
||||
* Time: 8:31 PM
|
||||
*/
|
||||
public class NSRuntimeProfile {
|
||||
final SimpleTimer outsideSchedulerTimer = new SimpleTimer("outside");
|
||||
final SimpleTimer inputTimer = new SimpleTimer("input");
|
||||
final SimpleTimer mapTimer = new SimpleTimer("map");
|
||||
final SimpleTimer reduceTimer = new SimpleTimer("reduce");
|
||||
|
||||
/**
|
||||
* Combine the elapsed time information from other with this profile
|
||||
*
|
||||
* @param other a non-null profile
|
||||
*/
|
||||
public void combine(final NSRuntimeProfile other) {
|
||||
outsideSchedulerTimer.addElapsed(other.outsideSchedulerTimer);
|
||||
inputTimer.addElapsed(other.inputTimer);
|
||||
mapTimer.addElapsed(other.mapTimer);
|
||||
reduceTimer.addElapsed(other.reduceTimer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the runtime profiling to logger
|
||||
*
|
||||
* @param logger
|
||||
*/
|
||||
public void log(final Logger logger) {
|
||||
log1(logger, "Input time", inputTimer);
|
||||
log1(logger, "Map time", mapTimer);
|
||||
log1(logger, "Reduce time", reduceTimer);
|
||||
log1(logger, "Outside time", outsideSchedulerTimer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the total runtime for all functions of this nano scheduler
|
||||
*/
|
||||
//@Ensures("result >= 0.0")
|
||||
public double totalRuntimeInSeconds() {
|
||||
return inputTimer.getElapsedTime()
|
||||
+ mapTimer.getElapsedTime()
|
||||
+ reduceTimer.getElapsedTime()
|
||||
+ outsideSchedulerTimer.getElapsedTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print to logger.info timing information from timer, with name label
|
||||
*
|
||||
* @param label the name of the timer to display. Should be human readable
|
||||
* @param timer the timer whose elapsed time we will display
|
||||
*/
|
||||
//@Requires({"label != null", "timer != null"})
|
||||
private void log1(final Logger logger, final String label, final SimpleTimer timer) {
|
||||
final double myTimeInSec = timer.getElapsedTime();
|
||||
final double myTimePercent = myTimeInSec / totalRuntimeInSeconds() * 100;
|
||||
logger.info(String.format("%s: %s (%5.2f%%)", label, new AutoFormattingTime(myTimeInSec), myTimePercent));
|
||||
}
|
||||
}
|
||||
|
|
@ -57,16 +57,6 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
boolean debug = false;
|
||||
private NSProgressFunction<InputType> progressFunction = null;
|
||||
|
||||
/**
|
||||
* Tracks the combined runtime profiles across all created nano schedulers
|
||||
*/
|
||||
final static private NSRuntimeProfile combinedNSRuntimeProfiler = new NSRuntimeProfile();
|
||||
|
||||
/**
|
||||
* The profile specific to this nano scheduler
|
||||
*/
|
||||
final private NSRuntimeProfile myNSRuntimeProfile = new NSRuntimeProfile();
|
||||
|
||||
/**
|
||||
* Create a new nanoscheduler with the desire characteristics requested by the argument
|
||||
*
|
||||
|
|
@ -94,9 +84,6 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
this.inputExecutor = Executors.newSingleThreadExecutor(new NamedThreadFactory("NS-input-thread-%d"));
|
||||
this.masterExecutor = Executors.newSingleThreadExecutor(new NamedThreadFactory("NS-master-thread-%d"));
|
||||
}
|
||||
|
||||
// start timing the time spent outside of the nanoScheduler
|
||||
myNSRuntimeProfile.outsideSchedulerTimer.start();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -123,11 +110,6 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
* After this call, execute cannot be invoked without throwing an error
|
||||
*/
|
||||
public void shutdown() {
|
||||
myNSRuntimeProfile.outsideSchedulerTimer.stop();
|
||||
|
||||
// add my timing information to the combined NS runtime profile
|
||||
combinedNSRuntimeProfiler.combine(myNSRuntimeProfile);
|
||||
|
||||
if ( nThreads > 1 ) {
|
||||
shutdownExecutor("inputExecutor", inputExecutor);
|
||||
shutdownExecutor("mapExecutor", mapExecutor);
|
||||
|
|
@ -137,19 +119,6 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
shutdown = true;
|
||||
}
|
||||
|
||||
public void printRuntimeProfile() {
|
||||
myNSRuntimeProfile.log(logger);
|
||||
}
|
||||
|
||||
public static void printCombinedRuntimeProfile() {
|
||||
if ( combinedNSRuntimeProfiler.totalRuntimeInSeconds() > 0.1 )
|
||||
combinedNSRuntimeProfiler.log(logger);
|
||||
}
|
||||
|
||||
protected double getTotalRuntime() {
|
||||
return myNSRuntimeProfile.totalRuntimeInSeconds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to cleanly shutdown an execution service, checking that the execution
|
||||
* state is clean when it's done.
|
||||
|
|
@ -245,8 +214,6 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
if ( map == null ) throw new IllegalArgumentException("map function cannot be null");
|
||||
if ( reduce == null ) throw new IllegalArgumentException("reduce function cannot be null");
|
||||
|
||||
myNSRuntimeProfile.outsideSchedulerTimer.stop();
|
||||
|
||||
ReduceType result;
|
||||
if ( ALLOW_SINGLE_THREAD_FASTPATH && getnThreads() == 1 ) {
|
||||
result = executeSingleThreaded(inputReader, map, initialValue, reduce);
|
||||
|
|
@ -254,7 +221,6 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
result = executeMultiThreaded(inputReader, map, initialValue, reduce);
|
||||
}
|
||||
|
||||
myNSRuntimeProfile.outsideSchedulerTimer.restart();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -273,28 +239,19 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
|
||||
while ( true ) {
|
||||
// start timer to ensure that both hasNext and next are caught by the timer
|
||||
myNSRuntimeProfile.inputTimer.restart();
|
||||
if ( ! inputReader.hasNext() ) {
|
||||
myNSRuntimeProfile.inputTimer.stop();
|
||||
break;
|
||||
} else {
|
||||
final InputType input = inputReader.next();
|
||||
myNSRuntimeProfile.inputTimer.stop();
|
||||
|
||||
// map
|
||||
myNSRuntimeProfile.mapTimer.restart();
|
||||
final long preMapTime = LOG_MAP_TIMES ? 0 : myNSRuntimeProfile.mapTimer.currentTimeNano();
|
||||
final MapType mapValue = map.apply(input);
|
||||
if ( LOG_MAP_TIMES ) logger.info("MAP TIME " + (myNSRuntimeProfile.mapTimer.currentTimeNano() - preMapTime));
|
||||
myNSRuntimeProfile.mapTimer.stop();
|
||||
|
||||
if ( i++ % this.bufferSize == 0 && progressFunction != null )
|
||||
if ( progressFunction != null )
|
||||
progressFunction.progress(input);
|
||||
|
||||
// reduce
|
||||
myNSRuntimeProfile.reduceTimer.restart();
|
||||
sum = reduce.apply(mapValue, sum);
|
||||
myNSRuntimeProfile.reduceTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -320,6 +277,7 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
while ( true ) {
|
||||
// check that no errors occurred while we were waiting
|
||||
handleErrors();
|
||||
// checkForDeadlocks();
|
||||
|
||||
try {
|
||||
final ReduceType result = reduceResult.get(100, TimeUnit.MILLISECONDS);
|
||||
|
|
@ -341,6 +299,26 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
}
|
||||
}
|
||||
|
||||
// private void checkForDeadlocks() {
|
||||
// if ( deadLockCheckCounter++ % 100 == 0 ) {
|
||||
// logger.info("Checking for deadlocks...");
|
||||
// final ThreadMXBean bean = ManagementFactory.getThreadMXBean();
|
||||
// final long[] threadIds = bean.findDeadlockedThreads(); // Returns null if no threads are deadlocked.
|
||||
//
|
||||
// if (threadIds != null) {
|
||||
// final ThreadInfo[] infos = bean.getThreadInfo(threadIds);
|
||||
//
|
||||
// logger.error("!!! Deadlock detected !!!!");
|
||||
// for (final ThreadInfo info : infos) {
|
||||
// logger.error("Thread " + info);
|
||||
// for ( final StackTraceElement elt : info.getStackTrace() ) {
|
||||
// logger.error("\t" + elt.toString());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private void handleErrors() {
|
||||
if ( errorTracker.hasAnErrorOccurred() ) {
|
||||
masterExecutor.shutdownNow();
|
||||
|
|
@ -380,7 +358,7 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
|
||||
// Create the input producer and start it running
|
||||
final InputProducer<InputType> inputProducer =
|
||||
new InputProducer<InputType>(inputReader, errorTracker, myNSRuntimeProfile.inputTimer, inputQueue);
|
||||
new InputProducer<InputType>(inputReader, errorTracker, inputQueue);
|
||||
inputExecutor.submit(inputProducer);
|
||||
|
||||
// a priority queue that stores up to bufferSize elements
|
||||
|
|
@ -389,7 +367,7 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
new PriorityBlockingQueue<MapResult<MapType>>();
|
||||
|
||||
final Reducer<MapType, ReduceType> reducer
|
||||
= new Reducer<MapType, ReduceType>(reduce, errorTracker, myNSRuntimeProfile.reduceTimer, initialValue);
|
||||
= new Reducer<MapType, ReduceType>(reduce, errorTracker, initialValue);
|
||||
|
||||
try {
|
||||
int nSubmittedJobs = 0;
|
||||
|
|
@ -408,7 +386,8 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
|
||||
// wait for all of the input and map threads to finish
|
||||
return waitForCompletion(inputProducer, reducer);
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
// logger.warn("Reduce job got exception " + ex);
|
||||
errorTracker.notifyOfError(ex);
|
||||
return initialValue;
|
||||
}
|
||||
|
|
@ -486,16 +465,12 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
final InputType input = inputWrapper.getValue();
|
||||
|
||||
// map
|
||||
myNSRuntimeProfile.mapTimer.restart();
|
||||
final long preMapTime = LOG_MAP_TIMES ? 0 : myNSRuntimeProfile.mapTimer.currentTimeNano();
|
||||
final MapType mapValue = map.apply(input);
|
||||
if ( LOG_MAP_TIMES ) logger.info("MAP TIME " + (myNSRuntimeProfile.mapTimer.currentTimeNano() - preMapTime));
|
||||
myNSRuntimeProfile.mapTimer.stop();
|
||||
|
||||
// enqueue the result into the mapResultQueue
|
||||
result = new MapResult<MapType>(mapValue, jobID);
|
||||
|
||||
if ( jobID % bufferSize == 0 && progressFunction != null )
|
||||
if ( progressFunction != null )
|
||||
progressFunction.progress(input);
|
||||
} else {
|
||||
// push back the EOF marker so other waiting threads can read it
|
||||
|
|
@ -508,7 +483,8 @@ public class NanoScheduler<InputType, MapType, ReduceType> {
|
|||
mapResultQueue.put(result);
|
||||
|
||||
final int nReduced = reducer.reduceAsMuchAsPossible(mapResultQueue);
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
// logger.warn("Map job got exception " + ex);
|
||||
errorTracker.notifyOfError(ex);
|
||||
} finally {
|
||||
// we finished a map job, release the job queue semaphore
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.google.java.contract.Ensures;
|
|||
import com.google.java.contract.Requires;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.broadinstitute.sting.utils.MultiThreadedErrorTracker;
|
||||
import org.broadinstitute.sting.utils.SimpleTimer;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
|
|
@ -34,7 +33,6 @@ class Reducer<MapType, ReduceType> {
|
|||
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
final NSReduceFunction<MapType, ReduceType> reduce;
|
||||
final SimpleTimer reduceTimer;
|
||||
final MultiThreadedErrorTracker errorTracker;
|
||||
|
||||
/**
|
||||
|
|
@ -61,20 +59,16 @@ class Reducer<MapType, ReduceType> {
|
|||
* reduceTimer
|
||||
*
|
||||
* @param reduce the reduce function to apply
|
||||
* @param reduceTimer the timer to time the reduce function call
|
||||
* @param initialSum the initial reduce sum
|
||||
*/
|
||||
public Reducer(final NSReduceFunction<MapType, ReduceType> reduce,
|
||||
final MultiThreadedErrorTracker errorTracker,
|
||||
final SimpleTimer reduceTimer,
|
||||
final ReduceType initialSum) {
|
||||
if ( errorTracker == null ) throw new IllegalArgumentException("Error tracker cannot be null");
|
||||
if ( reduce == null ) throw new IllegalArgumentException("Reduce function cannot be null");
|
||||
if ( reduceTimer == null ) throw new IllegalArgumentException("reduceTimer cannot be null");
|
||||
|
||||
this.errorTracker = errorTracker;
|
||||
this.reduce = reduce;
|
||||
this.reduceTimer = reduceTimer;
|
||||
this.sum = initialSum;
|
||||
}
|
||||
|
||||
|
|
@ -125,10 +119,7 @@ class Reducer<MapType, ReduceType> {
|
|||
nReducesNow++;
|
||||
|
||||
// apply reduce, keeping track of sum
|
||||
reduceTimer.restart();
|
||||
sum = reduce.apply(result.getValue(), sum);
|
||||
reduceTimer.stop();
|
||||
|
||||
}
|
||||
|
||||
numJobsReduced++;
|
||||
|
|
|
|||
|
|
@ -652,23 +652,19 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
|||
PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>) pileupElementTracker;
|
||||
PerSamplePileupElementTracker<PE> filteredTracker = new PerSamplePileupElementTracker<PE>();
|
||||
|
||||
int current = 0;
|
||||
|
||||
for (final String sample : tracker.getSamples()) {
|
||||
PileupElementTracker<PE> perSampleElements = tracker.getElements(sample);
|
||||
|
||||
List<PileupElement> filteredPileup = new ArrayList<PileupElement>();
|
||||
for (PileupElement p : perSampleElements) {
|
||||
int current = 0;
|
||||
UnifiedPileupElementTracker<PE> filteredPileup = new UnifiedPileupElementTracker<PE>();
|
||||
for (PE p : perSampleElements) {
|
||||
if (positions.contains(current))
|
||||
filteredPileup.add(p);
|
||||
}
|
||||
current++;
|
||||
|
||||
if (!filteredPileup.isEmpty()) {
|
||||
AbstractReadBackedPileup<RBP, PE> pileup = createNewPileup(loc, perSampleElements);
|
||||
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
||||
}
|
||||
|
||||
current++;
|
||||
filteredTracker.addElements(sample, filteredPileup);
|
||||
}
|
||||
|
||||
return (RBP) createNewPileup(loc, filteredTracker);
|
||||
|
|
@ -1058,6 +1054,11 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
|||
public FragmentCollection<PileupElement> toFragments() {
|
||||
return FragmentUtils.create(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadBackedPileup copy() {
|
||||
return new ReadBackedPileupImpl(loc, (PileupElementTracker<PileupElement>) pileupElementTracker.copy());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,11 +34,20 @@ import java.util.*;
|
|||
*/
|
||||
abstract class PileupElementTracker<PE extends PileupElement> implements Iterable<PE> {
|
||||
public abstract int size();
|
||||
public abstract PileupElementTracker<PE> copy();
|
||||
}
|
||||
|
||||
class UnifiedPileupElementTracker<PE extends PileupElement> extends PileupElementTracker<PE> {
|
||||
private final List<PE> pileup;
|
||||
|
||||
@Override
|
||||
public UnifiedPileupElementTracker<PE> copy() {
|
||||
UnifiedPileupElementTracker<PE> result = new UnifiedPileupElementTracker<PE>();
|
||||
for(PE element : pileup)
|
||||
result.add(element);
|
||||
return result;
|
||||
}
|
||||
|
||||
public UnifiedPileupElementTracker() { pileup = new LinkedList<PE>(); }
|
||||
public UnifiedPileupElementTracker(List<PE> pileup) { this.pileup = pileup; }
|
||||
|
||||
|
|
@ -65,6 +74,14 @@ class PerSamplePileupElementTracker<PE extends PileupElement> extends PileupElem
|
|||
pileup = new HashMap<String,PileupElementTracker<PE>>();
|
||||
}
|
||||
|
||||
public PerSamplePileupElementTracker<PE> copy() {
|
||||
PerSamplePileupElementTracker<PE> result = new PerSamplePileupElementTracker<PE>();
|
||||
for (Map.Entry<String, PileupElementTracker<PE>> entry : pileup.entrySet())
|
||||
result.addElements(entry.getKey(), entry.getValue());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of all the samples stored in this pileup.
|
||||
* @return List of samples in this pileup.
|
||||
|
|
|
|||
|
|
@ -283,4 +283,12 @@ public interface ReadBackedPileup extends Iterable<PileupElement>, HasGenomeLoca
|
|||
* @return
|
||||
*/
|
||||
public FragmentCollection<PileupElement> toFragments();
|
||||
|
||||
/**
|
||||
* Creates a full copy (not shallow) of the ReadBacked Pileup
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public ReadBackedPileup copy();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ package org.broadinstitute.sting.utils.progressmeter;
|
|||
|
||||
import com.google.java.contract.Ensures;
|
||||
import com.google.java.contract.Invariant;
|
||||
import com.google.java.contract.Requires;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.broadinstitute.sting.utils.*;
|
||||
import org.broadinstitute.sting.utils.exceptions.UserException;
|
||||
|
|
@ -143,6 +144,12 @@ public class ProgressMeter {
|
|||
/** We use the SimpleTimer to time our run */
|
||||
private final SimpleTimer timer = new SimpleTimer();
|
||||
|
||||
private GenomeLoc maxGenomeLoc = null;
|
||||
private String positionMessage = "starting";
|
||||
private long nTotalRecordsProcessed = 0;
|
||||
|
||||
final ProgressMeterDaemon progressMeterDaemon;
|
||||
|
||||
/**
|
||||
* Create a new ProgressMeter
|
||||
*
|
||||
|
|
@ -177,21 +184,15 @@ public class ProgressMeter {
|
|||
targetSizeInBP = processingIntervals.coveredSize();
|
||||
|
||||
// start up the timer
|
||||
progressMeterDaemon = new ProgressMeterDaemon(this);
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward request to notifyOfProgress
|
||||
*
|
||||
* Assumes that one cycle has been completed
|
||||
*
|
||||
* @param loc our current location. Null means "in unmapped reads"
|
||||
* @param nTotalRecordsProcessed the total number of records we've processed
|
||||
* Start up the progress meter, printing initialization message and starting up the
|
||||
* daemon thread for periodic printing.
|
||||
*/
|
||||
public void notifyOfProgress(final GenomeLoc loc, final long nTotalRecordsProcessed) {
|
||||
notifyOfProgress(loc, false, nTotalRecordsProcessed);
|
||||
}
|
||||
|
||||
@Requires("progressMeterDaemon != null")
|
||||
private synchronized void start() {
|
||||
timer.start();
|
||||
lastProgressPrintTime = timer.currentTime();
|
||||
|
|
@ -199,6 +200,8 @@ public class ProgressMeter {
|
|||
logger.info("[INITIALIZATION COMPLETE; STARTING PROCESSING]");
|
||||
logger.info(String.format("%15s processed.%s runtime per.1M.%s completed total.runtime remaining",
|
||||
"Location", processingUnitName, processingUnitName));
|
||||
|
||||
progressMeterDaemon.start();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -216,19 +219,41 @@ public class ProgressMeter {
|
|||
* Synchronized to ensure that even with multiple threads calling notifyOfProgress we still
|
||||
* get one clean stream of meter logs.
|
||||
*
|
||||
* Note this thread doesn't actually print progress, unless must print is true, but just registers
|
||||
* the progress itself. A separate printing daemon periodically polls the meter to print out
|
||||
* progress
|
||||
*
|
||||
* @param loc Current location, can be null if you are at the end of the processing unit
|
||||
* @param mustPrint If true, will print out info, regardless of time interval
|
||||
* @param nTotalRecordsProcessed the total number of records we've processed
|
||||
*/
|
||||
private synchronized void notifyOfProgress(final GenomeLoc loc, boolean mustPrint, final long nTotalRecordsProcessed) {
|
||||
public synchronized void notifyOfProgress(final GenomeLoc loc, final long nTotalRecordsProcessed) {
|
||||
if ( nTotalRecordsProcessed < 0 ) throw new IllegalArgumentException("nTotalRecordsProcessed must be >= 0");
|
||||
|
||||
// weird comparison to ensure that loc == null (in unmapped reads) is keep before maxGenomeLoc == null (on startup)
|
||||
this.maxGenomeLoc = loc == null ? loc : (maxGenomeLoc == null ? loc : loc.max(maxGenomeLoc));
|
||||
this.nTotalRecordsProcessed = Math.max(this.nTotalRecordsProcessed, nTotalRecordsProcessed);
|
||||
|
||||
// a pretty name for our position
|
||||
this.positionMessage = maxGenomeLoc == null
|
||||
? "unmapped reads"
|
||||
: String.format("%s:%d", maxGenomeLoc.getContig(), maxGenomeLoc.getStart());
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually try to print out progress
|
||||
*
|
||||
* This function may print out if the progress print is due, but if not enough time has elapsed
|
||||
* since the last print we will not print out information.
|
||||
*
|
||||
* @param mustPrint if true, progress will be printed regardless of the last time we printed progress
|
||||
*/
|
||||
protected synchronized void printProgress(final boolean mustPrint) {
|
||||
final long curTime = timer.currentTime();
|
||||
final boolean printProgress = mustPrint || maxElapsedIntervalForPrinting(curTime, lastProgressPrintTime, progressPrintFrequency);
|
||||
final boolean printLog = performanceLog != null && maxElapsedIntervalForPrinting(curTime, lastPerformanceLogPrintTime, PERFORMANCE_LOG_PRINT_FREQUENCY);
|
||||
|
||||
if ( printProgress || printLog ) {
|
||||
final ProgressMeterData progressData = takeProgressSnapshot(loc, nTotalRecordsProcessed);
|
||||
final ProgressMeterData progressData = takeProgressSnapshot(maxGenomeLoc, nTotalRecordsProcessed);
|
||||
|
||||
final AutoFormattingTime elapsed = new AutoFormattingTime(progressData.getElapsedSeconds());
|
||||
final AutoFormattingTime bpRate = new AutoFormattingTime(progressData.secondsPerMillionBP());
|
||||
|
|
@ -241,13 +266,8 @@ public class ProgressMeter {
|
|||
lastProgressPrintTime = curTime;
|
||||
updateLoggerPrintFrequency(estTotalRuntime.getTimeInSeconds());
|
||||
|
||||
// a pretty name for our position
|
||||
final String posName = loc == null
|
||||
? (mustPrint ? "done" : "unmapped reads")
|
||||
: String.format("%s:%d", loc.getContig(), loc.getStart());
|
||||
|
||||
logger.info(String.format("%15s %5.2e %s %s %5.1f%% %s %s",
|
||||
posName, progressData.getUnitsProcessed()*1.0, elapsed, unitRate,
|
||||
positionMessage, progressData.getUnitsProcessed()*1.0, elapsed, unitRate,
|
||||
100*fractionGenomeTargetCompleted, estTotalRuntime, timeToCompletion));
|
||||
|
||||
}
|
||||
|
|
@ -296,13 +316,18 @@ public class ProgressMeter {
|
|||
*/
|
||||
public void notifyDone(final long nTotalRecordsProcessed) {
|
||||
// print out the progress meter
|
||||
notifyOfProgress(null, true, nTotalRecordsProcessed);
|
||||
this.nTotalRecordsProcessed = nTotalRecordsProcessed;
|
||||
this.positionMessage = "done";
|
||||
printProgress(true);
|
||||
|
||||
logger.info(String.format("Total runtime %.2f secs, %.2f min, %.2f hours",
|
||||
timer.getElapsedTime(), timer.getElapsedTime() / 60, timer.getElapsedTime() / 3600));
|
||||
|
||||
if ( performanceLog != null )
|
||||
performanceLog.close();
|
||||
|
||||
// shutdown our daemon thread
|
||||
progressMeterDaemon.done();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
package org.broadinstitute.sting.utils.progressmeter;
|
||||
|
||||
/**
|
||||
* Daemon thread that periodically prints the progress of the progress meter
|
||||
*
|
||||
* User: depristo
|
||||
* Date: 12/4/12
|
||||
* Time: 9:16 PM
|
||||
*/
|
||||
public final class ProgressMeterDaemon extends Thread {
|
||||
/**
|
||||
* How frequently should we poll and print progress?
|
||||
*/
|
||||
private final static long POLL_FREQUENCY_MILLISECONDS = 10 * 1000;
|
||||
|
||||
/**
|
||||
* Are we to continue periodically printing status, or should we shut down?
|
||||
*/
|
||||
boolean done = false;
|
||||
|
||||
/**
|
||||
* The meter we will call print on
|
||||
*/
|
||||
final ProgressMeter meter;
|
||||
|
||||
/**
|
||||
* Create a new ProgressMeterDaemon printing progress for meter
|
||||
* @param meter the progress meter to print progress of
|
||||
*/
|
||||
public ProgressMeterDaemon(final ProgressMeter meter) {
|
||||
if ( meter == null ) throw new IllegalArgumentException("meter cannot be null");
|
||||
this.meter = meter;
|
||||
setDaemon(true);
|
||||
setName("ProgressMeterDaemon");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells this daemon thread to shutdown at the next opportunity, as the progress
|
||||
* metering is complete.
|
||||
*/
|
||||
public final void done() {
|
||||
this.done = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start up the ProgressMeterDaemon, polling every tens of seconds to print, if
|
||||
* necessary, the provided progress meter. Never exits until the JVM is complete,
|
||||
* or done() is called, as the thread is a daemon thread
|
||||
*/
|
||||
public void run() {
|
||||
while (! done) {
|
||||
meter.printProgress(false);
|
||||
try {
|
||||
Thread.sleep(POLL_FREQUENCY_MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package org.broadinstitute.sting.utils.recalibration.covariates;
|
||||
|
||||
import org.broadinstitute.sting.gatk.walkers.bqsr.RecalibrationArgumentCollection;
|
||||
import org.broadinstitute.sting.gatk.walkers.varianteval.stratifications.TandemRepeat;
|
||||
import org.broadinstitute.sting.utils.QualityUtils;
|
||||
import org.broadinstitute.sting.utils.recalibration.ReadCovariates;
|
||||
import org.broadinstitute.sting.utils.sam.GATKSAMRecord;
|
||||
import org.broadinstitute.sting.utils.variantcontext.VariantContextUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: rpoplin
|
||||
* Date: 11/3/12
|
||||
*/
|
||||
|
||||
public class RepeatLengthCovariate implements ExperimentalCovariate {
|
||||
final int MAX_REPEAT_LENGTH = 20;
|
||||
|
||||
// Initialize any member variables using the command-line arguments passed to the walkers
|
||||
@Override
|
||||
public void initialize(final RecalibrationArgumentCollection RAC) {}
|
||||
|
||||
@Override
|
||||
public void recordValues(final GATKSAMRecord read, final ReadCovariates values) {
|
||||
byte[] readBytes = read.getReadBases();
|
||||
for (int i = 0; i < readBytes.length; i++) {
|
||||
int maxRL = 0;
|
||||
for (int str = 1; str <= 8; str++) {
|
||||
if (i + str <= readBytes.length) {
|
||||
maxRL = Math.max(maxRL, VariantContextUtils.findNumberofRepetitions(
|
||||
Arrays.copyOfRange(readBytes,i,i + str),
|
||||
Arrays.copyOfRange(readBytes,i,readBytes.length)
|
||||
));
|
||||
}
|
||||
}
|
||||
if(maxRL > MAX_REPEAT_LENGTH) { maxRL = MAX_REPEAT_LENGTH; }
|
||||
values.addCovariate(maxRL, maxRL, maxRL, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Used to get the covariate's value from input csv file during on-the-fly recalibration
|
||||
@Override
|
||||
public final Object getValue(final String str) {
|
||||
return Byte.parseByte(str);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatKey(final int key) {
|
||||
return String.format("%d", key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int keyFromValue(final Object value) {
|
||||
return (value instanceof String) ? Integer.parseInt((String) value) : (Integer) value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maximumKeyValue() {
|
||||
return MAX_REPEAT_LENGTH + 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -397,6 +397,9 @@ public class GATKSAMRecord extends BAMRecord {
|
|||
else if (op != CigarOperator.HARD_CLIP)
|
||||
break;
|
||||
}
|
||||
|
||||
if ( softStart < 1 )
|
||||
softStart = 1;
|
||||
}
|
||||
return softStart;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
package org.broadinstitute.sting.utils.sam;
|
||||
|
||||
import org.broadinstitute.sting.gatk.GenomeAnalysisEngine;
|
||||
import org.broadinstitute.sting.gatk.iterators.ReadTransformer;
|
||||
import org.broadinstitute.sting.gatk.walkers.Walker;
|
||||
import org.broadinstitute.sting.utils.QualityUtils;
|
||||
import org.broadinstitute.sting.utils.exceptions.UserException;
|
||||
|
||||
/**
|
||||
* Checks for and errors out (or fixes if requested) when it detects reads with base qualities that are not encoded with
|
||||
* phred-scaled quality scores. Q0 == ASCII 33 according to the SAM specification, whereas Illumina encoding starts at
|
||||
* Q64. The idea here is simple: if we are asked to fix the scores then we just subtract 31 from every quality score.
|
||||
* Otherwise, we randomly sample reads (for efficiency) and error out if we encounter a qual that's too high.
|
||||
*/
|
||||
public class MisencodedBaseQualityReadTransformer extends ReadTransformer {
|
||||
|
||||
private static final int samplingFrequency = 1000; // sample 1 read for every 1000 encountered
|
||||
private static final int encodingFixValue = 31; // Illumina_64 - PHRED_33
|
||||
|
||||
private boolean disabled;
|
||||
private boolean fixQuals;
|
||||
private static int currentReadCounter = 0;
|
||||
|
||||
@Override
|
||||
public ApplicationTime initializeSub(final GenomeAnalysisEngine engine, final Walker walker) {
|
||||
fixQuals = engine.getArguments().FIX_MISENCODED_QUALS;
|
||||
disabled = !fixQuals && engine.getArguments().ALLOW_POTENTIALLY_MISENCODED_QUALS;
|
||||
|
||||
return ReadTransformer.ApplicationTime.ON_INPUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enabled() {
|
||||
return !disabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GATKSAMRecord apply(final GATKSAMRecord read) {
|
||||
if ( fixQuals )
|
||||
return fixMisencodedQuals(read);
|
||||
|
||||
checkForMisencodedQuals(read);
|
||||
return read;
|
||||
}
|
||||
|
||||
protected static GATKSAMRecord fixMisencodedQuals(final GATKSAMRecord read) {
|
||||
final byte[] quals = read.getBaseQualities();
|
||||
for ( int i = 0; i < quals.length; i++ ) {
|
||||
quals[i] -= encodingFixValue;
|
||||
}
|
||||
read.setBaseQualities(quals);
|
||||
return read;
|
||||
}
|
||||
|
||||
protected static void checkForMisencodedQuals(final GATKSAMRecord read) {
|
||||
// sample reads randomly for checking
|
||||
if ( ++currentReadCounter >= samplingFrequency ) {
|
||||
currentReadCounter = 0;
|
||||
|
||||
final byte[] quals = read.getBaseQualities();
|
||||
for ( final byte qual : quals ) {
|
||||
if ( qual > QualityUtils.MAX_REASONABLE_Q_SCORE )
|
||||
throw new UserException.MisencodedBAM(read, "we encountered an extremely high quality score of " + (int)qual);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1267,7 +1267,7 @@ public class VariantContextUtils {
|
|||
* @param testString String to test
|
||||
* @return Number of repetitions (0 if testString is not a concatenation of n repeatUnit's
|
||||
*/
|
||||
protected static int findNumberofRepetitions(byte[] repeatUnit, byte[] testString) {
|
||||
public static int findNumberofRepetitions(byte[] repeatUnit, byte[] testString) {
|
||||
int numRepeats = 0;
|
||||
for (int start = 0; start < testString.length; start += repeatUnit.length) {
|
||||
int end = start + repeatUnit.length;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ abstract class SortingVariantContextWriterBase implements VariantContextWriter {
|
|||
this.takeOwnershipOfInner = takeOwnershipOfInner;
|
||||
|
||||
// has to be PriorityBlockingQueue to be thread-safe
|
||||
// see http://getsatisfaction.com/gsa/topics/missing_loci_output_in_multi_thread_mode_when_implement_sortingvcfwriterbase?utm_content=topic_link&utm_medium=email&utm_source=new_topic
|
||||
this.queue = new PriorityBlockingQueue<VCFRecord>(50, new VariantContextComparator());
|
||||
|
||||
this.mostUpstreamWritableLoc = BEFORE_MOST_UPSTREAM_LOC;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package org.broadinstitute.sting.gatk.traversals;
|
||||
|
||||
import com.google.java.contract.PreconditionError;
|
||||
import net.sf.samtools.*;
|
||||
import org.broadinstitute.sting.utils.activeregion.ActiveRegionReadState;
|
||||
import org.broadinstitute.sting.utils.interval.IntervalMergingRule;
|
||||
import org.broadinstitute.sting.utils.interval.IntervalUtils;
|
||||
import org.broadinstitute.sting.utils.sam.GATKSAMRecord;
|
||||
|
|
@ -23,6 +25,7 @@ import org.broadinstitute.sting.utils.activeregion.ActiveRegion;
|
|||
import org.broadinstitute.sting.utils.activeregion.ActivityProfileResult;
|
||||
import org.broadinstitute.sting.utils.fasta.CachingIndexedFastaSequenceFile;
|
||||
import org.broadinstitute.sting.utils.sam.ArtificialSAMUtils;
|
||||
import org.broadinstitute.sting.utils.sam.ReadUtils;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
|
@ -45,6 +48,8 @@ public class TraverseActiveRegionsTest extends BaseTest {
|
|||
|
||||
private class DummyActiveRegionWalker extends ActiveRegionWalker<Integer, Integer> {
|
||||
private final double prob;
|
||||
private EnumSet<ActiveRegionReadState> states = super.desiredReadStates();
|
||||
|
||||
protected List<GenomeLoc> isActiveCalls = new ArrayList<GenomeLoc>();
|
||||
protected Map<GenomeLoc, ActiveRegion> mappedActiveRegions = new HashMap<GenomeLoc, ActiveRegion>();
|
||||
|
||||
|
|
@ -52,6 +57,20 @@ public class TraverseActiveRegionsTest extends BaseTest {
|
|||
this.prob = 1.0;
|
||||
}
|
||||
|
||||
public DummyActiveRegionWalker(double constProb) {
|
||||
this.prob = constProb;
|
||||
}
|
||||
|
||||
public DummyActiveRegionWalker(EnumSet<ActiveRegionReadState> wantStates) {
|
||||
this.prob = 1.0;
|
||||
this.states = wantStates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<ActiveRegionReadState> desiredReadStates() {
|
||||
return states;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActivityProfileResult isActive(RefMetaDataTracker tracker, ReferenceContext ref, AlignmentContext context) {
|
||||
isActiveCalls.add(ref.getLocus());
|
||||
|
|
@ -82,7 +101,7 @@ public class TraverseActiveRegionsTest extends BaseTest {
|
|||
private GenomeLocParser genomeLocParser;
|
||||
|
||||
private List<GenomeLoc> intervals;
|
||||
private List<SAMRecord> reads;
|
||||
private List<GATKSAMRecord> reads;
|
||||
|
||||
@BeforeClass
|
||||
private void init() throws FileNotFoundException {
|
||||
|
|
@ -96,21 +115,21 @@ public class TraverseActiveRegionsTest extends BaseTest {
|
|||
intervals.add(genomeLocParser.createGenomeLoc("1", 1000, 1999));
|
||||
intervals.add(genomeLocParser.createGenomeLoc("1", 2000, 2999));
|
||||
intervals.add(genomeLocParser.createGenomeLoc("1", 10000, 20000));
|
||||
// TODO: this fails!
|
||||
//intervals.add(genomeLocParser.createGenomeLoc("20", 10000, 20000));
|
||||
intervals.add(genomeLocParser.createGenomeLoc("20", 10000, 10100));
|
||||
intervals = IntervalUtils.sortAndMergeIntervals(genomeLocParser, intervals, IntervalMergingRule.OVERLAPPING_ONLY).toList();
|
||||
|
||||
reads = new ArrayList<SAMRecord>();
|
||||
reads = new ArrayList<GATKSAMRecord>();
|
||||
reads.add(buildSAMRecord("simple", "1", 100, 200));
|
||||
reads.add(buildSAMRecord("overlap_equal", "1", 10, 20));
|
||||
reads.add(buildSAMRecord("overlap_unequal", "1", 10, 21));
|
||||
reads.add(buildSAMRecord("boundary_equal", "1", 1990, 2009));
|
||||
reads.add(buildSAMRecord("boundary_unequal", "1", 1995, 2050));
|
||||
reads.add(buildSAMRecord("extended_only", "1", 3000, 3100));
|
||||
reads.add(buildSAMRecord("boundary_unequal", "1", 1990, 2008));
|
||||
reads.add(buildSAMRecord("extended_and_np", "1", 990, 1990));
|
||||
reads.add(buildSAMRecord("outside_intervals", "1", 5000, 6000));
|
||||
// TODO
|
||||
//reads.add(buildSAMRecord("simple20", "20", 10100, 10150));
|
||||
reads.add(buildSAMRecord("simple20", "20", 10025, 10075));
|
||||
|
||||
// required by LocusIteratorByState, and I prefer to list them in test case order above
|
||||
ReadUtils.sortReadsByCoordinate(reads);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -134,6 +153,18 @@ public class TraverseActiveRegionsTest extends BaseTest {
|
|||
return activeIntervals;
|
||||
}
|
||||
|
||||
@Test (expectedExceptions = PreconditionError.class)
|
||||
public void testIsActiveRangeLow () {
|
||||
DummyActiveRegionWalker walker = new DummyActiveRegionWalker(-0.1);
|
||||
getActiveRegions(walker, intervals).values();
|
||||
}
|
||||
|
||||
@Test (expectedExceptions = PreconditionError.class)
|
||||
public void testIsActiveRangeHigh () {
|
||||
DummyActiveRegionWalker walker = new DummyActiveRegionWalker(1.1);
|
||||
getActiveRegions(walker, intervals).values();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActiveRegionCoverage() {
|
||||
DummyActiveRegionWalker walker = new DummyActiveRegionWalker();
|
||||
|
|
@ -187,80 +218,210 @@ public class TraverseActiveRegionsTest extends BaseTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testReadMapping() {
|
||||
public void testPrimaryReadMapping() {
|
||||
DummyActiveRegionWalker walker = new DummyActiveRegionWalker();
|
||||
|
||||
// Contract: Each read has the Primary state in a single region (or none)
|
||||
// This is the region of maximum overlap for the read (earlier if tied)
|
||||
|
||||
// simple: Primary in 1:1-999
|
||||
// overlap_equal: Primary in 1:1-999
|
||||
// overlap_unequal: Primary in 1:1-999
|
||||
// boundary_equal: Non-Primary in 1:1000-1999, Primary in 1:2000-2999
|
||||
// boundary_unequal: Primary in 1:1000-1999, Non-Primary in 1:2000-2999
|
||||
// extended_and_np: Non-Primary in 1:1-999, Primary in 1:1000-1999, Extended in 1:2000-2999
|
||||
// outside_intervals: none
|
||||
// simple20: Primary in 20:10000-10100
|
||||
|
||||
Map<GenomeLoc, ActiveRegion> activeRegions = getActiveRegions(walker, intervals);
|
||||
ActiveRegion region;
|
||||
|
||||
region = activeRegions.get(genomeLocParser.createGenomeLoc("1", 1, 999));
|
||||
|
||||
getRead(region, "simple");
|
||||
getRead(region, "overlap_equal");
|
||||
getRead(region, "overlap_unequal");
|
||||
verifyReadNotPlaced(region, "boundary_equal");
|
||||
verifyReadNotPlaced(region, "boundary_unequal");
|
||||
verifyReadNotPlaced(region, "extended_and_np");
|
||||
verifyReadNotPlaced(region, "outside_intervals");
|
||||
verifyReadNotPlaced(region, "simple20");
|
||||
|
||||
region = activeRegions.get(genomeLocParser.createGenomeLoc("1", 1000, 1999));
|
||||
|
||||
verifyReadNotPlaced(region, "simple");
|
||||
verifyReadNotPlaced(region, "overlap_equal");
|
||||
verifyReadNotPlaced(region, "overlap_unequal");
|
||||
verifyReadNotPlaced(region, "boundary_equal");
|
||||
getRead(region, "boundary_unequal");
|
||||
getRead(region, "extended_and_np");
|
||||
verifyReadNotPlaced(region, "outside_intervals");
|
||||
verifyReadNotPlaced(region, "simple20");
|
||||
|
||||
region = activeRegions.get(genomeLocParser.createGenomeLoc("1", 2000, 2999));
|
||||
|
||||
verifyReadNotPlaced(region, "simple");
|
||||
verifyReadNotPlaced(region, "overlap_equal");
|
||||
verifyReadNotPlaced(region, "overlap_unequal");
|
||||
getRead(region, "boundary_equal");
|
||||
verifyReadNotPlaced(region, "boundary_unequal");
|
||||
verifyReadNotPlaced(region, "extended_and_np");
|
||||
verifyReadNotPlaced(region, "outside_intervals");
|
||||
verifyReadNotPlaced(region, "simple20");
|
||||
|
||||
region = activeRegions.get(genomeLocParser.createGenomeLoc("20", 10000, 10100));
|
||||
|
||||
verifyReadNotPlaced(region, "simple");
|
||||
verifyReadNotPlaced(region, "overlap_equal");
|
||||
verifyReadNotPlaced(region, "overlap_unequal");
|
||||
verifyReadNotPlaced(region, "boundary_equal");
|
||||
verifyReadNotPlaced(region, "boundary_unequal");
|
||||
verifyReadNotPlaced(region, "extended_and_np");
|
||||
verifyReadNotPlaced(region, "outside_intervals");
|
||||
getRead(region, "simple20");
|
||||
|
||||
// TODO: more tests and edge cases
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonPrimaryReadMapping() {
|
||||
DummyActiveRegionWalker walker = new DummyActiveRegionWalker(
|
||||
EnumSet.of(ActiveRegionReadState.PRIMARY, ActiveRegionReadState.NONPRIMARY));
|
||||
|
||||
// Contract: Each read has the Primary state in a single region (or none)
|
||||
// This is the region of maximum overlap for the read (earlier if tied)
|
||||
|
||||
// Contract: Each read has the Non-Primary state in all other regions it overlaps
|
||||
|
||||
// simple: Primary in 1:1-999
|
||||
// overlap_equal: Primary in 1:1-999
|
||||
// overlap_unequal: Primary in 1:1-999
|
||||
// boundary_equal: Non-Primary in 1:1000-1999, Primary in 1:2000-2999
|
||||
// boundary_unequal: Primary in 1:1000-1999, Non-Primary in 1:2000-2999
|
||||
// extended_and_np: Non-Primary in 1:1-999, Primary in 1:1000-1999, Extended in 1:2000-2999
|
||||
// outside_intervals: none
|
||||
// simple20: Primary in 20:10000-10100
|
||||
|
||||
Map<GenomeLoc, ActiveRegion> activeRegions = getActiveRegions(walker, intervals);
|
||||
ActiveRegion region;
|
||||
|
||||
region = activeRegions.get(genomeLocParser.createGenomeLoc("1", 1, 999));
|
||||
|
||||
getRead(region, "simple");
|
||||
getRead(region, "overlap_equal");
|
||||
getRead(region, "overlap_unequal");
|
||||
verifyReadNotPlaced(region, "boundary_equal");
|
||||
verifyReadNotPlaced(region, "boundary_unequal");
|
||||
getRead(region, "extended_and_np");
|
||||
verifyReadNotPlaced(region, "outside_intervals");
|
||||
verifyReadNotPlaced(region, "simple20");
|
||||
|
||||
region = activeRegions.get(genomeLocParser.createGenomeLoc("1", 1000, 1999));
|
||||
|
||||
verifyReadNotPlaced(region, "simple");
|
||||
verifyReadNotPlaced(region, "overlap_equal");
|
||||
verifyReadNotPlaced(region, "overlap_unequal");
|
||||
getRead(region, "boundary_equal");
|
||||
getRead(region, "boundary_unequal");
|
||||
getRead(region, "extended_and_np");
|
||||
verifyReadNotPlaced(region, "outside_intervals");
|
||||
verifyReadNotPlaced(region, "simple20");
|
||||
|
||||
region = activeRegions.get(genomeLocParser.createGenomeLoc("1", 2000, 2999));
|
||||
|
||||
verifyReadNotPlaced(region, "simple");
|
||||
verifyReadNotPlaced(region, "overlap_equal");
|
||||
verifyReadNotPlaced(region, "overlap_unequal");
|
||||
getRead(region, "boundary_equal");
|
||||
getRead(region, "boundary_unequal");
|
||||
verifyReadNotPlaced(region, "extended_and_np");
|
||||
verifyReadNotPlaced(region, "outside_intervals");
|
||||
verifyReadNotPlaced(region, "simple20");
|
||||
|
||||
region = activeRegions.get(genomeLocParser.createGenomeLoc("20", 10000, 10100));
|
||||
|
||||
verifyReadNotPlaced(region, "simple");
|
||||
verifyReadNotPlaced(region, "overlap_equal");
|
||||
verifyReadNotPlaced(region, "overlap_unequal");
|
||||
verifyReadNotPlaced(region, "boundary_equal");
|
||||
verifyReadNotPlaced(region, "boundary_unequal");
|
||||
verifyReadNotPlaced(region, "extended_and_np");
|
||||
verifyReadNotPlaced(region, "outside_intervals");
|
||||
getRead(region, "simple20");
|
||||
|
||||
// TODO: more tests and edge cases
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtendedReadMapping() {
|
||||
DummyActiveRegionWalker walker = new DummyActiveRegionWalker(
|
||||
EnumSet.of(ActiveRegionReadState.PRIMARY, ActiveRegionReadState.NONPRIMARY, ActiveRegionReadState.EXTENDED));
|
||||
|
||||
// Contract: Each read has the Primary state in a single region (or none)
|
||||
// This is the region of maximum overlap for the read (earlier if tied)
|
||||
|
||||
// Contract: Each read has the Non-Primary state in all other regions it overlaps
|
||||
// Contract: Each read has the Extended state in regions where it only overlaps if the region is extended
|
||||
|
||||
// simple: Primary in 1:1-999
|
||||
// overlap_equal: Primary in 1:1-999
|
||||
// overlap_unequal: Primary in 1:1-999
|
||||
// boundary_equal: Primary in 1:1000-1999, Non-Primary in 1:2000-2999
|
||||
// boundary_unequal: Non-Primary in 1:1000-1999, Primary in 1:2000-2999
|
||||
// extended_only: Extended in 1:2000-2999
|
||||
// boundary_equal: Non-Primary in 1:1000-1999, Primary in 1:2000-2999
|
||||
// boundary_unequal: Primary in 1:1000-1999, Non-Primary in 1:2000-2999
|
||||
// extended_and_np: Non-Primary in 1:1-999, Primary in 1:1000-1999, Extended in 1:2000-2999
|
||||
// outside_intervals: none
|
||||
|
||||
// TODO
|
||||
// simple20: Primary in 20:10000-20000
|
||||
// simple20: Primary in 20:10000-10100
|
||||
|
||||
Map<GenomeLoc, ActiveRegion> activeRegions = getActiveRegions(walker, intervals);
|
||||
ActiveRegion region;
|
||||
|
||||
region = activeRegions.get(genomeLocParser.createGenomeLoc("1", 1, 999));
|
||||
|
||||
verifyReadPrimary(region, "simple");
|
||||
verifyReadPrimary(region, "overlap_equal");
|
||||
verifyReadPrimary(region, "overlap_unequal");
|
||||
getRead(region, "simple");
|
||||
getRead(region, "overlap_equal");
|
||||
getRead(region, "overlap_unequal");
|
||||
verifyReadNotPlaced(region, "boundary_equal");
|
||||
verifyReadNotPlaced(region, "boundary_unequal");
|
||||
verifyReadNotPlaced(region, "extended_only");
|
||||
// TODO: fail verifyReadNonPrimary(region, "extended_and_np");
|
||||
getRead(region, "extended_and_np");
|
||||
verifyReadNotPlaced(region, "outside_intervals");
|
||||
verifyReadNotPlaced(region, "simple20");
|
||||
|
||||
region = activeRegions.get(genomeLocParser.createGenomeLoc("1", 1000, 1999));
|
||||
|
||||
verifyReadNotPlaced(region, "simple");
|
||||
verifyReadNotPlaced(region, "overlap_equal");
|
||||
verifyReadNotPlaced(region, "overlap_unequal");
|
||||
// TODO: fail verifyReadPrimary(region, "boundary_equal");
|
||||
// TODO: fail verifyReadNonPrimary(region, "boundary_unequal");
|
||||
verifyReadNotPlaced(region, "extended_only");
|
||||
// TODO: fail verifyReadPrimary(region, "extended_and_np");
|
||||
getRead(region, "boundary_equal");
|
||||
getRead(region, "boundary_unequal");
|
||||
getRead(region, "extended_and_np");
|
||||
verifyReadNotPlaced(region, "outside_intervals");
|
||||
verifyReadNotPlaced(region, "simple20");
|
||||
|
||||
region = activeRegions.get(genomeLocParser.createGenomeLoc("1", 2000, 2999));
|
||||
|
||||
verifyReadNotPlaced(region, "simple");
|
||||
verifyReadNotPlaced(region, "overlap_equal");
|
||||
verifyReadNotPlaced(region, "overlap_unequal");
|
||||
// TODO: fail verifyReadNonPrimary(region, "boundary_equal");
|
||||
verifyReadPrimary(region, "boundary_unequal");
|
||||
// TODO: fail verifyReadExtended(region, "extended_only");
|
||||
// TODO: fail verifyReadExtended(region, "extended_and_np");
|
||||
getRead(region, "boundary_equal");
|
||||
getRead(region, "boundary_unequal");
|
||||
getRead(region, "extended_and_np");
|
||||
verifyReadNotPlaced(region, "outside_intervals");
|
||||
verifyReadNotPlaced(region, "simple20");
|
||||
|
||||
region = activeRegions.get(genomeLocParser.createGenomeLoc("20", 10000, 10100));
|
||||
|
||||
verifyReadNotPlaced(region, "simple");
|
||||
verifyReadNotPlaced(region, "overlap_equal");
|
||||
verifyReadNotPlaced(region, "overlap_unequal");
|
||||
verifyReadNotPlaced(region, "boundary_equal");
|
||||
verifyReadNotPlaced(region, "boundary_unequal");
|
||||
verifyReadNotPlaced(region, "extended_and_np");
|
||||
verifyReadNotPlaced(region, "outside_intervals");
|
||||
getRead(region, "simple20");
|
||||
|
||||
// TODO: more tests and edge cases
|
||||
}
|
||||
|
||||
private void verifyReadPrimary(ActiveRegion region, String readName) {
|
||||
SAMRecord read = getRead(region, readName);
|
||||
Assert.assertFalse(read.getNotPrimaryAlignmentFlag(), "Read " + read + " not primary in active region " + region);
|
||||
}
|
||||
|
||||
private void verifyReadNonPrimary(ActiveRegion region, String readName) {
|
||||
SAMRecord read = getRead(region, readName);
|
||||
Assert.assertTrue(read.getNotPrimaryAlignmentFlag(), "Read " + read + " primary in active region " + region);
|
||||
}
|
||||
|
||||
private void verifyReadExtended(ActiveRegion region, String readName) {
|
||||
Assert.fail("The Extended read state has not been implemented");
|
||||
}
|
||||
|
||||
private void verifyReadNotPlaced(ActiveRegion region, String readName) {
|
||||
for (SAMRecord read : region.getReads()) {
|
||||
if (read.getReadName().equals(readName))
|
||||
|
|
@ -274,7 +435,7 @@ public class TraverseActiveRegionsTest extends BaseTest {
|
|||
return read;
|
||||
}
|
||||
|
||||
Assert.fail("Read " + readName + " not found in active region " + region);
|
||||
Assert.fail("Read " + readName + " not assigned to active region " + region);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -282,6 +443,8 @@ public class TraverseActiveRegionsTest extends BaseTest {
|
|||
for (LocusShardDataProvider dataProvider : createDataProviders(intervals))
|
||||
t.traverse(walker, dataProvider, 0);
|
||||
|
||||
t.endTraversal(walker, 0);
|
||||
|
||||
return walker.mappedActiveRegions;
|
||||
}
|
||||
|
||||
|
|
@ -345,7 +508,7 @@ public class TraverseActiveRegionsTest extends BaseTest {
|
|||
engine.setGenomeLocParser(genomeLocParser);
|
||||
t.initialize(engine);
|
||||
|
||||
StingSAMIterator iterator = ArtificialSAMUtils.createReadIterator(reads);
|
||||
StingSAMIterator iterator = ArtificialSAMUtils.createReadIterator(new ArrayList<SAMRecord>(reads));
|
||||
Shard shard = new MockLocusShard(genomeLocParser, intervals);
|
||||
|
||||
List<LocusShardDataProvider> providers = new ArrayList<LocusShardDataProvider>();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package org.broadinstitute.sting.gatk.walkers;
|
||||
|
||||
import org.broadinstitute.sting.WalkerTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PrintReadsLargeScaleTest extends WalkerTest {
|
||||
@Test( timeOut = 1000 * 60 * 60 * 20 ) // 60 seconds * 60 seconds / minute * 20 minutes
|
||||
public void testRealignerTargetCreator() {
|
||||
WalkerTestSpec spec = new WalkerTestSpec(
|
||||
"-R " + b37KGReference +
|
||||
" -T PrintReads" +
|
||||
" -I " + evaluationDataLocation + "CEUTrio.HiSeq.WEx.b37.NA12892.clean.dedup.recal.1.bam" +
|
||||
" -o /dev/null",
|
||||
0,
|
||||
new ArrayList<String>(0));
|
||||
executeTest("testPrintReadsWholeExomeChr1", spec);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ package org.broadinstitute.sting.utils;
|
|||
|
||||
|
||||
import net.sf.samtools.SAMFileHeader;
|
||||
import net.sf.samtools.SAMSequenceDictionary;
|
||||
import net.sf.samtools.SAMSequenceRecord;
|
||||
import org.broadinstitute.sting.BaseTest;
|
||||
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||
import org.broadinstitute.sting.utils.exceptions.UserException;
|
||||
|
|
@ -74,6 +76,23 @@ public class GenomeLocParserUnitTest extends BaseTest {
|
|||
genomeLocParser.parseGenomeLoc("Bad:0-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContigHasColon() {
|
||||
SAMFileHeader header = new SAMFileHeader();
|
||||
header.setSortOrder(net.sf.samtools.SAMFileHeader.SortOrder.coordinate);
|
||||
SAMSequenceDictionary dict = new SAMSequenceDictionary();
|
||||
SAMSequenceRecord rec = new SAMSequenceRecord("c:h:r1", 10);
|
||||
rec.setSequenceLength(10);
|
||||
dict.addSequence(rec);
|
||||
header.setSequenceDictionary(dict);
|
||||
|
||||
final GenomeLocParser myGenomeLocParser = new GenomeLocParser(header.getSequenceDictionary());
|
||||
GenomeLoc loc = myGenomeLocParser.parseGenomeLoc("c:h:r1:4-5");
|
||||
assertEquals(0, loc.getContigIndex());
|
||||
assertEquals(loc.getStart(), 4);
|
||||
assertEquals(loc.getStop(), 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseGoodString() {
|
||||
GenomeLoc loc = genomeLocParser.parseGenomeLoc("chr1:1-10");
|
||||
|
|
@ -81,7 +100,7 @@ public class GenomeLocParserUnitTest extends BaseTest {
|
|||
assertEquals(loc.getStop(), 10);
|
||||
assertEquals(loc.getStart(), 1);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateGenomeLoc1() {
|
||||
GenomeLoc loc = genomeLocParser.createGenomeLoc("chr1", 1, 100);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
// our package
|
||||
package org.broadinstitute.sting.utils.baq;
|
||||
|
||||
|
||||
// the imports for unit testing.
|
||||
|
||||
|
||||
import org.broadinstitute.sting.utils.exceptions.UserException;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
|
@ -24,7 +20,7 @@ import net.sf.picard.reference.IndexedFastaSequenceFile;
|
|||
import net.sf.samtools.*;
|
||||
|
||||
/**
|
||||
* Basic unit test for GenomeLoc
|
||||
* Basic unit test for BAQ calculation
|
||||
*/
|
||||
public class BAQUnitTest extends BaseTest {
|
||||
private SAMFileHeader header;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ public class VCFIntegrationTest extends WalkerTest {
|
|||
}
|
||||
|
||||
@Test(enabled = true)
|
||||
// See https://getsatisfaction.com/gsa/topics/support_vcf_4_1_structural_variation_breakend_alleles?utm_content=topic_link&utm_medium=email&utm_source=new_topic
|
||||
public void testReadingAndWritingBreakpointAlleles() {
|
||||
String testVCF = privateTestDir + "breakpoint-example.vcf";
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package org.broadinstitute.sting.utils.nanoScheduler;
|
|||
|
||||
import org.broadinstitute.sting.BaseTest;
|
||||
import org.broadinstitute.sting.utils.MultiThreadedErrorTracker;
|
||||
import org.broadinstitute.sting.utils.SimpleTimer;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
|
@ -46,7 +45,7 @@ public class InputProducerUnitTest extends BaseTest {
|
|||
final LinkedBlockingDeque<InputProducer<Integer>.InputValue> readQueue =
|
||||
new LinkedBlockingDeque<InputProducer<Integer>.InputValue>(queueSize);
|
||||
|
||||
final InputProducer<Integer> ip = new InputProducer<Integer>(elements.iterator(), new MultiThreadedErrorTracker(), new SimpleTimer(), readQueue);
|
||||
final InputProducer<Integer> ip = new InputProducer<Integer>(elements.iterator(), new MultiThreadedErrorTracker(), readQueue);
|
||||
|
||||
final ExecutorService es = Executors.newSingleThreadExecutor();
|
||||
|
||||
|
|
@ -94,7 +93,7 @@ public class InputProducerUnitTest extends BaseTest {
|
|||
final LinkedBlockingDeque<InputProducer<Integer>.InputValue> readQueue =
|
||||
new LinkedBlockingDeque<InputProducer<Integer>.InputValue>();
|
||||
|
||||
final InputProducer<Integer> ip = new InputProducer<Integer>(elements.iterator(), new MultiThreadedErrorTracker(), new SimpleTimer(), readQueue);
|
||||
final InputProducer<Integer> ip = new InputProducer<Integer>(elements.iterator(), new MultiThreadedErrorTracker(), readQueue);
|
||||
|
||||
final ExecutorService es = Executors.newSingleThreadExecutor();
|
||||
es.submit(ip);
|
||||
|
|
|
|||
|
|
@ -188,17 +188,6 @@ public class NanoSchedulerUnitTest extends BaseTest {
|
|||
|
||||
Assert.assertTrue(callback.callBacks >= test.nExpectedCallbacks(), "Not enough callbacks detected. Expected at least " + test.nExpectedCallbacks() + " but saw only " + callback.callBacks);
|
||||
nanoScheduler.shutdown();
|
||||
|
||||
// TODO -- need to enable only in the case where there's serious time spend in
|
||||
// TODO -- read /map / reduce, otherwise the "outside" timer doesn't add up
|
||||
final double myTimeEstimate = timer.getElapsedTime();
|
||||
final double tolerance = 0.1;
|
||||
if ( false && myTimeEstimate > 0.1 ) {
|
||||
Assert.assertTrue(nanoScheduler.getTotalRuntime() > myTimeEstimate * tolerance,
|
||||
"NanoScheduler said that the total runtime was " + nanoScheduler.getTotalRuntime()
|
||||
+ " but the overall test time was " + myTimeEstimate + ", beyond our tolerance factor of "
|
||||
+ tolerance);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(enabled = true && ! DEBUG, dataProvider = "NanoSchedulerBasicTest", dependsOnMethods = "testMultiThreadedNanoScheduler", timeOut = NANO_SCHEDULE_MAX_RUNTIME)
|
||||
|
|
@ -243,7 +232,7 @@ public class NanoSchedulerUnitTest extends BaseTest {
|
|||
for ( final int nThreads : Arrays.asList(8) ) {
|
||||
for ( final boolean addDelays : Arrays.asList(true, false) ) {
|
||||
final NanoSchedulerBasicTest test = new NanoSchedulerBasicTest(bufSize, nThreads, 1, 1000000, false);
|
||||
final int maxN = addDelays ? 10000 : 100000;
|
||||
final int maxN = addDelays ? 1000 : 10000;
|
||||
for ( int nElementsBeforeError = 0; nElementsBeforeError < maxN; nElementsBeforeError += Math.max(nElementsBeforeError / 10, 1) ) {
|
||||
tests.add(new Object[]{nElementsBeforeError, test, addDelays});
|
||||
}
|
||||
|
|
@ -259,17 +248,22 @@ public class NanoSchedulerUnitTest extends BaseTest {
|
|||
executeTestErrorThrowingInput(10, new NullPointerException(), exampleTest, false);
|
||||
}
|
||||
|
||||
@Test(enabled = true, expectedExceptions = ReviewedStingException.class, timeOut = 10000)
|
||||
@Test(enabled = true, expectedExceptions = ReviewedStingException.class, timeOut = 1000)
|
||||
public void testInputErrorIsThrown_RSE() throws InterruptedException {
|
||||
executeTestErrorThrowingInput(10, new ReviewedStingException("test"), exampleTest, false);
|
||||
}
|
||||
|
||||
@Test(enabled = true, expectedExceptions = NullPointerException.class, dataProvider = "NanoSchedulerInputExceptionTest", timeOut = 10000, invocationCount = 1)
|
||||
public void testInputErrorDoesntDeadlock(final int nElementsBeforeError, final NanoSchedulerBasicTest test, final boolean addDelays ) throws InterruptedException {
|
||||
@Test(enabled = true, expectedExceptions = NullPointerException.class, dataProvider = "NanoSchedulerInputExceptionTest", timeOut = 1000, invocationCount = 1)
|
||||
public void testInputRuntimeExceptionDoesntDeadlock(final int nElementsBeforeError, final NanoSchedulerBasicTest test, final boolean addDelays ) throws InterruptedException {
|
||||
executeTestErrorThrowingInput(nElementsBeforeError, new NullPointerException(), test, addDelays);
|
||||
}
|
||||
|
||||
private void executeTestErrorThrowingInput(final int nElementsBeforeError, final RuntimeException ex, final NanoSchedulerBasicTest test, final boolean addDelays) {
|
||||
@Test(enabled = true, expectedExceptions = ReviewedStingException.class, dataProvider = "NanoSchedulerInputExceptionTest", timeOut = 1000, invocationCount = 1)
|
||||
public void testInputErrorDoesntDeadlock(final int nElementsBeforeError, final NanoSchedulerBasicTest test, final boolean addDelays ) throws InterruptedException {
|
||||
executeTestErrorThrowingInput(nElementsBeforeError, new Error(), test, addDelays);
|
||||
}
|
||||
|
||||
private void executeTestErrorThrowingInput(final int nElementsBeforeError, final Throwable ex, final NanoSchedulerBasicTest test, final boolean addDelays) {
|
||||
logger.warn("executeTestErrorThrowingInput " + nElementsBeforeError + " ex=" + ex + " test=" + test + " addInputDelays=" + addDelays);
|
||||
final NanoScheduler<Integer, Integer, Integer> nanoScheduler = test.makeScheduler();
|
||||
nanoScheduler.execute(new ErrorThrowingIterator(nElementsBeforeError, ex, addDelays), test.makeMap(), test.initReduce(), test.makeReduce());
|
||||
|
|
@ -279,9 +273,9 @@ public class NanoSchedulerUnitTest extends BaseTest {
|
|||
final int nElementsBeforeError;
|
||||
final boolean addDelays;
|
||||
int i = 0;
|
||||
final RuntimeException ex;
|
||||
final Throwable ex;
|
||||
|
||||
private ErrorThrowingIterator(final int nElementsBeforeError, RuntimeException ex, boolean addDelays) {
|
||||
private ErrorThrowingIterator(final int nElementsBeforeError, Throwable ex, boolean addDelays) {
|
||||
this.nElementsBeforeError = nElementsBeforeError;
|
||||
this.ex = ex;
|
||||
this.addDelays = addDelays;
|
||||
|
|
@ -290,7 +284,12 @@ public class NanoSchedulerUnitTest extends BaseTest {
|
|||
@Override public boolean hasNext() { return true; }
|
||||
@Override public Integer next() {
|
||||
if ( i++ > nElementsBeforeError ) {
|
||||
throw ex;
|
||||
if ( ex instanceof Error )
|
||||
throw (Error)ex;
|
||||
else if ( ex instanceof RuntimeException )
|
||||
throw (RuntimeException)ex;
|
||||
else
|
||||
throw new RuntimeException("Bad exception " + ex);
|
||||
} else if ( addDelays ) {
|
||||
maybeDelayMe(i);
|
||||
return i;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package org.broadinstitute.sting.utils.nanoScheduler;
|
|||
|
||||
import org.broadinstitute.sting.BaseTest;
|
||||
import org.broadinstitute.sting.utils.MultiThreadedErrorTracker;
|
||||
import org.broadinstitute.sting.utils.SimpleTimer;
|
||||
import org.broadinstitute.sting.utils.Utils;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.DataProvider;
|
||||
|
|
@ -93,7 +92,7 @@ public class ReducerUnitTest extends BaseTest {
|
|||
|
||||
final List<List<MapResult<Integer>>> jobGroups = Utils.groupList(allJobs, groupSize);
|
||||
final ReduceSumTest reduce = new ReduceSumTest();
|
||||
final Reducer<Integer, Integer> reducer = new Reducer<Integer, Integer>(reduce, new MultiThreadedErrorTracker(), new SimpleTimer(), 0);
|
||||
final Reducer<Integer, Integer> reducer = new Reducer<Integer, Integer>(reduce, new MultiThreadedErrorTracker(), 0);
|
||||
|
||||
final TestWaitingForFinalReduce waitingThread = new TestWaitingForFinalReduce(reducer, expectedSum(allJobs));
|
||||
final ExecutorService es = Executors.newSingleThreadExecutor();
|
||||
|
|
@ -155,7 +154,7 @@ public class ReducerUnitTest extends BaseTest {
|
|||
private void runSettingJobIDTwice() throws Exception {
|
||||
final PriorityBlockingQueue<MapResult<Integer>> mapResultsQueue = new PriorityBlockingQueue<MapResult<Integer>>();
|
||||
|
||||
final Reducer<Integer, Integer> reducer = new Reducer<Integer, Integer>(new ReduceSumTest(), new MultiThreadedErrorTracker(), new SimpleTimer(), 0);
|
||||
final Reducer<Integer, Integer> reducer = new Reducer<Integer, Integer>(new ReduceSumTest(), new MultiThreadedErrorTracker(), 0);
|
||||
|
||||
reducer.setTotalJobCount(10);
|
||||
reducer.setTotalJobCount(15);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
package org.broadinstitute.sting.utils.sam;
|
||||
|
||||
|
||||
import net.sf.samtools.SAMFileHeader;
|
||||
import org.broadinstitute.sting.BaseTest;
|
||||
import org.broadinstitute.sting.utils.exceptions.UserException;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Basic unit test for misencoded quals
|
||||
*/
|
||||
public class MisencodedBaseQualityUnitTest extends BaseTest {
|
||||
|
||||
private static final String readBases = "AAAAAAAAAA";
|
||||
private static final byte[] badQuals = { 59, 60, 62, 63, 64, 61, 62, 58, 57, 56 };
|
||||
private static final byte[] goodQuals = { 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 };
|
||||
private static final byte[] fixedQuals = { 28, 29, 31, 32, 33, 30, 31, 27, 26, 25 };
|
||||
private SAMFileHeader header;
|
||||
|
||||
@BeforeMethod
|
||||
public void before() {
|
||||
header = ArtificialSAMUtils.createArtificialSamHeader(1, 1, 1000);
|
||||
}
|
||||
|
||||
private GATKSAMRecord createRead(final boolean useGoodBases) {
|
||||
GATKSAMRecord read = ArtificialSAMUtils.createArtificialRead(header, "foo", 0, 10, readBases.getBytes(), useGoodBases ? goodQuals : badQuals);
|
||||
read.setCigarString("10M");
|
||||
return read;
|
||||
}
|
||||
|
||||
@Test(enabled = true)
|
||||
public void testGoodQuals() {
|
||||
final List<GATKSAMRecord> reads = new ArrayList<GATKSAMRecord>(10000);
|
||||
for ( int i = 0; i < 10000; i++ )
|
||||
reads.add(createRead(true));
|
||||
|
||||
testEncoding(reads);
|
||||
}
|
||||
|
||||
@Test(enabled = true, expectedExceptions = {UserException.class})
|
||||
public void testBadQualsThrowsError() {
|
||||
final List<GATKSAMRecord> reads = new ArrayList<GATKSAMRecord>(10000);
|
||||
for ( int i = 0; i < 10000; i++ )
|
||||
reads.add(createRead(false));
|
||||
|
||||
testEncoding(reads);
|
||||
}
|
||||
|
||||
@Test(enabled = true)
|
||||
public void testFixBadQuals() {
|
||||
final GATKSAMRecord read = createRead(false);
|
||||
final GATKSAMRecord fixedRead = MisencodedBaseQualityReadTransformer.fixMisencodedQuals(read);
|
||||
for ( int i = 0; i < fixedQuals.length; i++ )
|
||||
Assert.assertEquals(fixedQuals[i], fixedRead.getBaseQualities()[i]);
|
||||
}
|
||||
|
||||
private void testEncoding(final List<GATKSAMRecord> reads) {
|
||||
for ( final GATKSAMRecord read : reads )
|
||||
MisencodedBaseQualityReadTransformer.checkForMisencodedQuals(read);
|
||||
}
|
||||
}
|
||||
|
|
@ -793,7 +793,7 @@ public class VariantContextUtilsUnitTest extends BaseTest {
|
|||
|
||||
int sampleI = 0;
|
||||
for ( final List<Allele> alleles : Utils.makePermutations(vc.getAlleles(), 2, true) ) {
|
||||
genotypes.add(GenotypeBuilder.create("sample" + sampleI, alleles));
|
||||
genotypes.add(GenotypeBuilder.create("sample" + sampleI++, alleles));
|
||||
}
|
||||
genotypes.add(GenotypeBuilder.createMissing("missing", 2));
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@
|
|||
<dir name="org/broadinstitute/sting/utils/R" includes="**/*.tar.gz" />
|
||||
<!-- All R scripts in org.broadinstitute.sting -->
|
||||
<dir name="org/broadinstitute/sting" includes="**/*.R" />
|
||||
<!-- Resources in org.broadinstitute.sting -->
|
||||
<dir name="org/broadinstitute/sting" includes="**/resources/*" />
|
||||
<dir name="org/broadinstitute/sting" includes="**/templates/*" />
|
||||
<!-- The GATK public key -->
|
||||
<file path="GATK_public.key" />
|
||||
</dependencies>
|
||||
|
|
|
|||
|
|
@ -72,6 +72,10 @@ class QSettings {
|
|||
@Argument(fullName="resident_memory_request_parameter", shortName="resMemReqParam", doc="Parameter for resident memory requests. By default not requested.", required=false)
|
||||
var residentRequestParameter: String = _
|
||||
|
||||
@Argument(fullName="job_walltime", shortName="wallTime", doc="Setting the required DRMAA walltime or LSF run limit.", required=false)
|
||||
@ClassType(classOf[Long])
|
||||
var jobWalltime: Option[Long] = None
|
||||
|
||||
/** The name of the parallel environment (required for SGE, for example) */
|
||||
@Argument(fullName="job_parallel_env", shortName="jobParaEnv", doc="An SGE style parallel environment to use for jobs requesting more than 1 core. Equivalent to submitting jobs with -pe ARG nt for jobs with nt > 1", required=false)
|
||||
var parallelEnvironmentName: String = "smp_pe" // Broad default
|
||||
|
|
|
|||
|
|
@ -65,6 +65,9 @@ class DrmaaJobRunner(val session: Session, val function: CommandLineFunction) ex
|
|||
drmaaJob.setJoinFiles(true)
|
||||
}
|
||||
|
||||
if(!function.wallTime.isEmpty)
|
||||
drmaaJob.setHardWallclockTimeLimit(function.wallTime.get)
|
||||
|
||||
drmaaJob.setNativeSpecification(functionNativeSpec)
|
||||
|
||||
// Instead of running the function.commandLine, run "sh <jobScript>"
|
||||
|
|
|
|||
|
|
@ -151,8 +151,11 @@ class Lsf706JobRunner(val function: CommandLineFunction) extends CommandLineJobR
|
|||
throw new QException("setOption_() returned -1 while setting esub");
|
||||
}
|
||||
|
||||
// LSF specific: get the max runtime for the jobQueue and pass it for this job
|
||||
request.rLimits(LibLsf.LSF_RLIMIT_RUN) = Lsf706JobRunner.getRlimitRun(function.jobQueue)
|
||||
if(!function.wallTime.isEmpty)
|
||||
request.rLimits(LibLsf.LSF_RLIMIT_RUN) = function.wallTime.get.toInt
|
||||
else
|
||||
// LSF specific: get the max runtime for the jobQueue and pass it for this job
|
||||
request.rLimits(LibLsf.LSF_RLIMIT_RUN) = Lsf706JobRunner.getRlimitRun(function.jobQueue)
|
||||
|
||||
// Run the command as sh <jobScript>
|
||||
request.command = "sh " + jobScript
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ import org.broadinstitute.sting.commandline.Argument
|
|||
trait CommandLineFunction extends QFunction with Logging {
|
||||
def commandLine: String
|
||||
|
||||
/** Setting the wall time request for DRMAA / run limit for LSF */
|
||||
var wallTime: Option[Long] = None
|
||||
|
||||
/** Upper memory limit */
|
||||
@Argument(doc="Memory limit", required=false)
|
||||
var memoryLimit: Option[Double] = None
|
||||
|
|
@ -67,6 +70,9 @@ trait CommandLineFunction extends QFunction with Logging {
|
|||
super.copySettingsTo(function)
|
||||
function match {
|
||||
case commandLineFunction: CommandLineFunction =>
|
||||
if(commandLineFunction.wallTime.isEmpty)
|
||||
commandLineFunction.wallTime = this.wallTime
|
||||
|
||||
if (commandLineFunction.memoryLimit.isEmpty)
|
||||
commandLineFunction.memoryLimit = this.memoryLimit
|
||||
|
||||
|
|
@ -110,6 +116,10 @@ trait CommandLineFunction extends QFunction with Logging {
|
|||
* Sets all field values.
|
||||
*/
|
||||
override def freezeFieldValues() {
|
||||
|
||||
if(wallTime.isEmpty)
|
||||
wallTime = qSettings.jobWalltime
|
||||
|
||||
if (jobQueue == null)
|
||||
jobQueue = qSettings.jobQueue
|
||||
|
||||
|
|
|
|||
|
|
@ -126,4 +126,15 @@ class HelloWorldPipelineTest {
|
|||
spec.jobRunners = Seq("GridEngine")
|
||||
PipelineTest.executeTest(spec)
|
||||
}
|
||||
|
||||
// disabled because our DRMAA implementation doesn't support wallTime
|
||||
@Test(enabled=false, timeOut=36000000)
|
||||
def testHelloWorldWithWalltime() {
|
||||
val spec = new PipelineTestSpec
|
||||
spec.name = "HelloWorldWithWalltime"
|
||||
spec.args = "-S public/scala/qscript/org/broadinstitute/sting/queue/qscripts/examples/HelloWorld.scala" +
|
||||
" -wallTime 100"
|
||||
spec.jobRunners = PipelineTest.allJobRunners
|
||||
PipelineTest.executeTest(spec)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue