From 0b43ee117cd06a138309a3d18be3b3809be87c9f Mon Sep 17 00:00:00 2001
From: Kiran V Garimella
Date: Mon, 25 Jul 2011 11:35:34 -0400
Subject: [PATCH 01/25] Added the required=false tag to the -noST and -noEV
arguments so the auto-help output doesn't look weird (i.e. listing arguments
as required when their value has already been specified by default).
---
.../sting/gatk/walkers/varianteval/VariantEvalWalker.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/VariantEvalWalker.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/VariantEvalWalker.java
index fe3173506..3867aa958 100755
--- a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/VariantEvalWalker.java
+++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/VariantEvalWalker.java
@@ -67,7 +67,7 @@ public class VariantEvalWalker extends RodWalker implements Tr
@Argument(fullName="stratificationModule", shortName="ST", doc="One or more specific stratification modules to apply to the eval track(s) (in addition to the standard stratifications, unless -noS is specified)", required=false)
protected String[] STRATIFICATIONS_TO_USE = {};
- @Argument(fullName="doNotUseAllStandardStratifications", shortName="noST", doc="Do not use the standard stratification modules by default (instead, only those that are specified with the -S option)")
+ @Argument(fullName="doNotUseAllStandardStratifications", shortName="noST", doc="Do not use the standard stratification modules by default (instead, only those that are specified with the -S option)", required=false)
protected Boolean NO_STANDARD_STRATIFICATIONS = false;
@Argument(fullName="onlyVariantsOfType", shortName="VT", doc="If provided, only variants of these types will be considered during the evaluation, in ", required=false)
@@ -77,7 +77,7 @@ public class VariantEvalWalker extends RodWalker implements Tr
@Argument(fullName="evalModule", shortName="EV", doc="One or more specific eval modules to apply to the eval track(s) (in addition to the standard modules, unless -noE is specified)", required=false)
protected String[] MODULES_TO_USE = {};
- @Argument(fullName="doNotUseAllStandardModules", shortName="noEV", doc="Do not use the standard modules by default (instead, only those that are specified with the -E option)")
+ @Argument(fullName="doNotUseAllStandardModules", shortName="noEV", doc="Do not use the standard modules by default (instead, only those that are specified with the -E option)", required=false)
protected Boolean NO_STANDARD_MODULES = false;
// Other arguments
From 412c466de6cee301082086cb0e99dc193029faff Mon Sep 17 00:00:00 2001
From: Kiran V Garimella
Date: Tue, 26 Jul 2011 17:43:43 -0400
Subject: [PATCH 18/25] Bug fix, wherein triple-hets after genotype refinement
need to be left unphased, not just prior to refinement
---
.../gatk/walkers/phasing/PhaseByTransmission.java | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/phasing/PhaseByTransmission.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/phasing/PhaseByTransmission.java
index d3ed46ce8..cf4afbb6d 100755
--- a/public/java/src/org/broadinstitute/sting/gatk/walkers/phasing/PhaseByTransmission.java
+++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/phasing/PhaseByTransmission.java
@@ -234,7 +234,7 @@ public class PhaseByTransmission extends RodWalker {
finalGenotypes.add(father);
finalGenotypes.add(child);
- if (mother.isCalled() && father.isCalled() && child.isCalled() && !(mother.isHet() && father.isHet() && child.isHet())) {
+ if (mother.isCalled() && father.isCalled() && child.isCalled()) {
ArrayList possibleMotherGenotypes = createAllThreeGenotypes(ref, alt, mother);
ArrayList possibleFatherGenotypes = createAllThreeGenotypes(ref, alt, father);
ArrayList possibleChildGenotypes = createAllThreeGenotypes(ref, alt, child);
@@ -265,12 +265,14 @@ public class PhaseByTransmission extends RodWalker {
}
}
- Map attributes = new HashMap();
- attributes.putAll(bestChildGenotype.getAttributes());
- attributes.put(TRANSMISSION_PROBABILITY_TAG_NAME, bestPrior*bestConfigurationLikelihood / norm);
- bestChildGenotype = Genotype.modifyAttributes(bestChildGenotype, attributes);
+ if (!(bestMotherGenotype.isHet() && bestFatherGenotype.isHet() && bestChildGenotype.isHet())) {
+ Map attributes = new HashMap();
+ attributes.putAll(bestChildGenotype.getAttributes());
+ attributes.put(TRANSMISSION_PROBABILITY_TAG_NAME, bestPrior*bestConfigurationLikelihood / norm);
+ bestChildGenotype = Genotype.modifyAttributes(bestChildGenotype, attributes);
- finalGenotypes = getPhasedGenotypes(bestMotherGenotype, bestFatherGenotype, bestChildGenotype);
+ finalGenotypes = getPhasedGenotypes(bestMotherGenotype, bestFatherGenotype, bestChildGenotype);
+ }
}
return finalGenotypes;
From 92a11ed8dcc6899697196e329ea2b3d944fb3bf2 Mon Sep 17 00:00:00 2001
From: Kiran V Garimella
Date: Tue, 26 Jul 2011 17:52:25 -0400
Subject: [PATCH 19/25] Updated MD5 for PhaseByTransmissionIntegrationTest
---
.../walkers/phasing/PhaseByTransmissionIntegrationTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/java/test/org/broadinstitute/sting/gatk/walkers/phasing/PhaseByTransmissionIntegrationTest.java b/public/java/test/org/broadinstitute/sting/gatk/walkers/phasing/PhaseByTransmissionIntegrationTest.java
index 69f98b700..f62f12082 100644
--- a/public/java/test/org/broadinstitute/sting/gatk/walkers/phasing/PhaseByTransmissionIntegrationTest.java
+++ b/public/java/test/org/broadinstitute/sting/gatk/walkers/phasing/PhaseByTransmissionIntegrationTest.java
@@ -20,7 +20,7 @@ public class PhaseByTransmissionIntegrationTest extends WalkerTest {
"-o %s"
),
1,
- Arrays.asList("ff02b1583ee3a12ed66a9c0e08e346b2")
+ Arrays.asList("45fef0e23113e2fcd9570379e2fc1b75")
);
executeTest("testBasicFunctionality", spec);
}
From 321afac4e8ebc3a6db2c0e9b00094f0dfe12f0e6 Mon Sep 17 00:00:00 2001
From: Mauricio Carneiro
Date: Tue, 26 Jul 2011 19:29:25 -0400
Subject: [PATCH 20/25] Updates to the help layout.
*New style.css, new template for the walker auto-generated html. Short description is no longer repeated in the long description of the walker.
*Updated DiffObjectsWalker and ContigStatsWalker as "reference" documented walkers.
---
.../walkers/diffengine/DiffObjectsWalker.java | 74 +++++++++++--------
.../help/GenericDocumentationHandler.java | 2 +-
settings/helpTemplates/common.html | 6 +-
settings/helpTemplates/generic.template.html | 7 +-
settings/helpTemplates/style.css | 52 +++++++++++--
5 files changed, 96 insertions(+), 45 deletions(-)
diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/DiffObjectsWalker.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/DiffObjectsWalker.java
index b679f967a..f43d1342d 100644
--- a/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/DiffObjectsWalker.java
+++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/DiffObjectsWalker.java
@@ -25,7 +25,6 @@
package org.broadinstitute.sting.gatk.walkers.diffengine;
import org.broadinstitute.sting.commandline.Argument;
-import org.broadinstitute.sting.commandline.Hidden;
import org.broadinstitute.sting.commandline.Output;
import org.broadinstitute.sting.gatk.contexts.AlignmentContext;
import org.broadinstitute.sting.gatk.contexts.ReferenceContext;
@@ -35,34 +34,45 @@ import org.broadinstitute.sting.gatk.walkers.RodWalker;
import java.io.File;
import java.io.PrintStream;
-import java.util.Arrays;
import java.util.List;
/**
* A generic engine for comparing tree-structured objects
+ *
*
- * Compares two record-oriented files, itemizing specific difference between equivalent
- * records in the two files. Reports both itemized and summarized differences.
- *
- * What are the summarized differences and the DiffObjectsWalker
+ * Compares two record-oriented files, itemizing specific difference between equivalent
+ * records in the two files. Reports both itemized and summarized differences.
+ *
+ *
+ * What are the summarized differences and the DiffObjectsWalker?
+ *
*
* The GATK contains a summarizing difference engine that compares hierarchical data structures to emit:
- *
- * - A list of specific differences between the two data structures. This is similar to saying the value in field A in record 1 in file F differences from the value in field A in record 1 in file G.
- *
- A summarized list of differences ordered by frequency of the difference. This output is similar to saying field A in 50 records in files F and G differed.
- *
+ *
+ * - A list of specific differences between the two data structures. This is similar to saying the value in field A in record 1 in file F differences from the value in field A in record 1 in file G.
+ *
- A summarized list of differences ordered by frequency of the difference. This output is similar to saying field A in 50 records in files F and G differed.
+ *
+ *
*
*
- * The GATK contains a private walker DiffObjects that allows you access to the DiffEngine capabilities on the command line. Simply provide the walker with the master and test files and it will emit summarized differences for you.
+ * The GATK contains a private walker DiffObjects that allows you access to the DiffEngine capabilities on the command line. Simply provide the walker with the master and test files and it will emit summarized differences for you.
+ *
+ *
+ * Why?
*
*
- * Why?
- *
- * The reason for this system is that it allows you to compare two structured files -- such as BAMs and VCFs -- for common differences among them. This is primarily useful in regression testing or optimization, where you want to ensure that the differences are those that you expect and not any others.
+ * The reason for this system is that it allows you to compare two structured files -- such as BAMs and VCFs -- for common differences among them. This is primarily useful in regression testing or optimization, where you want to ensure that the differences are those that you expect and not any others.
+ *
*
- * Understanding the output
- *
The DiffEngine system compares to two hierarchical data structures for specific differences in the values of named
- * nodes. Suppose I have two trees:
+ *
Input
+ *
+ * The DiffObjectsWalker works with BAM or VCF files.
+ *
+ *
+ * Output
+ *
+ * The DiffEngine system compares to two hierarchical data structures for specific differences in the values of named
+ * nodes. Suppose I have two trees:
*
* Tree1=(A=1 B=(C=2 D=3))
* Tree2=(A=1 B=(C=3 D=3 E=4))
@@ -70,33 +80,37 @@ import java.util.List;
*
*
* where every node in the tree is named, or is a raw value (here all leaf values are integers). The DiffEngine
- * traverses these data structures by name, identifies equivalent nodes by fully qualified names
- * (Tree1.A is distinct from Tree2.A, and determines where their values are equal (Tree1.A=1, Tree2.A=1, so they are).
- * These itemized differences are listed as:
+ * traverses these data structures by name, identifies equivalent nodes by fully qualified names
+ * (Tree1.A is distinct from Tree2.A, and determines where their values are equal (Tree1.A=1, Tree2.A=1, so they are).
+ * These itemized differences are listed as:
*
* Tree1.B.C=2 != Tree2.B.C=3
* Tree1.B.C=2 != Tree3.B.C=4
* Tree2.B.C=3 != Tree3.B.C=4
* Tree1.B.E=MISSING != Tree2.B.E=4
*
+ *
*
- * This conceptually very similar to the output of the unix command line tool diff. What's nice about DiffEngine though
- * is that it computes similarity among the itemized differences and displays the count of differences names
- * in the system. In the above example, the field C is not equal three times, while the missing E in Tree1 occurs
- * only once. So the summary is:
+ * This conceptually very similar to the output of the unix command line tool diff. What's nice about DiffEngine though
+ * is that it computes similarity among the itemized differences and displays the count of differences names
+ * in the system. In the above example, the field C is not equal three times, while the missing E in Tree1 occurs
+ * only once. So the summary is:
*
*
* *.B.C : 3
* *.B.E : 1
*
- * where the * operator indicates that any named field matches. This output is sorted by counts, and provides an
- * immediate picture of the commonly occurring differences among the files.
+ *
*
- * Below is a detailed example of two VCF fields that differ because of a bug in the AC, AF, and AN counting routines,
- * detected by the integrationtest integration (more below). You can see that in the although there are many specific
- * instances of these differences between the two files, the summarized differences provide an immediate picture that
- * the AC, AF, and AN fields are the major causes of the differences.
+ * where the * operator indicates that any named field matches. This output is sorted by counts, and provides an
+ * immediate picture of the commonly occurring differences among the files.
*
+ * Below is a detailed example of two VCF fields that differ because of a bug in the AC, AF, and AN counting routines,
+ * detected by the integrationtest integration (more below). You can see that in the although there are many specific
+ * instances of these differences between the two files, the summarized differences provide an immediate picture that
+ * the AC, AF, and AN fields are the major causes of the differences.
+ *
+ *
*
[testng] path count
[testng] *.*.*.AC 6
diff --git a/public/java/src/org/broadinstitute/sting/utils/help/GenericDocumentationHandler.java b/public/java/src/org/broadinstitute/sting/utils/help/GenericDocumentationHandler.java
index fd1048844..c69345816 100644
--- a/public/java/src/org/broadinstitute/sting/utils/help/GenericDocumentationHandler.java
+++ b/public/java/src/org/broadinstitute/sting/utils/help/GenericDocumentationHandler.java
@@ -92,7 +92,7 @@ public class GenericDocumentationHandler extends DocumentedGATKFeatureHandler {
for(Tag tag: classdoc.firstSentenceTags())
summaryBuilder.append(tag.text());
root.put("summary", summaryBuilder.toString());
- root.put("description", classdoc.commentText());
+ root.put("description", classdoc.commentText().substring(summaryBuilder.toString().length()));
root.put("timestamp", toProcess.buildTimestamp);
root.put("version", toProcess.absoluteVersion);
diff --git a/settings/helpTemplates/common.html b/settings/helpTemplates/common.html
index ebc060d0a..1554a1d40 100644
--- a/settings/helpTemplates/common.html
+++ b/settings/helpTemplates/common.html
@@ -6,10 +6,10 @@
#macro>
<#macro headerInfo>
+#macro>
+
+<#macro footerInfo>
See also Main index | GATK wiki | GATK support forum
GATK version ${version} built at ${timestamp}.
#macro>
-<#macro footerInfo>
-#macro>
-
diff --git a/settings/helpTemplates/generic.template.html b/settings/helpTemplates/generic.template.html
index ca0d1e76f..032407164 100644
--- a/settings/helpTemplates/generic.template.html
+++ b/settings/helpTemplates/generic.template.html
@@ -53,19 +53,18 @@
${name}
<@headerInfo />
- Brief summary
- ${summary}
+ ${summary}
<#if author??>
Author
${author}
#if>
- Detailed description
+ Introduction
${description}
<#-- Create the argument summary -->
<#if arguments.all?size != 0>
- Feature specific arguments
+ ${name} specific arguments
diff --git a/settings/helpTemplates/style.css b/settings/helpTemplates/style.css
index 79f409f55..1d7bcc576 100644
--- a/settings/helpTemplates/style.css
+++ b/settings/helpTemplates/style.css
@@ -14,29 +14,67 @@ p, ul, ol, dl, dt, dd, td
font-size: 12pt;
}
-p.version, p.see-also
+p
{
- font-size: 8pt;
+ margin-left: 1em;
}
-h1, h2, h3
+p.summary
+{
+ margin-left: 2em;
+ margin-top: -20pt;
+ font-style: italic;
+}
+
+p.see-also
+{
+ font-size: 10pt;
+ margin-left: 0em;
+ margin-top: 3em;
+ text-align: center;
+}
+
+p.version
+{
+ font-size: 8pt;
+ margin-left: 0em;
+ margin-top: -8pt;
+ text-align: center;
+}
+
+
+h1, h2, h3, h4
{
font-family: Corbel, Arial, Helvetica, Sans-Serif;
font-weight: bold;
text-align: left;
- color: #669;
}
h1
{
font-size: 32pt;
letter-spacing: -2px;
+ color: #669;
}
-h3
+h2
{
- font-size: 16pt;
- font-weight: normal;
+ font-size: 16pt;
+ font-weight: bold;
+ margin-top: 2em;
+ color: #669;
+}
+
+h3
+{
+ font-size: 12pt;
+ margin-left: 1em;
+ color: #000;
+}
+
+hr
+{
+ margin-top: 4em;
}
/*
From dc8061e7a69b81715ac3ba967e34dd23026a8e6d Mon Sep 17 00:00:00 2001
From: Kiran V Garimella
Date: Wed, 27 Jul 2011 10:34:56 -0400
Subject: [PATCH 22/25] Moved gsalib from private/ to public/
---
build.xml | 2 +-
public/R/src/gsalib/DESCRIPTION | 10 ++
public/R/src/gsalib/R/gsa.error.R | 12 ++
public/R/src/gsalib/R/gsa.getargs.R | 116 ++++++++++++++++++
public/R/src/gsalib/R/gsa.message.R | 3 +
public/R/src/gsalib/R/gsa.plot.venn.R | 50 ++++++++
public/R/src/gsalib/R/gsa.read.eval.R | 83 +++++++++++++
public/R/src/gsalib/R/gsa.read.gatkreport.R | 64 ++++++++++
public/R/src/gsalib/R/gsa.read.squidmetrics.R | 28 +++++
public/R/src/gsalib/R/gsa.read.vcf.R | 23 ++++
public/R/src/gsalib/R/gsa.warn.R | 3 +
public/R/src/gsalib/Read-and-delete-me | 9 ++
public/R/src/gsalib/data/tearsheetdrop.jpg | Bin 0 -> 50343 bytes
public/R/src/gsalib/man/gsa.error.Rd | 49 ++++++++
public/R/src/gsalib/man/gsa.getargs.Rd | 57 +++++++++
public/R/src/gsalib/man/gsa.message.Rd | 44 +++++++
public/R/src/gsalib/man/gsa.plot.venn.Rd | 75 +++++++++++
public/R/src/gsalib/man/gsa.read.eval.Rd | 111 +++++++++++++++++
.../R/src/gsalib/man/gsa.read.gatkreport.Rd | 55 +++++++++
.../R/src/gsalib/man/gsa.read.squidmetrics.Rd | 48 ++++++++
public/R/src/gsalib/man/gsa.read.vcf.Rd | 53 ++++++++
public/R/src/gsalib/man/gsa.warn.Rd | 46 +++++++
public/R/src/gsalib/man/gsalib-package.Rd | 68 ++++++++++
23 files changed, 1008 insertions(+), 1 deletion(-)
create mode 100644 public/R/src/gsalib/DESCRIPTION
create mode 100644 public/R/src/gsalib/R/gsa.error.R
create mode 100644 public/R/src/gsalib/R/gsa.getargs.R
create mode 100644 public/R/src/gsalib/R/gsa.message.R
create mode 100644 public/R/src/gsalib/R/gsa.plot.venn.R
create mode 100644 public/R/src/gsalib/R/gsa.read.eval.R
create mode 100644 public/R/src/gsalib/R/gsa.read.gatkreport.R
create mode 100644 public/R/src/gsalib/R/gsa.read.squidmetrics.R
create mode 100644 public/R/src/gsalib/R/gsa.read.vcf.R
create mode 100644 public/R/src/gsalib/R/gsa.warn.R
create mode 100644 public/R/src/gsalib/Read-and-delete-me
create mode 100755 public/R/src/gsalib/data/tearsheetdrop.jpg
create mode 100644 public/R/src/gsalib/man/gsa.error.Rd
create mode 100644 public/R/src/gsalib/man/gsa.getargs.Rd
create mode 100644 public/R/src/gsalib/man/gsa.message.Rd
create mode 100644 public/R/src/gsalib/man/gsa.plot.venn.Rd
create mode 100644 public/R/src/gsalib/man/gsa.read.eval.Rd
create mode 100644 public/R/src/gsalib/man/gsa.read.gatkreport.Rd
create mode 100644 public/R/src/gsalib/man/gsa.read.squidmetrics.Rd
create mode 100644 public/R/src/gsalib/man/gsa.read.vcf.Rd
create mode 100644 public/R/src/gsalib/man/gsa.warn.Rd
create mode 100644 public/R/src/gsalib/man/gsalib-package.Rd
diff --git a/build.xml b/build.xml
index 60c678591..438e9c90c 100644
--- a/build.xml
+++ b/build.xml
@@ -1089,7 +1089,7 @@
-
+
diff --git a/public/R/src/gsalib/DESCRIPTION b/public/R/src/gsalib/DESCRIPTION
new file mode 100644
index 000000000..6116e8c66
--- /dev/null
+++ b/public/R/src/gsalib/DESCRIPTION
@@ -0,0 +1,10 @@
+Package: gsalib
+Type: Package
+Title: Utility functions
+Version: 1.0
+Date: 2010-10-02
+Author: Kiran Garimella
+Maintainer: Kiran Garimella
+Description: Utility functions for GATK NGS analyses
+License: BSD
+LazyLoad: yes
diff --git a/public/R/src/gsalib/R/gsa.error.R b/public/R/src/gsalib/R/gsa.error.R
new file mode 100644
index 000000000..1c6a56046
--- /dev/null
+++ b/public/R/src/gsalib/R/gsa.error.R
@@ -0,0 +1,12 @@
+gsa.error <- function(message) {
+ message("");
+ gsa.message("Error: **********");
+ gsa.message(sprintf("Error: %s", message));
+ gsa.message("Error: **********");
+ message("");
+
+ traceback();
+
+ message("");
+ stop(message, call. = FALSE);
+}
diff --git a/public/R/src/gsalib/R/gsa.getargs.R b/public/R/src/gsalib/R/gsa.getargs.R
new file mode 100644
index 000000000..94613bf93
--- /dev/null
+++ b/public/R/src/gsalib/R/gsa.getargs.R
@@ -0,0 +1,116 @@
+.gsa.getargs.usage <- function(argspec, doc) {
+ cargs = commandArgs();
+
+ usage = "Usage:";
+
+ fileIndex = grep("--file=", cargs);
+ if (length(fileIndex) > 0) {
+ progname = gsub("--file=", "", cargs[fileIndex[1]]);
+
+ usage = sprintf("Usage: Rscript %s [arguments]", progname);
+
+ if (!is.na(doc)) {
+ message(sprintf("%s: %s\n", progname, doc));
+ }
+ }
+
+ message(usage);
+
+ for (argname in names(argspec)) {
+ key = argname;
+ defaultValue = 0;
+ doc = "";
+
+ if (is.list(argspec[[argname]])) {
+ defaultValue = argspec[[argname]]$value;
+ doc = argspec[[argname]]$doc;
+ }
+
+ message(sprintf(" -%-10s\t[default: %s]\t%s", key, defaultValue, doc));
+ }
+
+ message("");
+
+ stop(call. = FALSE);
+}
+
+gsa.getargs <- function(argspec, doc = NA) {
+ argsenv = new.env();
+
+ for (argname in names(argspec)) {
+ value = 0;
+ if (is.list(argspec[[argname]])) {
+ value = argspec[[argname]]$value;
+ } else {
+ value = argspec[[argname]];
+ }
+
+ assign(argname, value, envir=argsenv);
+ }
+
+ if (interactive()) {
+ for (argname in names(argspec)) {
+ value = get(argname, envir=argsenv);
+
+ if (is.na(value) | is.null(value)) {
+ if (exists("cmdargs")) {
+ assign(argname, cmdargs[[argname]], envir=argsenv);
+ } else {
+ assign(argname, readline(sprintf("Please enter a value for '%s': ", argname)), envir=argsenv);
+ }
+ } else {
+ assign(argname, value, envir=argsenv);
+ }
+ }
+ } else {
+ cargs = commandArgs(TRUE);
+
+ if (length(cargs) == 0) {
+ .gsa.getargs.usage(argspec, doc);
+ }
+
+ for (i in 1:length(cargs)) {
+ if (length(grep("^-", cargs[i], ignore.case=TRUE)) > 0) {
+ key = gsub("-", "", cargs[i]);
+ value = cargs[i+1];
+
+ if (key == "h" | key == "help") {
+ .gsa.getargs.usage(argspec, doc);
+ }
+
+ if (length(grep("^[\\d\\.e\\+\\-]+$", value, perl=TRUE, ignore.case=TRUE)) > 0) {
+ value = as.numeric(value);
+ }
+
+ assign(key, value, envir=argsenv);
+ }
+ }
+ }
+
+ args = as.list(argsenv);
+
+ isMissingArgs = 0;
+ missingArgs = c();
+
+ for (arg in names(argspec)) {
+ if (is.na(args[[arg]]) | is.null(args[[arg]])) {
+ gsa.warn(sprintf("Value for required argument '-%s' was not specified", arg));
+
+ isMissingArgs = 1;
+ missingArgs = c(missingArgs, arg);
+ }
+ }
+
+ if (isMissingArgs) {
+ gsa.error(
+ paste(
+ "Missing required arguments: -",
+ paste(missingArgs, collapse=" -"),
+ ". Specify -h or -help to this script for a list of available arguments.",
+ sep=""
+ )
+ );
+ }
+
+ args;
+}
diff --git a/public/R/src/gsalib/R/gsa.message.R b/public/R/src/gsalib/R/gsa.message.R
new file mode 100644
index 000000000..a2b909d3d
--- /dev/null
+++ b/public/R/src/gsalib/R/gsa.message.R
@@ -0,0 +1,3 @@
+gsa.message <- function(message) {
+ message(sprintf("[gsalib] %s", message));
+}
diff --git a/public/R/src/gsalib/R/gsa.plot.venn.R b/public/R/src/gsalib/R/gsa.plot.venn.R
new file mode 100644
index 000000000..b1353ccc1
--- /dev/null
+++ b/public/R/src/gsalib/R/gsa.plot.venn.R
@@ -0,0 +1,50 @@
+gsa.plot.venn <-
+function(a, b, c=0, a_and_b, a_and_c=0, b_and_c=0,
+ col=c("#FF6342", "#63C6DE", "#ADDE63"),
+ pos=c(0.20, 0.20, 0.80, 0.82),
+ debug=0
+ ) {
+ library(png);
+ library(graphics);
+
+ # Set up properties
+ for (i in 1:length(col)) {
+ rgbcol = col2rgb(col[i]);
+ col[i] = sprintf("%02X%02X%02X", rgbcol[1], rgbcol[2], rgbcol[3]);
+ }
+
+ chco = paste(col[1], col[2], col[3], sep=",");
+ chd = paste(a, b, c, a_and_b, a_and_c, b_and_c, sep=",");
+
+ props = c(
+ 'cht=v',
+ 'chs=525x525',
+ 'chds=0,10000000000',
+ paste('chco=', chco, sep=""),
+ paste('chd=t:', chd, sep="")
+ );
+ proplist = paste(props[1], props[2], props[3], props[4], props[5], sep='&');
+
+ # Get the venn diagram (as a temporary file)
+ filename = tempfile("venn");
+ cmd = paste("wget -O ", filename, " 'http://chart.apis.google.com/chart?", proplist, "' > /dev/null 2>&1", sep="");
+
+ if (debug == 1) {
+ print(cmd);
+ }
+ system(cmd);
+
+ # Render the temp png file into a plotting frame
+ a = readPNG(filename);
+
+ plot(0, 0, type="n", xaxt="n", yaxt="n", bty="n", xlim=c(0, 1), ylim=c(0, 1), xlab="", ylab="");
+ if (c == 0 || a >= b) {
+ rasterImage(a, pos[1], pos[2], pos[3], pos[4]);
+ } else {
+ rasterImage(a, 0.37+pos[1], 0.37+pos[2], 0.37+pos[3], 0.37+pos[4], angle=180);
+ }
+
+ # Clean up!
+ unlink(filename);
+}
+
diff --git a/public/R/src/gsalib/R/gsa.read.eval.R b/public/R/src/gsalib/R/gsa.read.eval.R
new file mode 100644
index 000000000..f1d49092b
--- /dev/null
+++ b/public/R/src/gsalib/R/gsa.read.eval.R
@@ -0,0 +1,83 @@
+.gsa.attemptToLoadFile <- function(filename) {
+ file = NA;
+
+ if (file.exists(filename) & file.info(filename)$size > 500) {
+ file = read.csv(filename, header=TRUE, comment.char="#");
+ }
+
+ file;
+}
+
+gsa.read.eval <-
+function(evalRoot) {
+ fileAlleleCountStats = paste(evalRoot, ".AlleleCountStats.csv", sep="");
+ fileCompOverlap = paste(evalRoot, ".Comp_Overlap.csv", sep="");
+ fileCountVariants = paste(evalRoot, ".Count_Variants.csv", sep="");
+ fileGenotypeConcordance = paste(evalRoot, ".Genotype_Concordance.csv", sep="");
+ fileMetricsByAc = paste(evalRoot, ".MetricsByAc.csv", sep="");
+ fileMetricsBySample = paste(evalRoot, ".MetricsBySample.csv", sep="");
+ fileQuality_Metrics_by_allele_count = paste(evalRoot, ".Quality_Metrics_by_allele_count.csv", sep="");
+ fileQualityScoreHistogram = paste(evalRoot, ".QualityScoreHistogram.csv", sep="");
+ fileSampleStatistics = paste(evalRoot, ".Sample_Statistics.csv", sep="");
+ fileSampleSummaryStatistics = paste(evalRoot, ".Sample_Summary_Statistics.csv", sep="");
+ fileSimpleMetricsBySample = paste(evalRoot, ".SimpleMetricsBySample.csv", sep="");
+ fileTi_slash_Tv_Variant_Evaluator = paste(evalRoot, ".Ti_slash_Tv_Variant_Evaluator.csv", sep="");
+ fileTiTvStats = paste(evalRoot, ".TiTvStats.csv", sep="");
+ fileVariant_Quality_Score = paste(evalRoot, ".Variant_Quality_Score.csv", sep="");
+
+ eval = list(
+ AlleleCountStats = NA,
+ CompOverlap = NA,
+ CountVariants = NA,
+ GenotypeConcordance = NA,
+ MetricsByAc = NA,
+ MetricsBySample = NA,
+ Quality_Metrics_by_allele_count = NA,
+ QualityScoreHistogram = NA,
+ SampleStatistics = NA,
+ SampleSummaryStatistics = NA,
+ SimpleMetricsBySample = NA,
+ TiTv = NA,
+ TiTvStats = NA,
+ Variant_Quality_Score = NA,
+
+ CallsetNames = c(),
+ CallsetOnlyNames = c(),
+ CallsetFilteredNames = c()
+ );
+
+ eval$AlleleCountStats = .gsa.attemptToLoadFile(fileAlleleCountStats);
+ eval$CompOverlap = .gsa.attemptToLoadFile(fileCompOverlap);
+ eval$CountVariants = .gsa.attemptToLoadFile(fileCountVariants);
+ eval$GenotypeConcordance = .gsa.attemptToLoadFile(fileGenotypeConcordance);
+ eval$MetricsByAc = .gsa.attemptToLoadFile(fileMetricsByAc);
+ eval$MetricsBySample = .gsa.attemptToLoadFile(fileMetricsBySample);
+ eval$Quality_Metrics_by_allele_count = .gsa.attemptToLoadFile(fileQuality_Metrics_by_allele_count);
+ eval$QualityScoreHistogram = .gsa.attemptToLoadFile(fileQualityScoreHistogram);
+ eval$SampleStatistics = .gsa.attemptToLoadFile(fileSampleStatistics);
+ eval$SampleSummaryStatistics = .gsa.attemptToLoadFile(fileSampleSummaryStatistics);
+ eval$SimpleMetricsBySample = .gsa.attemptToLoadFile(fileSimpleMetricsBySample);
+ eval$TiTv = .gsa.attemptToLoadFile(fileTi_slash_Tv_Variant_Evaluator);
+ eval$TiTvStats = .gsa.attemptToLoadFile(fileTiTvStats);
+ eval$Variant_Quality_Score = .gsa.attemptToLoadFile(fileVariant_Quality_Score);
+
+ uniqueJexlExpressions = unique(eval$TiTv$jexl_expression);
+ eval$CallsetOnlyNames = as.vector(uniqueJexlExpressions[grep("FilteredIn|Intersection|none", uniqueJexlExpressions, invert=TRUE, ignore.case=TRUE)]);
+ eval$CallsetNames = as.vector(gsub("-only", "", eval$CallsetOnlyNames));
+ eval$CallsetFilteredNames = as.vector(c(
+ paste(gsub("^(\\w)", "In\\U\\1", eval$CallsetNames[1], perl=TRUE), "-Filtered", gsub("^(\\w)", "In\\U\\1", eval$CallsetNames[2], perl=TRUE), sep=""),
+ paste(gsub("^(\\w)", "In\\U\\1", eval$CallsetNames[2], perl=TRUE), "-Filtered", gsub("^(\\w)", "In\\U\\1", eval$CallsetNames[1], perl=TRUE), sep=""))
+ );
+
+ if (!(eval$CallsetFilteredNames[1] %in% unique(eval$TiTv$jexl_expression))) {
+ eval$CallsetFilteredNames[1] = paste("In", eval$CallsetNames[1], "-FilteredIn", eval$CallsetNames[2], sep="");
+ }
+
+ if (!(eval$CallsetFilteredNames[2] %in% unique(eval$TiTv$jexl_expression))) {
+ eval$CallsetFilteredNames[2] = paste("In", eval$CallsetNames[2], "-FilteredIn", eval$CallsetNames[1], sep="");
+ #eval$CallsetFilteredNames[2] = paste(gsub("^(\\w)", "In", eval$CallsetNames[2], perl=TRUE), "-Filtered", gsub("^(\\w)", "In", eval$CallsetNames[1], perl=TRUE), sep="");
+ }
+
+ eval;
+}
+
diff --git a/public/R/src/gsalib/R/gsa.read.gatkreport.R b/public/R/src/gsalib/R/gsa.read.gatkreport.R
new file mode 100644
index 000000000..9b3ef1ad1
--- /dev/null
+++ b/public/R/src/gsalib/R/gsa.read.gatkreport.R
@@ -0,0 +1,64 @@
+# Load a table into the specified environment. Make sure that each new table gets a unique name (this allows one to cat a bunch of tables with the same name together and load them into R without each table overwriting the last.
+.gsa.assignGATKTableToEnvironment <- function(tableName, tableHeader, tableRows, tableEnv) {
+ d = data.frame(tableRows, row.names=NULL, stringsAsFactors=FALSE);
+ colnames(d) = tableHeader;
+
+ for (i in 1:ncol(d)) {
+ v = suppressWarnings(as.numeric(d[,i]));
+
+ if (length(na.omit(as.numeric(v))) == length(d[,i])) {
+ d[,i] = v;
+ }
+ }
+
+ usedNames = ls(envir=tableEnv, pattern=tableName);
+
+ if (length(usedNames) > 0) {
+ tableName = paste(tableName, ".", length(usedNames), sep="");
+ }
+
+ assign(tableName, d, envir=tableEnv);
+}
+
+# Load all GATKReport tables from a file
+gsa.read.gatkreport <- function(filename) {
+ con = file(filename, "r", blocking = TRUE);
+ lines = readLines(con);
+ close(con);
+
+ tableEnv = new.env();
+
+ tableName = NA;
+ tableHeader = c();
+ tableRows = c();
+
+ for (line in lines) {
+ if (length(grep("^##:GATKReport.v0.1[[:space:]]+", line, ignore.case=TRUE)) > 0) {
+ headerFields = unlist(strsplit(line, "[[:space:]]+"));
+
+ if (!is.na(tableName)) {
+ .gsa.assignGATKTableToEnvironment(tableName, tableHeader, tableRows, tableEnv);
+ }
+
+ tableName = headerFields[2];
+ tableHeader = c();
+ tableRows = c();
+ } else if (length(grep("^[[:space:]]*$", line)) > 0 | length(grep("^[[:space:]]*#", line)) > 0) {
+ # do nothing
+ } else if (!is.na(tableName)) {
+ row = unlist(strsplit(line, "[[:space:]]+"));
+
+ if (length(tableHeader) == 0) {
+ tableHeader = row;
+ } else {
+ tableRows = rbind(tableRows, row);
+ }
+ }
+ }
+
+ if (!is.na(tableName)) {
+ .gsa.assignGATKTableToEnvironment(tableName, tableHeader, tableRows, tableEnv);
+ }
+
+ gatkreport = as.list(tableEnv);
+}
diff --git a/public/R/src/gsalib/R/gsa.read.squidmetrics.R b/public/R/src/gsalib/R/gsa.read.squidmetrics.R
new file mode 100644
index 000000000..39fa1ad32
--- /dev/null
+++ b/public/R/src/gsalib/R/gsa.read.squidmetrics.R
@@ -0,0 +1,28 @@
+gsa.read.squidmetrics = function(project, bylane = FALSE) {
+ suppressMessages(library(ROracle));
+
+ drv = dbDriver("Oracle");
+ con = dbConnect(drv, "REPORTING/REPORTING@ora01:1521/SEQPROD");
+
+ if (bylane) {
+ statement = paste("SELECT * FROM ILLUMINA_PICARD_METRICS WHERE \"Project\" = '", project, "'", sep="");
+ print(statement);
+
+ rs = dbSendQuery(con, statement = statement);
+ d = fetch(rs, n=-1);
+ dbHasCompleted(rs);
+ dbClearResult(rs);
+ } else {
+ statement = paste("SELECT * FROM ILLUMINA_SAMPLE_STATUS_AGG WHERE \"Project\" = '", project, "'", sep="");
+ print(statement);
+
+ rs = dbSendQuery(con, statement = statement);
+ d = fetch(rs, n=-1);
+ dbHasCompleted(rs);
+ dbClearResult(rs);
+ }
+
+ oraCloseDriver(drv);
+
+ subset(d, Project == project);
+}
diff --git a/public/R/src/gsalib/R/gsa.read.vcf.R b/public/R/src/gsalib/R/gsa.read.vcf.R
new file mode 100644
index 000000000..5beb6455d
--- /dev/null
+++ b/public/R/src/gsalib/R/gsa.read.vcf.R
@@ -0,0 +1,23 @@
+gsa.read.vcf <- function(vcffile, skip=0, nrows=-1, expandGenotypeFields = FALSE) {
+ headers = readLines(vcffile, n=100);
+ headerline = headers[grep("#CHROM", headers)];
+ header = unlist(strsplit(gsub("#", "", headerline), "\t"))
+
+ d = read.table(vcffile, header=FALSE, skip=skip, nrows=nrows, stringsAsFactors=FALSE);
+ colnames(d) = header;
+
+ if (expandGenotypeFields) {
+ columns = ncol(d);
+
+ offset = columns + 1;
+ for (sampleIndex in 10:columns) {
+ gt = unlist(lapply(strsplit(d[,sampleIndex], ":"), function(x) x[1]));
+ d[,offset] = gt;
+ colnames(d)[offset] = sprintf("%s.GT", colnames(d)[sampleIndex]);
+
+ offset = offset + 1;
+ }
+ }
+
+ return(d);
+}
diff --git a/public/R/src/gsalib/R/gsa.warn.R b/public/R/src/gsalib/R/gsa.warn.R
new file mode 100644
index 000000000..7ee08ce65
--- /dev/null
+++ b/public/R/src/gsalib/R/gsa.warn.R
@@ -0,0 +1,3 @@
+gsa.warn <- function(message) {
+ gsa.message(sprintf("Warning: %s", message));
+}
diff --git a/public/R/src/gsalib/Read-and-delete-me b/public/R/src/gsalib/Read-and-delete-me
new file mode 100644
index 000000000..d04323a6e
--- /dev/null
+++ b/public/R/src/gsalib/Read-and-delete-me
@@ -0,0 +1,9 @@
+* Edit the help file skeletons in 'man', possibly combining help files
+ for multiple functions.
+* Put any C/C++/Fortran code in 'src'.
+* If you have compiled code, add a .First.lib() function in 'R' to load
+ the shared library.
+* Run R CMD build to build the package tarball.
+* Run R CMD check to check the package tarball.
+
+Read "Writing R Extensions" for more information.
diff --git a/public/R/src/gsalib/data/tearsheetdrop.jpg b/public/R/src/gsalib/data/tearsheetdrop.jpg
new file mode 100755
index 0000000000000000000000000000000000000000..c9d480fa05f4acf066e3bf1cf469db47b8a1afc3
GIT binary patch
literal 50343
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