Mercurial > repos > shians > shrnaseq
changeset 6:3d04308a99f9
- Added differentially expressed hairpin count output
- Added running time output
- Added counts table output
author | shian_su <registertonysu@gmail.com> |
---|---|
date | Fri, 11 Apr 2014 17:17:15 +1000 |
parents | 17befe9f8b03 |
children | 91e411fcdecc |
files | hairpinTool.R hairpinTool.xml |
diffstat | 2 files changed, 192 insertions(+), 56 deletions(-) [+] |
line wrap: on
line diff
--- a/hairpinTool.R Mon Feb 24 14:50:08 2014 +1100 +++ b/hairpinTool.R Fri Apr 11 17:17:15 2014 +1000 @@ -1,3 +1,51 @@ +# ARGS: 1.inputType -String specifying format of input (fastq or table) +# IF inputType is "fastQ": +# 2*.fastqPath -One or more strings specifying path to fastq files +# 2.annoPath -String specifying path to hairpin annotation table +# 3.samplePath -String specifying path to sample annotation table +# 4.barStart -Integer specifying starting position of barcode +# 5.barEnd -Integer specifying ending position of barcode +# 6.hpStart -Integer specifying startins position of hairpin +# unique region +# 7.hpEnd -Integer specifying ending position of hairpin +# unique region +# ### +# IF inputType is "counts": +# 2.countPath -String specifying path to count table +# 3.annoPath -String specifying path to hairpin annotation table +# 4.samplePath -String specifying path to sample annotation table +# ### +# 8.cpmReq -Float specifying cpm requirement +# 9.sampleReq -Integer specifying cpm requirement +# 10.fdrThresh -Float specifying the FDR requirement +# 11.lfcThresh -Float specifying the log-fold-change requirement +# 12.workMode -String specifying exact test or GLM usage +# 13.htmlPath -String specifying path to HTML file +# 14.folderPath -STring specifying path to folder for output +# IF workMode is "classic" (exact test) +# 15.pairData[2] -String specifying first group for exact test +# 16.pairData[1] -String specifying second group for exact test +# ### +# IF workMode is "glm" +# 15.contrastData -String specifying contrasts to be made +# 16.roastOpt -String specifying usage of gene-wise tests +# 17.hairpinReq -String specifying hairpin requirement for gene- +# wise test +# 18.selectOpt -String specifying type of selection for barcode +# plots +# 19.selectVals -String specifying members selected for barcode +# plots +# +# OUT: Bar Plot of Counts Per Index +# Bar Plot of Counts Per Hairpin +# MDS Plot +# Smear Plot +# Barcode Plots (If Genewise testing was selected) +# Top Expression Table +# HTML file linking to the ouputs +# +# Author: Shian Su - registertonysu@gmail.com - Jan 2014 + # Record starting time timeStart <- as.character(Sys.time()) @@ -115,7 +163,7 @@ fastqPath <- as.character(gsub("fastq::", "", argv[grepl("fastq::", argv)], fixed=TRUE)) argv <- argv[!grepl("fastq::", argv, fixed=TRUE)] - hairpinPath <- as.character(argv[2]) + annoPath <- as.character(argv[2]) samplePath <- as.character(argv[3]) barStart <- as.numeric(argv[4]) barEnd <- as.numeric(argv[5]) @@ -134,6 +182,7 @@ workMode <- as.character(argv[12]) htmlPath <- as.character(argv[13]) folderPath <- as.character(argv[14]) + if (workMode=="classic") { pairData <- character() pairData[2] <- as.character(argv[15]) @@ -147,14 +196,13 @@ } # Read in inputs -if (inputType=="fastq") { - samples <- read.table(samplePath, header=TRUE, sep="\t") - hairpins <- read.table(hairpinPath, header=TRUE, sep="\t") -} else if (inputType=="counts") { - samples <- read.table(samplePath, header=TRUE, sep="\t") + +samples <- read.table(samplePath, header=TRUE, sep="\t") +anno <- read.table(annoPath, header=TRUE, sep="\t") +if (inputType=="counts") { counts <- read.table(countPath, header=TRUE, sep="\t") - anno <- read.table(annoPath, header=TRUE, sep="\t") } + ###################### Check inputs for correctness ############################ samples$ID <- make.names(samples$ID) @@ -166,16 +214,16 @@ tab <- table(samples$ID) offenders <- paste(names(tab[tab>1]), collapse=", ") offenders <- unmake.names(offenders) - stop("ID column of sample annotation must have unique values, values ", + stop("'ID' column of sample annotation must have unique values, values ", offenders, " are repeated") } # Check that IDs in sample annotation are unique if (inputType=="fastq") { - - if (any(table(hairpins$ID)>1)){ - tab <- table(hairpins$ID) + + if (any(table(anno$ID)>1)){ + tab <- table(anno$ID) offenders <- paste(names(tab[tab>1]), collapse=", ") - stop("ID column of hairpin annotation must have unique values, values ", + stop("'ID' column of hairpin annotation must have unique values, values ", offenders, " are repeated") } # Check that IDs in hairpin annotation are unique @@ -187,10 +235,20 @@ if (any(table(counts$ID)>1)){ tab <- table(counts$ID) offenders <- paste(names(tab[tab>1]), collapse=", ") - stop("ID column of count table must have unique values, values ", + stop("'ID' column of count table must have unique values, values ", offenders, " are repeated") } # Check that IDs in count table are unique } +if (workMode=="glm") { + if (roastOpt == "yes") { + if (is.na(match("Gene", colnames(anno)))) { + tempStr <- paste("Gene-wise tests selected but'Gene' column not", + "specified in hairpin annotation file") + stop(tempStr) + } + } +} + ################################################################################ # Process arguments @@ -216,7 +274,7 @@ } # Generate output folder and paths -dir.create(folderPath) +dir.create(folderPath, showWarnings=FALSE) # Generate links for outputs imgOut("barHairpin") @@ -243,6 +301,8 @@ barcodePdf[i] <- makeOut(paste0("barcode(", contrastData[i], ").pdf")) } } +countsOut <- makeOut("counts.tsv") + # Initialise data for html links and images, table with the link label and # link address linkData <- data.frame(Label=character(), Link=character(), @@ -276,22 +336,21 @@ } if (inputType=="fastq") { -# Use EdgeR hairpin process and capture outputs -hpReadout <- capture.output( - data <- processHairpinReads(fastqPath, samplePath, hairpinPath, + # Use EdgeR hairpin process and capture outputs + hpReadout <- capture.output( + data <- processHairpinReads(fastqPath, samplePath, annoPath, hairpinStart=hpStart, hairpinEnd=hpEnd, verbose=TRUE) -) - -# Remove function output entries that show processing data or is empty -hpReadout <- hpReadout[hpReadout!=""] -hpReadout <- hpReadout[!grepl("Processing", hpReadout)] -hpReadout <- hpReadout[!grepl("in file", hpReadout)] -hpReadout <- gsub(" -- ", "", hpReadout, fixed=TRUE) - - -# Make the names of groups syntactically valid (replace spaces with periods) -data$samples$group <- make.names(data$samples$group) + ) + + # Remove function output entries that show processing data or is empty + hpReadout <- hpReadout[hpReadout!=""] + hpReadout <- hpReadout[!grepl("Processing", hpReadout)] + hpReadout <- hpReadout[!grepl("in file", hpReadout)] + hpReadout <- gsub(" -- ", "", hpReadout, fixed=TRUE) + + # Make the names of groups syntactically valid (replace spaces with periods) + data$samples$group <- make.names(data$samples$group) } else if (inputType=="counts") { # Process counts information, set ID column to be row names rownames(counts) <- counts$ID @@ -318,14 +377,17 @@ # Create DGEList data <- DGEList(counts=counts, lib.size=colSums(counts), norm.factors=rep(1,ncol(counts)), genes=anno, group=factors) - + # Make the names of groups syntactically valid (replace spaces with periods) data$samples$group <- make.names(data$samples$group) } # Filter hairpins with low counts +preFilterCount <- nrow(data) sel <- rowSums(cpm(data$counts) > cpmReq) >= sampleReq data <- data[sel, ] +postFilterCount <- nrow(data) +filteredCount <- preFilterCount-postFilterCount # Estimate dispersions data <- estimateDisp(data) @@ -540,8 +602,17 @@ } } -# Record ending time +ID <- rownames(data$counts) +outputCounts <- cbind(ID, data$counts) +write.table(outputCounts, file=countsOut, row.names=FALSE, sep="\t") +linkName <- "Counts table (.tsv)" +linkAddr <- "counts.tsv" +linkData <- rbind(linkData, c(linkName, linkAddr)) + +# Record ending time and calculate total run time timeEnd <- as.character(Sys.time()) +timeTaken <- capture.output(round(difftime(timeEnd,timeStart), digits=3)) +timeTaken <- gsub("Time difference of ", "", timeTaken, fixed=TRUE) ################################################################################ ### HTML Generation ################################################################################ @@ -559,12 +630,12 @@ ListItem(hpReadout[1]) ListItem(hpReadout[2]) cata("</ul>\n") - cata(hpReadout[3], "<br/>\n") + cata(hpReadout[3], "<br />\n") cata("<ul>\n") ListItem(hpReadout[4]) ListItem(hpReadout[7]) cata("</ul>\n") - cata(hpReadout[8:11], sep="<br/>\n") + cata(hpReadout[8:11], sep="<br />\n") cata("<br />\n") cata("<b>Please check that read percentages are consistent with ") cata("expectations.</b><br >\n") @@ -582,7 +653,7 @@ cata("<h4>Output:</h4>\n") cata("All images displayed have PDF copy at the bottom of the page, these can ") -cata("exported in a pdf viewer to high resolution image format. <br/>\n") +cata("exported in a pdf viewer to high resolution image format. <br />\n") for (i in 1:nrow(imageData)) { if (grepl("barcode", imageData$Link[i])) { if (packageVersion("limma")<"3.19.19") { @@ -596,7 +667,7 @@ HtmlImage(imageData$Link[i], imageData$Label[i]) } } -cata("<br/>\n") +cata("<br />\n") cata("<h4>Plots:</h4>\n") for (i in 1:nrow(linkData)) { @@ -617,14 +688,80 @@ cata("disk icon to download all files in a zip archive.</p>\n") cata("<p>.tsv files are tab seperated files that can be viewed using Excel ") cata("or other spreadsheet programs</p>\n") + +cata("<h4>Additional Information:</h4>\n") + +if (inputType == "fastq") { + ListItem("Data was gathered from fastq raw read file(s).") +} else if (inputType == "counts") { + ListItem("Data was gathered from a table of counts.") +} + +if (cpmReq!=0 && sampleReq!=0) { + tempStr <- paste("Hairpins that do not have more than", cpmReq, + "CPM in at least", sampleReq, "samples are considered", + "insignificant and filtered out.") + ListItem(tempStr) + filterProp <- round(filteredCount/preFilterCount*100, digits=2) + tempStr <- paste0(filteredCount, " of ", preFilterCount," (", filterProp, + "%) hairpins were filtered out for low count-per-million.") + ListItem(tempStr) +} + +if (workMode == "classic") { + ListItem("An exact test was performed on each hairpin.") +} else if (workMode == "glm") { + ListItem("A generalised linear model was fitted to each hairpin.") +} + + + +cit <- character() +link <-character() +link[1] <- paste0("<a href=\"", + "http://www.bioconductor.org/packages/release/bioc/", + "vignettes/limma/inst/doc/usersguide.pdf", + "\">", "limma User's Guide", "</a>.") +link[2] <- paste0("<a href=\"", + "http://www.bioconductor.org/packages/release/bioc/", + "vignettes/edgeR/inst/doc/edgeRUsersGuide.pdf", + "\">", "edgeR User's Guide", "</a>") + +cit[1] <- paste("Robinson MD, McCarthy DJ and Smyth GK (2010).", + "edgeR: a Bioconductor package for differential", + "expression analysis of digital gene expression", + "data. Bioinformatics 26, 139-140") +cit[2] <- paste("Robinson MD and Smyth GK (2007). Moderated statistical tests", + "for assessing differences in tag abundance. Bioinformatics", + "23, 2881-2887") +cit[3] <- paste("Robinson MD and Smyth GK (2008). Small-sample estimation of", + "negative binomial dispersion, with applications to SAGE data.", + "Biostatistics, 9, 321-332") + +cit[4] <- paste("McCarthy DJ, Chen Y and Smyth GK (2012). Differential", + "expression analysis of multifactor RNA-Seq experiments with", + "respect to biological variation. Nucleic Acids Research 40,", + "4288-4297") + +cata("<h4>Citations</h4>") +cata("<ol>\n") +ListItem(cit[1]) +ListItem(cit[2]) +ListItem(cit[3]) +ListItem(cit[4]) +cata("</ol>\n") + cata("<table border=\"0\">\n") - cata("<tr>\n") TableItem("Task started at:"); TableItem(timeStart) cata("</tr>\n") cata("<tr>\n") TableItem("Task ended at:"); TableItem(timeEnd) cata("</tr>\n") +cata("<tr>\n") +TableItem("Task run time:"); TableItem(timeTaken) +cata("<tr>\n") +cata("</table>\n") cata("</body>\n") cata("</html>")
--- a/hairpinTool.xml Mon Feb 24 14:50:08 2014 +1100 +++ b/hairpinTool.xml Fri Apr 11 17:17:15 2014 +1000 @@ -1,11 +1,11 @@ -<tool id="shRNAseq" name="shRNAseq Tool" version="1.0.5"> +<tool id="shRNAseq" name="shRNAseq Tool" version="1.0.7"> <description> Analyse hairpin differential representation using edgeR </description> <requirements> - <requirement type="R-module">edgeR</requirement> - <requirement type="R-module">limma</requirement> + <requirement type="R-module" version="3.5.27">edgeR</requirement> + <requirement type="R-module" version="3.18.13">limma</requirement> </requirements> <stdio> @@ -13,8 +13,8 @@ </stdio> <command interpreter="Rscript"> - hairpinTool.R $inputOpt.type - #if $inputOpt.type=="fastq": + hairpinTool.R $inputOpt.inputType + #if $inputOpt.inputType=="fastq": #for $i, $fas in enumerate($inputOpt.fastq): fastq::$fas.file #end for @@ -22,7 +22,7 @@ $inputOpt.hairpin $inputOpt.samples - #if $inputOpt.positions.option=="yes": + #if $inputOpt.positions.posOption=="yes": $inputOpt.positions.barstart $inputOpt.positions.barend $inputOpt.positions.hpstart @@ -35,12 +35,12 @@ #end if #else: $inputOpt.counts - $inputOpt.anno - "$inputOpt.factors" + $inputOpt.hairpin + $inputOpt.samples 0 0 0 #end if - #if $filterCPM.option=="yes": + #if $filterCPM.filtOption=="yes": $filterCPM.cpmReq $filterCPM.sampleReq #else: @@ -57,12 +57,12 @@ #if $workMode.mode=="classic": "$workMode.pair1" "$workMode.pair2" - #else: + #elif $workMode.mode=="glm": "$workMode.contrast" - $workMode.roast.option - #if $workMode.roast.option=="yes": + $workMode.roast.roastOption + #if $workMode.roast.roastOption=="yes": $workMode.roast.hairpinReq - $workMode.roast.select.option + $workMode.roast.select.selOption "$workMode.roast.select.selection" #else: 0 @@ -74,7 +74,7 @@ <inputs> <conditional name="inputOpt"> - <param name="type" type="select" label="Input File Type"> + <param name="inputType" type="select" label="Input File Type"> <option value="fastq">FastQ File</option> <option value="counts">Table of Counts</option> </param> @@ -92,7 +92,7 @@ </repeat> <conditional name="positions"> - <param name="option" type="select" + <param name="posOption" type="select" label="Specify Barcode and Hairpin Locations?" help="Default Positions: Barcode: 1 to 5, Hairpin: 37 to 57."> <option value="no" selected="True">No</option> @@ -118,15 +118,15 @@ <when value="counts"> <param name="counts" type="data" format="tabular" label="Counts Table"/> - <param name="anno" type="data" format="tabular" + <param name="hairpin" type="data" format="tabular" label="Hairpin Annotation"/> - <param name="factors" type="data" format="tabular" + <param name="samples" type="data" format="tabular" label="Sample Annotation"/> </when> </conditional> <conditional name="filterCPM"> - <param name="option" type="select" label="Filter Low CPM?" + <param name="filtOption" type="select" label="Filter Low CPM?" help="Ignore hairpins with very low representation when performing analysis."> <option value="yes">Yes</option> @@ -172,7 +172,7 @@ expression."/> <conditional name="roast"> - <param name="option" type="select" + <param name="roastOption" type="select" label="Perform Gene Level Analysis?" help="Analyse LogFC tendencies for hairpins belonging to the same gene."> @@ -187,7 +187,7 @@ be analysed."/> <conditional name="select"> - <param name="option" type="select" + <param name="selOption" type="select" label="Gene Selection Method"> <option value="rank">By p-value Rank</option> <option value="geneID">By Gene Identifier</option> @@ -232,7 +232,6 @@ <outputs> <data format="html" name="outFile" label="shRNAseq Analysis"/> </outputs> - <help> .. class:: infomark