diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 791ef96be43a9ba90e9ef57e51a8e89a7f17091a..03a422fc78ecb76ac0bae7962cda596acec7e15b 100755 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -36,16 +36,19 @@ simple_1: - branches - tags except: - - develop - - master + refs: + - develop + - master script: - - nextflow run workflow/main.nf --fastq "$CI_PROJECT_DIR/test_data/hu.v3s1r500/*.fastq.gz" --designFile "$CI_PROJECT_DIR/test_data/hu.v3s1r500/design.csv" --genome 'GRCh38-3.0.0' --kitVersion 'three' --version '3.0.2' - - pytest -m count302 + - nextflow run workflow/main.nf --fastq "$CI_PROJECT_DIR/test_data/hu.v3s1r500/*.fastq.gz" --designFile "$CI_PROJECT_DIR/test_data/hu.v3s1r500/design.csv" --genome 'GRCh38-3.0.0' --kitVersion 'three' --version '3.1.0' + - pytest -m count310 artifacts: name: "$CI_JOB_NAME" when: always paths: - .nextflow.log + - workflow/output/count310/sample1/outs/web_summary.html + - workflow/output/multiqc/run/multiqc_report.html expire_in: 2 days retry: max: 1 @@ -57,17 +60,20 @@ simple_2: only: - branches except: - - develop - - master - - tags + refs: + - develop + - master + - tags script: - - nextflow run workflow/main.nf --fastq "$CI_PROJECT_DIR/test_data/mu.v3s1r500/*.fastq.gz" --designFile "$CI_PROJECT_DIR/test_data/mu.v3s1r500/design.csv" --genome 'mm10-3.0.0' --kitVersion 'three' --version '3.0.1' - - pytest -m count301 + - nextflow run workflow/main.nf --fastq "$CI_PROJECT_DIR/test_data/mu.v3s1r500/*.fastq.gz" --designFile "$CI_PROJECT_DIR/test_data/mu.v3s1r500/design.csv" --genome 'mm10-3.0.0' --kitVersion 'three' --version '3.1.0' + - pytest -m count310 artifacts: name: "$CI_JOB_NAME" when: always paths: - .nextflow.log + - workflow/output/count310/sample1/outs/web_summary.html + - workflow/output/multiqc/run/multiqc_report.html expire_in: 2 days retry: max: 1 @@ -80,36 +86,43 @@ detailed_1: - develop - master except: - - tags + refs: + - tags script: - - nextflow run workflow/main.nf --fastq "$CI_PROJECT_DIR/test_data/hu.v3s2r10k/*.fastq.gz" --designFile "$CI_PROJECT_DIR/test_data/hu.v3s2r10k/design.csv" --genome 'GRCh38-3.0.0' --kitVersion 'auto' --version '3.0.2' - - pytest -m count302 + - nextflow run workflow/main.nf --fastq "$CI_PROJECT_DIR/test_data/hu.v3s2r10k/*.fastq.gz" --designFile "$CI_PROJECT_DIR/test_data/hu.v3s2r10k/design.csv" --genome 'GRCh38-3.0.0' --kitVersion 'auto' --version '3.1.0' + - pytest -m count310 artifacts: name: "$CI_JOB_NAME" when: always paths: - .nextflow.log + - workflow/output/count310/sample1/outs/web_summary.html + - workflow/output/multiqc/run/multiqc_report.html expire_in: 2 days retry: max: 1 when: - always + detailed_2: stage: detailed only: - develop - master except: - - tags + refs: + - tags script: - - nextflow run workflow/main.nf --fastq "$CI_PROJECT_DIR/test_data/mu.v3s2r10k/*.fastq.gz" --designFile "$CI_PROJECT_DIR/test_data/mu.v3s2r10k/design.csv" --genome 'mm10-3.0.0' --kitVersion 'three' --version '3.0.2' + - nextflow run workflow/main.nf --fastq "$CI_PROJECT_DIR/test_data/hu.v3s2r10k/*.fastq.gz" --designFile "$CI_PROJECT_DIR/test_data/hu.v3s2r10k/design.csv" --genome 'GRCh38-3.0.0' --kitVersion 'auto' --version '3.0.2' - pytest -m count302 artifacts: name: "$CI_JOB_NAME" when: always paths: - .nextflow.log + - workflow/output/count302/sample1/outs/web_summary.html + - workflow/output/multiqc/run/multiqc_report.html expire_in: 2 days retry: max: 1 @@ -122,7 +135,32 @@ detailed_3: - develop - master except: - - tags + refs: + - tags + script: + - nextflow run workflow/main.nf --fastq "$CI_PROJECT_DIR/test_data/mu.v3s2r10k/*.fastq.gz" --designFile "$CI_PROJECT_DIR/test_data/mu.v3s2r10k/design.csv" --genome 'mm10-3.0.0' --kitVersion 'three' --version '3.0.1' + - pytest -m count301 + artifacts: + name: "$CI_JOB_NAME" + when: always + paths: + - .nextflow.log + - workflow/output/count301/sample1/outs/web_summary.html + - workflow/output/multiqc/run/multiqc_report.html + expire_in: 2 days + retry: + max: 1 + when: + - always + +detailed_4: + stage: detailed + only: + - develop + - master + except: + refs: + - tags script: - nextflow run workflow/main.nf --fastq "$CI_PROJECT_DIR/test_data/hu.v2s2r10k/*.fastq.gz" --designFile "$CI_PROJECT_DIR/test_data/hu.v2s2r10k/design.csv" --genome 'GRCh38-1.2.0' --kitVersion 'two' --version '2.1.1' - pytest -m count211 @@ -131,6 +169,8 @@ detailed_3: when: always paths: - .nextflow.log + - workflow/output/count211/sample1/outs/web_summary.html + - workflow/output/multiqc/run/multiqc_report.html expire_in: 2 days retry: max: 1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e2d478d74f3bd8cfaae2ea4be9eba073a8dfcef..df4bdebb1180a5eb2ed19928d12262bf84bd551e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,18 @@ -# v1.1.0 (in development) +# v1.2.0 +**User Facing** +* Add Cellranger Version 3.1.0 +* Add human/mouse farmyard reference Version 3.1.0 from 10x +* Add Vizapp (shiny) +* Fix mutiqc error +* Add MIT License + +**Background** +* Add CI Artifacts + +*Known Bugs* +* Vizapp does not yet work for Astrocyte + +# v1.1.0 **User Facing** * Make report (multiqc) for cellranger qc output, version, references diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..ce31415967a482f717d2e7eaea440fd34d4e9ba6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,25 @@ +MIT License + +Copyright (c) 2019 University of Texas Southwestern Medical Center. + +Contributors: Gervaise H. Henry, Jeremy Mathews, and Venkat Malladi + +Department: Bioinformatic Core Facility, Department of Bioinformatics + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 6892ea715becad0d2669be7313747d5679e6c85f..6323ec5b79b16f933558813f4c745cba11be01ef 100755 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ To Run: * path to the fastq location * R1 and R2 only necessary but can include I2 * only fastq's in designFile (see below) are used, not present will be ignored - * eg: **--fastq '/project/shared/bicf_workflow_ref/workflow_testdata/cellranger/cellranger_count/hu.v3s2r100k/\*.fastq.gz'** + * eg: **--fastq '/project/shared/bicf_workflow_ref/workflow_testdata/cellranger/cellranger_count/hu.v3s2r10k/\*.fastq.gz'** * **--designFile** * path to design file (csv format) location * column 1 = "Sample" @@ -35,7 +35,7 @@ To Run: * column 3 = "fastq_R2" * can have repeated "Sample" if there are multiple fastq R1/R2 pairs for the samples * can be downloaded [HERE](https://git.biohpc.swmed.edu/BICF/Astrocyte/cellranger_count/blob/master/docs/design.csv) - * eg: **--designFile '/project/shared/bicf_workflow_ref/workflow_testdata/cellranger/cellranger_count/hu.v3s2r100k/design.csv'** + * eg: **--designFile '/project/shared/bicf_workflow_ref/workflow_testdata/cellranger/cellranger_count/hu.v3s2r10k/design.csv'** * **--genome** * reference genome * requires workflow/conf/biohpc.config to work @@ -46,8 +46,9 @@ To Run: * *'hg19-1.2.0'* = Human GRCh37 (hg19) release 84 * *'mm10-3.0.0'* = Mouse GRCm38 (mm10) release 93 * *'mm10-3.0.0'* = Mouse GRCm38 (mm10) release 84 - * *'hg19_and_mm10-3.0.0'* = Human GRCh37 (hg19) + Mouse GRCm38 (mm19) release 93 - * *'hg19_and_mm10-1.2.0'* = Human GRCh37 (hg19) + Mouse GRCm38 (mm19) release 84 + * *'GRCh38_and_mm10-3.1.0'* = Human GRCh38 + Mouse GRCm38 (mm10) release 93 + * *'hg19_and_mm10-3.0.0'* = Human GRCh37 (hg19) + Mouse GRCm38 (mm10) release 93 + * *'hg19_and_mm10-1.2.0'* = Human GRCh37 (hg19) + Mouse GRCm38 (mm10) release 84 * *'ercc92-1.2.0'* = ERCC.92 Spike-In * if --genome is used then --genomeLocationFull is not necessary * eg: **--genome 'GRCh38-3.0.0'** @@ -83,16 +84,17 @@ To Run: * cellranger version * --version (cellranger version) 2.1.1 can only read --kitVersion of two (2) * options: + * *'3.1.0'* * *'3.0.2'* * *'3.0.1'* * *'2.1.1'* - * eg: **--version '3.0.2'** + * eg: **--version '3.1.0'** * **--outDir** * optional output directory for run * eg: **--outDir 'test'** * FULL EXAMPLE: ``` - nextflow run workflow/main.nf --fastq '/project/shared/bicf_workflow_ref/workflow_testdata/cellranger/cellranger_count/hu.v3s2r100k/*.fastq.gz' --designFile '/project/shared/bicf_workflow_ref/workflow_testdata/cellranger/cellranger_count/hu.v3s2r100k/design.csv' --genome 'GRCh38-3.0.0' --kitVersion 'three' --version '3.0.2' --outDir 'test' + nextflow run workflow/main.nf --fastq '/project/shared/bicf_workflow_ref/workflow_testdata/cellranger/cellranger_count/hu.v3s2r10k/*.fastq.gz' --designFile '/project/shared/bicf_workflow_ref/workflow_testdata/cellranger/cellranger_count/hu.v3s2r10k/design.csv' --genome 'GRCh38-3.0.0' --kitVersion 'three' --version '3.1.0' --outDir 'test' ``` * Design example: diff --git a/astrocyte_pkg.yml b/astrocyte_pkg.yml index 0c7a0a05e2792dc8ead17dd738c0135d19ec911a..1a7cb7a0cf81e44d4f67198cc57b5ad91fdd3820 100755 --- a/astrocyte_pkg.yml +++ b/astrocyte_pkg.yml @@ -43,6 +43,7 @@ workflow_modules: - 'cellranger/2.1.1' - 'cellranger/3.0.1' - 'cellranger/3.0.2' + - 'cellranger/3.1.0' - 'bcl2fastq/2.17.1.14' - 'multiqc/1.7' @@ -104,8 +105,9 @@ workflow_parameters: - ['hg19-1.2.0', 'Human GRCh37 (hg19) release 84'] - ['mm10-3.0.0', 'Mouse GRCm38 (mm10) release 93'] - ['mm10-1.2.0', 'Mouse GRCm38 (mm10) release 84'] - - ['hg19_and_mm10-3.0.0', 'Human GRCh37 (hg19) + Mouse GRCm38 (mm19) release 93'] - - ['hg19_and_mm10-1.2.0', 'Human GRCh37 (hg19) + Mouse GRCm38 (mm19) release 84'] + - ['GRCh38_and_mm10-3.1.0', 'Human GRCh38 + Mouse GRCm38 (mm10) release 93'] + - ['hg19_and_mm10-3.0.0', 'Human GRCh37 (hg19) + Mouse GRCm38 (mm10) release 93'] + - ['hg19_and_mm10-1.2.0', 'Human GRCh37 (hg19) + Mouse GRCm38 (mm10) release 84'] - ['ercc92-1.2.0', 'ERCC.92 Spike-In'] required: true description: | @@ -142,8 +144,9 @@ workflow_parameters: - id: version type: select - default: '3.0.2' + default: '3.1.0' choices: + - ['3.1.0', '3.1.0'] - ['3.0.2', '3.0.2'] - ['3.0.1', '3.0.1'] - ['2.1.1', '2.1.1'] diff --git a/docs/index.md b/docs/index.md index b2c1ad6c49707a7c493a047c659b3c1cf42acd7f..29cf0d399120909478055abf5538241312f28a40 100644 --- a/docs/index.md +++ b/docs/index.md @@ -36,8 +36,9 @@ To Run: * *'hg19-1.2.0'* = Human GRCh37 (hg19) release 84 * *'mm10-3.0.0'* = Human GRCm38 (mm10) release 93 * *'mm10-3.0.0'* = Human GRCm38 (mm10) release 84 - * *'hg19_and_mm10-3.0.0'* = Human GRCh37 (hg19) + Mouse GRCm38 (mm19) release 93 - * *'hg19_and_mm10-1.2.0'* = Human GRCh37 (hg19) + Mouse GRCm38 (mm19) release 84 + * *'GRCh38-and-mm10-3.1.0'* = Human GRCh38 + Mouse GRCm38 (mm10) release 93 + * *'hg19_and_mm10-3.0.0'* = Human GRCh37 (hg19) + Mouse GRCm38 (mm10) release 93 + * *'hg19_and_mm10-1.2.0'* = Human GRCh37 (hg19) + Mouse GRCm38 (mm10) release 84 * *'ercc92-1.2.0'* = ERCC.92 Spike-In * **expect cells** * Expected number of recovered cells. diff --git a/docs/references.md b/docs/references.md index d2034fbff9592f59bbf2c281c79d3da075cda008..ea483c496889564a214e995e17e2b56e4991a557 100644 --- a/docs/references.md +++ b/docs/references.md @@ -4,7 +4,7 @@ * Anaconda (Anaconda Software Distribution, [https://anaconda.com](https://anaconda.com)) 2. **cellranger** - * Cellranger mkfastq [https://support.10xgenomics.com/single-cell-gene-expression/software/pipelines/latest/using/mkfastq](https://support.10xgenomics.com/single-cell-gene-expression/software/pipelines/latest/using/mkfastq) + * Cellranger count [https://support.10xgenomics.com/single-cell-gene-expression/software/pipelines/latest/using/count](https://support.10xgenomics.com/single-cell-gene-expression/software/pipelines/latest/using/count) 3. **MultiQc**: * Ewels P., Magnusson M., Lundin S. and Käller M. 2016. MultiQC: Summarize analysis results for multiple tools and samples in a single report. Bioinformatics 32(19): 3047–3048. doi:[10.1093/bioinformatics/btw354](https://dx.doi.org/10.1093/bioinformatics/btw354) diff --git a/vizapp/functions.R b/vizapp/functions.R new file mode 100644 index 0000000000000000000000000000000000000000..8e30560bfb52c279fa4dc4158880f96ae7e40567 --- /dev/null +++ b/vizapp/functions.R @@ -0,0 +1,98 @@ +LoadData <- function(dim=c("pca","tsne","umap"),dir,samp){ + exp <- readMM(paste0(dir,samp,"/outs/filtered_feature_bc_matrix/matrix.mtx.gz")) + features <- read.table(paste0(dir,samp,"/outs/filtered_feature_bc_matrix/features.tsv.gz"),quote="\t") + barcodes <- read.table(paste0(dir,samp,"/outs/filtered_feature_bc_matrix/barcodes.tsv.gz"),quote="\t") + + exp.raw <- readMM(paste0(dir,samp,"/outs/raw_feature_bc_matrix/matrix.mtx.gz")) + features.raw <- read.table(paste0(dir,samp,"/outs/filtered_feature_bc_matrix/features.tsv.gz"),quote="\t") + barcodes.raw <- read.table(paste0(dir,samp,"/outs/raw_feature_bc_matrix/barcodes.tsv.gz"),quote="\t") + + dr <- list() + for (i in dim){ + if (i=="pca"){ + dr[[i]] <- read.csv(paste0(dir,samp,"/outs/analysis/",i,"/10_components/projection.csv")) + dr[[i]] <- dr[[i]][,1:3] + } else { + dr[[i]] <- read.csv(paste0(dir,samp,"/outs/analysis/",i,"/2_components/projection.csv")) + } + } + rm(i) + + cl <- c("graphclust",paste0("kmeans_",2:10,"_clusters")) + cluster <- list() + deg <- list() + for (i in cl){ + cluster[[i]] <- read.csv(paste0(dir,samp,"/outs/analysis/clustering/",i,"/clusters.csv")) + deg[[i]] <- read.csv(paste0(dir,samp,"/outs/analysis/diffexp/",i,"/differential_expression.csv")) + } + rm(i) + + qc <- read.csv(paste0(dir,samp,"/outs/metrics_summary.csv")) + qc <- data.frame(t(qc)) + qc[,2] <- qc[,1] + qc[,1] <- rownames(qc) + qc <- qc[-1,] + colnames(qc) <- c("Metric","Value") + + results <- list( + sample=samp, + exp=exp, + features=features, + barcodes=barcodes, + exp.raw=exp.raw, + features.raw=features.raw, + barcodes.raw=barcodes.raw, + dr=dr, + cluster=cluster, + deg=deg, + qc=qc + ) + return(results) +} + +Plot.cluster <- function(dr,cluster){ + pl <-merge(dr,cluster,by="Barcode",all.x=TRUE) + axis.labs <- colnames(pl)[2:3] + colnames(pl)[2:3] <- c("dim1","dim2") + plot.out <- ggplot(pl,aes(x=dim1,y=dim2,col=factor(Cluster)))+geom_point()+scale_color_viridis(discrete=TRUE)+xlab(axis.labs[1])+ylab(axis.labs[2])+labs(col="Cluster")+theme_cowplot() + return(plot.out) +} + +Plot.feature <- function(dr,ft){ + dr$exp <- ft + axis.labs <- colnames(dr)[2:3] + colnames(dr)[2:3] <- c("dim1","dim2") + if (sum(dr$exp) != 0){ + plot.out <- ggplot(dr,aes(x=dim1,y=dim2,col=exp))+geom_point()+scale_color_viridis(option="inferno")+xlab(axis.labs[1])+ylab(axis.labs[2])+labs(col="Expression")+theme_cowplot() + } else { + plot.out <- ggplot(dr,aes(x=dim1,y=dim2,col=exp))+geom_point()+scale_color_gradient(low="black",high="black")+xlab(axis.labs[1])+ylab(axis.labs[2])+labs(col="Expression")+theme_cowplot() + } + return(plot.out) +} + +Plot.violinbox <- function(ft,cluster){ + cluster$exp <- ft + cluster$Cluster <- factor(cluster$Cluster) + plot.out <- ggplot(cluster,aes(x=Cluster,y=exp,fill=Cluster))+geom_violin(scale="width",trim=TRUE)+geom_boxplot(width=0.25,fill="white",outlier.shape=NA)+scale_fill_viridis(discrete=TRUE)+ylab("Expression")+theme_cowplot()+theme(axis.text.x=element_text(angle=45)) + + return(plot.out) +} + +Plot.cliffknee <- function(barcodes.raw,exp.raw,barcodes){ + umi <- matrix(nrow=length(barcodes.raw[,1]),ncol=4) + umi[,1] <- t(colSums(exp.raw)) + umi[,2] <- as.character(barcodes.raw[,1]) + umi <- as.data.frame(umi) + umi[,1] <- as.numeric(levels(umi[,1]))[umi[,1]] + colnames(umi) <- c("nUMI","barcodes","rank","Cell") + umi <- umi[order(umi$nUMI,decreasing=TRUE),] + umi$rank <- 1:nrow(umi) + umi$Cell <- factor(as.character(umi$barcodes %in% barcodes[,1])) + umi$Cell <- factor(umi$Cell,levels(umi$Cell)[c(2,1)]) + plot.out <- ggplot(umi,aes(x=rank,y=nUMI,col=Cell))+geom_point()+scale_color_manual(values=c("darkgreen","darkred"))+ + scale_x_log10(breaks=trans_breaks("log10",function(x) 10^x),labels=trans_format("log10",math_format(10^.x)))+ + scale_y_log10(breaks=trans_breaks("log10",function(x) 10^x),labels=trans_format("log10",math_format(10^.x)))+ + annotation_logticks()+xlab("Barcode Rank")+ylab("nUMI")+theme_cowplot() + + return(plot.out) +} diff --git a/vizapp/global.R b/vizapp/global.R new file mode 100644 index 0000000000000000000000000000000000000000..988fc942d71c2db605dec0e86e2d8504ae2b06f7 --- /dev/null +++ b/vizapp/global.R @@ -0,0 +1,16 @@ +library(shiny) +library(shinythemes) +library(Matrix) +library(ggplot2) +library(RColorBrewer) +library(viridis) +library(cowplot) +library(scales) + +setwd("../") +source("./vizapp/functions.R") + +#load data +dir.shared <- "/work/BICF/s189701/cellranger_count/workflow/output/count310/" +samples <- list.dirs(dir.shared,full.names=FALSE,recursive=FALSE) +results <- LoadData(dim=c("umap","tsne","pca"),dir=dir.shared,samp=samples[1]) diff --git a/vizapp/server.R b/vizapp/server.R index 81017c8445db8d640af1798cc8160bdffe2ec789..595710378f2ad30ed97394052d217f11e424f2e9 100644 --- a/vizapp/server.R +++ b/vizapp/server.R @@ -1,20 +1,365 @@ -# This example implements a simple file browser for accessing results. - library(shiny) -library(shinyFiles) - -# Results are available in the directory specified by the outputDir environment -# variable, red by Sys.getenv - -rootdir <- Sys.getenv('outputDir') - - -shinyServer(function(input, output, session) { - - # The backend for a simple file chooser, restricted to the - # rootdir we obtained above. - # See https://github.com/thomasp85/shinyFiles - - shinyFileChoose(input, 'files', roots=c('workflow'=rootdir), filetypes=c('', 'bed', 'xls','wig'), session=session) +library(shinythemes) +library(Matrix) +library(ggplot2) +library(RColorBrewer) +library(viridis) +library(cowplot) +library(scales) +shinyServer(function(input,output,session){ + #reactive inputs + values <- reactiveValues( + results=results, + dr.c="",cluster.c="", + dr.f="",feature.f="", + cluster.vb="",feature.vb="", + cluster.deg="",cluster.1.deg="",alpha.deg="",fc.deg="",direction.deg="" + ) + values$results <- eventReactive(input$go.d,{ + LoadData(dim=c("umap","tsne","pca"),dir=dir.shared,samp=input$sample) + }) + output$loaded <- eventReactive(input$go.d,{ + paste0("Sample ",values$results()$sample) + }) + output$nav.analysis <- renderUI({ + req(values$results()$sample) + tabsetPanel(type="tabs", + tabPanel("Cluster Plot", + sidebarPanel( + h3(textOutput("lab.sample.c")), + uiOutput("dr.c"), + uiOutput("cluster.c"), + actionButton("go.c","Submit") + ), + mainPanel( + h3(textOutput("lab.dr.c")), + h4(textOutput("lab.cluster.c")), + plotOutput("plot.cluster.c"), + tags$br(), + uiOutput("button.download.c") + ) + ), + tabPanel("Feature Plot", + sidebarPanel( + h3(textOutput("lab.sample.f")), + uiOutput("dr.f"), + uiOutput("feature.f"), + actionButton("go.f","Submit") + ), + mainPanel( + h3(textOutput("lab.feature.f")), + h4(textOutput("lab.dr.f")), + plotOutput("plot.feature"), + tags$br(), + uiOutput("button.download.f") + ) + ), + tabPanel("ViolinBox Plot", + sidebarPanel( + h3(textOutput("lab.sample.vb")), + uiOutput("cluster.vb"), + uiOutput("feature.vb"), + actionButton("go.vb","Submit"), + br(), + br(), + plotOutput("plot.cluster.vb") + ), + mainPanel( + h3(textOutput("lab.feature.vb")), + h4(textOutput("lab.cluster.vb")), + plotOutput("plot.violinbox"), + tags$br(), + uiOutput("button.download.vb"), + tags$br(), + tags$br(), + tableOutput("table.expression.vb") + ) + ), + tabPanel("Differentially Expressed Features", + sidebarPanel( + h3(textOutput("lab.sample.deg")), + uiOutput("cluster.deg"), + uiOutput("cluster.1.deg"), + numericInput("alpha.deg","Maximum p-value",min=0,max =1,value=0.05,step=0.001), + numericInput("fc.deg","Minimum Fold Change",min=0,max =50,value=0,step=0.5), + radioButtons("direction.deg","Fold Change Direction",c("Positively Expressed"="up","Negatively Expressed"="down","Both"="both"),selected="up"), + actionButton("go.deg","Submit"), + br(), + br(), + plotOutput("plot.cluster.deg") + ), + mainPanel( + h3(textOutput("lab.cluster.1.deg")), + h4(textOutput("lab.cluster.deg")), + h5(textOutput("lab.alpha.deg")), + h5(textOutput("lab.fc.deg")), + uiOutput("download.deg.button"), + tags$br(), + tags$br(), + tableOutput("table.deg") + ) + ) + ) + }) + output$nav.qc <- renderUI({ + req(values$results()$sample) + tabPanel("Output", + sidebarPanel( + h3(textOutput("lab.sample.qc")), + h4(textOutput("lab.cell.count")), + br(), + tableOutput("qc") + ), + mainPanel( + plotOutput("plot.cliffknee") + ) + ) + }) + + #sidebar input/outputs + output$lab.sample.c <- reactive({paste0("Sample ",values$results()$sample)}) + output$dr.c <- renderUI({selectInput("dr.c","Dimentionality Reduction",names(values$results()$dr))}) + output$cluster.c <- renderUI({selectInput("cluster.c","Clustering",names(values$results()$cluster))}) + output$lab.sample.f <- reactive({paste0("Sample ",values$results()$sample)}) + output$dr.f <- renderUI({selectInput("dr.f","Dimentionality Reduction",names(values$results()$dr))}) + output$feature.f <- renderUI({textInput("feature.f","Feature",levels(values$results()$features[,2])[1])}) + output$lab.sample.vb <- reactive({paste0("Sample ",values$results()$sample)}) + output$cluster.vb <- renderUI({selectInput("cluster.vb","Clustering",names(values$results()$cluster))}) + output$feature.vb <- renderUI({textInput("feature.vb","Feature",levels(values$results()$features[,2])[1])}) + output$plot.cluster.vb <- renderPlot({ + req(input$go.vb) + print(plot.cluster.vb()) + }) + output$lab.sample.deg <- reactive({paste0("Sample ",values$results()$sample)}) + output$cluster.deg <- renderUI({selectInput("cluster.deg","Clustering",names(values$results()$cluster))}) + output$cluster.1.deg <- renderUI({ + clust <- levels(factor(values$results()$cluster[[req(input$cluster.deg)]]$Cluster)) + selectInput("cluster.1.deg", "Specific Cluster",clust,clust[1]) + }) + observe({ + if (!is.numeric(input$alpha.deg)) { + updateNumericInput(session,"alpha","Maximum p-value",min=0,max =1,value=0.05,step=0.001) + } + }) + observe({ + if (!is.numeric(input$fc.deg)) { + updateNumericInput(session,"fc","Minimum Fold Change",min=0,max =50,value=0,step=0.5) + } + }) + output$lab.sample.qc <- reactive({paste0("Sample ",values$results()$sample)}) + output$lab.cell.count <- renderText({paste0(nrow(values$results()$barcodes)," Cells Detected")}) + output$qc <- renderTable(values$results()$qc) + + #main input/outputs + output$lab.dr.c <- eventReactive(input$go.c,{ + req(input$go.c) + paste0(toupper(req(input$dr.c))," Reduction") + },ignoreNULL=FALSE) + output$lab.cluster.c <- eventReactive(input$go.c,{ + req(input$go.c) + paste0(toupper(req(input$cluster.c))," Clustering") + },ignoreNULL=FALSE) + output$plot.cluster.c <- renderPlot({ + req(input$go.c) + print(plot.cluster.c()) + }) + output$lab.feature.f <- eventReactive(input$go.f,{ + req(input$go.f) + if(toupper(req(input$feature.f)) %in% as.character(values$results()$features[,2])){ + toupper(req(input$feature.f)) + } else { + paste0(req(input$feature.f)," NOT PRESENT") + } + },ignoreNULL=FALSE) + output$lab.dr.f <- eventReactive(input$go.f,{ + req(input$go.f) + paste0(toupper(req(input$dr.f))," Reduction") + },ignoreNULL=FALSE) + output$plot.feature <- renderPlot({ + req(input$go.f) + print(plot.feature()) + }) + output$lab.feature.vb <- eventReactive(input$go.vb,{ + req(input$go.vb) + if(toupper(req(input$feature.vb)) %in% as.character(values$results()$features[,2])){ + toupper(req(input$feature.vb)) + } else { + paste0(req(input$feature.vb)," NOT PRESENT") + } + },ignoreNULL=FALSE) + output$lab.cluster.vb <- eventReactive(input$go.vb,{ + req(input$go.vb) + paste0(toupper(req(input$cluster.vb))," Clustering") + },ignoreNULL=FALSE) + output$plot.violinbox <- renderPlot({ + req(input$go.vb) + print(plot.violinbox()) + }) + output$table.expression.vb <- renderTable({ + req(input$go.vb) + table.expression.vb() + }) + output$lab.cluster.1.deg <- eventReactive(input$go.deg,{ + req(input$go.deg) + paste0("Cluster ",req(input$cluster.1.deg)," DEGs") + },ignoreNULL=FALSE) + output$lab.cluster.deg <- eventReactive(input$go.deg,{ + req(input$go.deg) + paste0(toupper(req(input$cluster.deg))," Clustering") + },ignoreNULL=FALSE) + output$lab.alpha.deg <- eventReactive(input$go.deg,{ + req(input$go.deg) + paste0("Maximum p-value <- ",req(input$alpha.deg)) + },ignoreNULL=FALSE) + output$lab.fc.deg <- eventReactive(input$go.deg,{ + req(input$go.deg) + if (req(input$direction.deg) == "up"){ + paste0("Minimum fold-change difference <- ",req(input$fc.deg)," above the other cells") + } else if (req(input$direction.deg) == "down") { + paste0("Minimum fold-change difference <- ",req(input$fc.deg)," below the other cells") + } else { + paste0("Minimum fold-change difference <- ",req(input$fc.deg)," above & below the other cells") + } + },ignoreNULL=FALSE) + output$table.deg <- renderTable({ + req(input$go.deg) + table.deg() + }) + output$plot.cluster.deg <- renderPlot({ + req(input$go.deg) + print(plot.cluster.deg()) + }) + output$download.deg.button <- renderUI({ + req(input$go.deg) + downloadButton("download.deg","Download Table") + }) + output$plot.cliffknee <- renderPlot({print(Plot.cliffknee(barcodes.raw=values$results()$barcodes.raw,exp.raw=values$results()$exp.raw,barcodes=values$results()$barcodes))}) + + #reactive download buttons + output$button.download.c <- renderUI({ + req(input$go.c) + downloadButton("download.c","Download Figure") + }) + output$button.download.f <- renderUI({ + req(input$go.f) + downloadButton("download.f","Download Figure") + }) + output$button.download.vb <- renderUI({ + req(input$go.vb) + downloadButton("download.vb","Download Figure") + }) + output$button.download.deg <- renderUI({ + req(input$go.deg) + downloadButton("download.deg","Download Table") + }) + + #save current parameters + values$dr.c <- eventReactive(input$go.c,{input$dr.c}) + values$cluster.c <- eventReactive(input$go.c,{input$cluster.c}) + values$dr.f <- eventReactive(input$go.f,{input$dr.f}) + values$feature.f <- eventReactive(input$go.f,{toupper(input$feature.f)}) + values$cluster.vb <- eventReactive(input$go.vb,{input$cluster.vb}) + values$feature.vb <- eventReactive(input$go.vb,{toupper(input$feature.vb)}) + values$cluster.deg <- eventReactive(input$go.deg,{input$cluster.deg}) + values$cluster.1.deg <- eventReactive(input$go.deg,{input$cluster.1.deg}) + values$alpha.deg <- eventReactive(input$go.deg,{input$alpha.deg}) + values$fc.deg <- eventReactive(input$go.deg,{input$fc.deg}) + values$direction.deg <- eventReactive(input$go.deg,{input$direction.deg}) + + #plot functions + plot.cluster.c <- eventReactive(input$go.c,{ + Plot.cluster( + values$results()$dr[[req(input$dr.c)]],values$results()$cluster[[req(input$cluster.c)]]) + },ignoreNULL=FALSE) + plot.feature <- eventReactive(input$go.f,{ + if(toupper(req(input$feature.f)) %in% as.character(values$results()$features[,2])){ + Plot.feature(values$results()$dr[[req(input$dr.f)]],values$results()$exp[as.numeric(rownames(values$results()$features[values$results()$features[,2]==toupper(req(input$feature.f)),])),]) + } else { + plot.new() + } + },ignoreNULL=FALSE) + plot.violinbox <- eventReactive(input$go.vb,{ + if(toupper(req(input$feature.vb)) %in% as.character(values$results()$features[,2])){ + Plot.violinbox(values$results()$exp[as.numeric(rownames(values$results()$features[values$results()$features[,2]==toupper(req(input$feature.vb)),])),],values$results()$cluster[[req(input$cluster.vb)]]) + } else { + plot.new() + } + },ignoreNULL=FALSE) + plot.cluster.vb <- eventReactive(input$go.vb,{ + Plot.cluster( + values$results()$dr[["umap"]],values$results()$cluster[[req(input$cluster.vb)]]) + },ignoreNULL=FALSE) + plot.cluster.deg <- eventReactive(input$go.deg,{ + req(input$cluster.1.deg) + Plot.cluster( + values$results()$dr[["umap"]],values$results()$cluster[[input$cluster.deg]]) + },ignoreNULL=FALSE) + + #table functions + table.expression.vb <- eventReactive(input$go.vb,{ + if(toupper(req(input$feature.vb)) %in% as.character(values$results()$features[,2])){ + tab <- values$results()$deg[[req(input$cluster.vb)]][values$results()$deg[[req(input$cluster.vb)]][,2]==toupper(req(input$feature.vb)),c(2,grep("Mean.Counts",names(values$results()$deg[[req(input$cluster.vb)]])))] + colnames(tab) <- c("Feature",gsub(".Mean.Counts","",names(tab[,-1]))) + tab <- data.frame(t(tab)) + tab[,2] <- tab[,1] + tab[,1] <- rownames(tab) + tab <- tab[-1,] + colnames(tab) <- c("Cluster",paste0("Ave ",req(input$feature.vb)," Expression")) + tab + } else { + "" + } + },ignoreNULL=FALSE) + table.deg <- eventReactive(input$go.deg,{ + tab <- values$results()$deg[[input$cluster.deg]] + tab <- tab[tab[paste0("Cluster.",req(input$cluster.1.deg),".Adjusted.p.value")]<=input$alpha.deg,] + if (input$fc.deg == 0){ + fc <- 0 + } else { + fc <- log2(input$fc.deg) + } + if (input$direction.deg=="up"){ + tab <- tab[tab[paste0("Cluster.",req(input$cluster.1.deg),".Log2.fold.change")]>=fc,] + } else if (input$direction.deg=="down"){ + tab <- tab[tab[paste0("Cluster.",req(input$cluster.1.deg),".Log2.fold.change")]<=-fc,] + } else { + tab <- tab[tab[paste0("Cluster.",req(input$cluster.1.deg),".Log2.fold.change")]>=fc | tab[paste0("Cluster.",req(input$cluster.1.deg),".Log2.fold.change")]<=-fc,] + } + tab <- tab[,c(colnames(values$results()$deg[[input$cluster.deg]])[2],paste0("Cluster.",req(input$cluster.1.deg),".Mean.Counts"),paste0("Cluster.",req(input$cluster.1.deg),".Log2.fold.change"),paste0("Cluster.",req(input$cluster.1.deg),".Adjusted.p.value"))] + tab <- tab[order(abs(tab[paste0("Cluster.",req(input$cluster.1.deg),".Log2.fold.change")]),decreasing=TRUE),] + tab + },ignoreNULL=FALSE) + + #download + output$download.c <- downloadHandler( + filename <- function(){paste0("clusters_",values$dr.c(),"_",values$cluster.c(),".pdf")}, + content <- function(file){ + pdf(file,onefile=FALSE) + print(plot.cluster.c()) + dev.off() + } + ) + output$download.f <- downloadHandler( + filename <- function(){paste0("feature_",values$dr.f(),"_",toupper(values$feature.f()),".pdf")}, + content <- function(file){ + pdf(file,onefile=FALSE) + print(plot.feature()) + dev.off() + } + ) + output$download.vb <- downloadHandler( + filename <- function(){paste0("violinbox_",values$cluster.vb(),"_",toupper(values$feature.vb()),".pdf")}, + content <- function(file){ + pdf(file,onefile=FALSE) + print(plot.violinbox()) + dev.off() + } + ) + output$download.deg <- downloadHandler( + filename <- function(){paste0("deg_",values$cluster.deg(),"_cluster.",values$cluster.1.deg(),"_p",values$alpha.deg(),"_fc",values$fc.deg(),values$direction.deg(),".csv")}, + content <- function(file){ + write.csv(table.deg(),file,row.names=FALSE,quote=FALSE) + } + ) }) diff --git a/vizapp/ui.R b/vizapp/ui.R index 79f4cc99131a5d5dcb3d0e4694650db178ed8c5c..e1a6a90180d0d05ba63922ff567ba566efe53b8e 100644 --- a/vizapp/ui.R +++ b/vizapp/ui.R @@ -1,30 +1,18 @@ -library(shiny) -library(shinyFiles) - - -shinyUI(fluidPage( - - verticalLayout( - - # Application title - titlePanel("Astrocyte Example"), - - wellPanel( - - helpText("This is a minimal example, demonstrating how - a Shiny visualization application can access the output of a workflow. - Here we provide a file browser using the shinyFiles package. Real - Astrocyte vizapps would provide custom methods to access and visualize - output."), - - helpText("The workflow output is in the directory set in the - outputDir environment variable. this can be retrieved in R with the - command Sys.getenv('outputDir')"), - - # A simple file browser within the workflow output directory - # See https://github.com/thomasp85/shinyFiles - shinyFilesButton('files', label='Browse workflow output', title='Please select a file', multiple=FALSE) - +navbarPage(theme=shinytheme("slate"),"BICF Cellranger Count Analysis (cellranger 3.1.0 version)", + tabPanel("Select Data", + mainPanel( + selectInput("sample","Available Samples",samples), + actionButton("go.d","Load"), + br(), + br(), + h4("Please whait until the sample has been loaded and a message below displays this, it may take a few minutes"), + h3(textOutput("loaded")) ) + ), + tabPanel("Analysis", + uiOutput("nav.analysis") + ), + tabPanel("QC", + uiOutput("nav.qc") ) -)) +) diff --git a/workflow/conf/biohpc.config b/workflow/conf/biohpc.config index 6e356466fb53801aa9c00876f55bfc6903798c50..a5ea037bbdc5558ff20dec18c238ffa4e3f4ed44 100755 --- a/workflow/conf/biohpc.config +++ b/workflow/conf/biohpc.config @@ -18,6 +18,10 @@ process { module = ['cellranger/3.0.2'] queue = '128GB,256GB,256GBv1,384GB' } + withLabel: count310 { + module = ['cellranger/3.1.0'] + queue = '128GB,256GB,256GBv1,384GB' + } withLabel: versions { module = ['python/3.6.1-2-anaconda','pandoc/2.7','multiqc/1.7'] executor = 'local' @@ -49,6 +53,9 @@ params { 'mm10-1.2.0' { loc = '/project/apps_database/cellranger/refdata-cellranger-' } + 'GRCh38_and_mm10-3.1.0' { + loc = '/project/apps_database/cellranger/refdata-cellranger-' + } 'hg19_and_mm10-3.0.0' { loc = '/project/apps_database/cellranger/refdata-cellranger-' } diff --git a/workflow/main.nf b/workflow/main.nf index e0e2f551111de61d27d892fa8ab0883c84ec4b4b..8862991d57eec85dae8d55ecc7ac7001a187e671 100755 --- a/workflow/main.nf +++ b/workflow/main.nf @@ -1,7 +1,12 @@ #!/usr/bin/env nextflow - -// Path to an input file, or a pattern for multiple inputs -// Note - $baseDir is the location of this workflow file main.nf +/* +main.nf +* +* -------------------------------------------------------------------------- +* Licensed under MIT (https://git.biohpc.swmed.edu/BICF/Astrocyte/cellranger_count/blob/develop/LICENSE) +* -------------------------------------------------------------------------- +* +*/ // Define Input variables params.name = "run" @@ -11,7 +16,7 @@ params.genome = 'GRCh38-3.0.0' params.expectCells = 10000 params.forceCells = 0 params.kitVersion = 'three' -params.version = '3.0.2' +params.version = '3.1.0' params.astrocyte = false params.outDir = "${baseDir}/output" params.multiqcConf = "${baseDir}/conf/multiqc_config.yaml" @@ -64,6 +69,7 @@ outDir = params.outDir multiqcConf = params.multiqcConf references = params.references + process checkDesignFile { tag "${name}" @@ -100,20 +106,25 @@ samples.into { samples211 samples301 samples302 + samples310 } refLocation.into { refLocation211 refLocation301 refLocation302 + refLocation310 } expectCells211 = expectCells expectCells301 = expectCells expectCells302 = expectCells +expectCells310 = expectCells forceCells211 = forceCells forceCells301 = forceCells forceCells302 = forceCells +forceCells310 = forceCells chemistryParam301 = chemistryParam chemistryParam302 = chemistryParam +chemistryParam310 = chemistryParam process count211 { @@ -143,7 +154,7 @@ process count211 { ulimit -a bash ${baseDir}/scripts/filename_check.sh -r ${ref} cellranger count --id=${sample} --transcriptome=./${ref} --fastqs=. --sample=${sample} --expect-cells=${expectCells211} - sed -E 's/("([^"]*)")?,/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv + sed -E 's/("([^"]*)")?(,|\$)/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv """ } else { @@ -152,7 +163,7 @@ process count211 { ulimit -a bash ${baseDir}/scripts/filename_check.sh -r ${ref} cellranger count --id=${sample} --transcriptome=./${ref} --fastqs=. --sample=${sample} --force-cells=${forceCells211} - sed -E 's/("([^"]*)")?,/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv + sed -E 's/("([^"]*)")?(,|\$)/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv """ } @@ -187,7 +198,7 @@ process count301 { ulimit -a bash ${baseDir}/scripts/filename_check.sh -r ${ref} cellranger count --id=${sample} --transcriptome=./${ref} --fastqs=. --sample=${sample} --expect-cells=${expectCells301} --chemistry=${chemistryParam301} - sed -E 's/("([^"]*)")?,/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv + sed -E 's/("([^"]*)")?(,|\$)/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv """ } else { @@ -196,7 +207,7 @@ process count301 { ulimit -a bash ${baseDir}/scripts/filename_check.sh -r ${ref} cellranger count --id=${sample} --transcriptome=./${ref} --fastqs=. --sample=${sample} --force-cells=${forceCells301} --chemistry=${chemistryParam301} - sed -E 's/("([^"]*)")?,/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv + sed -E 's/("([^"]*)")?(,|\$)/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv """ } @@ -231,7 +242,7 @@ process count302 { ulimit -a bash ${baseDir}/scripts/filename_check.sh -r ${ref} cellranger count --id=${sample} --transcriptome=./${ref} --fastqs=. --sample=${sample} --expect-cells=${expectCells302} --chemistry=${chemistryParam302} - sed -E 's/("([^"]*)")?,/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv + sed -E 's/("([^"]*)")?(,|\$)/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv """ } else { @@ -240,7 +251,51 @@ process count302 { ulimit -a bash ${baseDir}/scripts/filename_check.sh -r ${ref} cellranger count --id=${sample} --transcriptome=./${ref} --fastqs=. --sample=${sample} --force-cells=${forceCells302} --chemistry=${chemistryParam302} - sed -E 's/("([^"]*)")?,/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv + sed -E 's/("([^"]*)")?(,|\$)/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv + """ + } + +} + + +process count310 { + + queue '128GB,256GB,256GBv1,384GB' + tag "${sample}" + publishDir "${outDir}/${task.process}", mode: 'copy' + module 'cellranger/3.1.0' + + input: + set sample, file("${sample}_S?_L001_R1_001.fastq.gz"), file("${sample}_S?_L001_R2_001.fastq.gz") from samples310 + file ref from refLocation310.first() + expectCells310 + forceCells310 + chemistryParam310 + + output: + file("**/outs/**") into outPaths310 + file("*_metrics_summary.tsv") into metricsSummary310 + + when: + version == '3.1.0' + + script: + if (forceCells310 == 0) { + """ + hostname + ulimit -a + bash ${baseDir}/scripts/filename_check.sh -r ${ref} + cellranger count --id=${sample} --transcriptome=./${ref} --fastqs=. --sample=${sample} --expect-cells=${expectCells310} --chemistry=${chemistryParam310} + sed -E 's/("([^"]*)")?(,|\$)/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv + """ + } + else { + """ + hostname + ulimit -a + bash ${baseDir}/scripts/filename_check.sh -r ${ref} + cellranger count --id=${sample} --transcriptome=./${ref} --fastqs=. --sample=${sample} --force-cells=${forceCells310} --chemistry=${chemistryParam310} + sed -E 's/("([^"]*)")?(,|\$)/\\2\t/g' ${sample}/outs/metrics_summary.csv | tr -d "," | sed "s/^/${sample}\t/" > ${sample}_metrics_summary.tsv """ } @@ -272,10 +327,9 @@ process versions { } -metricsSummary = metricsSummary211.mix(metricsSummary301, metricsSummary302) +metricsSummary = metricsSummary211.mix(metricsSummary301, metricsSummary302, metricsSummary310) -// Generate MultiQC Report process multiqc { tag "${name}" @@ -299,4 +353,4 @@ process multiqc { multiqc -c ${multiqcConf} . """ -} +} \ No newline at end of file diff --git a/workflow/scripts/check_design.py b/workflow/scripts/check_design.py index a648a4e20d4a79b52cad60d6415bed14cf39fda9..c5c679e58b2819e6fafb4f34e6181cdd62f8cdbd 100755 --- a/workflow/scripts/check_design.py +++ b/workflow/scripts/check_design.py @@ -1,6 +1,10 @@ #!/usr/bin/env python3 - -'''Check if design file is correctly formatted and matches files list.''' +#check_design.py +#* +#* -------------------------------------------------------------------------- +#* Licensed under MIT (https://git.biohpc.swmed.edu/BICF/Astrocyte/cellranger_count/blob/develop/LICENSE) +#* -------------------------------------------------------------------------- +#* import argparse import logging @@ -11,8 +15,6 @@ For more details: %(prog)s --help ''' -# SETTINGS - logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) logger.propagate = False @@ -61,6 +63,7 @@ def check_design_headers(design): return design + def check_files(design, fastq): '''Check if design file has the files found.''' @@ -104,4 +107,4 @@ def main(): new_design_df.to_csv('design.checked.csv', header=True, sep=',', index=False) if __name__ == '__main__': - main() + main() \ No newline at end of file diff --git a/workflow/scripts/filename_check.sh b/workflow/scripts/filename_check.sh index 78fa08ed25b54c1e3f921819a1b485525c772abf..333bb7ad2b0a3dce27675d3ea09e9c585aa42eff 100644 --- a/workflow/scripts/filename_check.sh +++ b/workflow/scripts/filename_check.sh @@ -1,5 +1,10 @@ #!/bin/bash #filename_check.sh +#* +#* -------------------------------------------------------------------------- +#* Licensed under MIT (https://git.biohpc.swmed.edu/BICF/Astrocyte/cellranger_count/blob/develop/LICENSE) +#* -------------------------------------------------------------------------- +#* usage() { echo "-r --ref file" @@ -28,4 +33,4 @@ if [ $(echo "${ref}" | tr -d ' ') != "${ref}" ]; then echo "Error: Spaces found in Reference Files" echo ${ref} exit 21 -fi +fi \ No newline at end of file diff --git a/workflow/scripts/generate_references.py b/workflow/scripts/generate_references.py index c40cc7efa689e8b4d8fcd52908ffe7a8112d3e8c..e614db7b3c22c1ea139f2cfac1f25d4780041df6 100755 --- a/workflow/scripts/generate_references.py +++ b/workflow/scripts/generate_references.py @@ -1,6 +1,10 @@ #!/usr/bin/env python3 - -'''Make header for HTML of references.''' +#generate_references.py +#* +#* -------------------------------------------------------------------------- +#* Licensed under MIT (https://git.biohpc.swmed.edu/BICF/Astrocyte/cellranger_count/blob/develop/LICENSE) +#* -------------------------------------------------------------------------- +#* import argparse import subprocess @@ -12,8 +16,6 @@ For more details: %(prog)s --help ''' -# SETTINGS - logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) logger.propagate = False @@ -65,4 +67,4 @@ def main(): if __name__ == '__main__': - main() + main() \ No newline at end of file diff --git a/workflow/scripts/generate_versions.py b/workflow/scripts/generate_versions.py index 242c971b4ca8769e13c9dfb16d4be092bc8ea86b..ddcda535f6bf1f8350f5aa148af517f2c421c272 100755 --- a/workflow/scripts/generate_versions.py +++ b/workflow/scripts/generate_versions.py @@ -1,7 +1,10 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -'''Make YAML of software versions.''' +#generate_versions.py +#* +#* -------------------------------------------------------------------------- +#* Licensed under MIT (https://git.biohpc.swmed.edu/BICF/Astrocyte/cellranger_count/blob/develop/LICENSE) +#* -------------------------------------------------------------------------- +#* from __future__ import print_function from collections import OrderedDict @@ -15,7 +18,6 @@ For more details: %(prog)s --help ''' -# SETTINGS logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) logger.propagate = False @@ -104,4 +106,4 @@ def main(): if __name__ == '__main__': - main() + main() \ No newline at end of file diff --git a/workflow/tests/test_check_design.py b/workflow/tests/test_check_design.py index 28968b0dbf1ab4bca46df91ec1d7e23812b47e9d..f425d09ab3a19ba1e610f451435a657f55d954ae 100644 --- a/workflow/tests/test_check_design.py +++ b/workflow/tests/test_check_design.py @@ -1,4 +1,10 @@ #!/usr/bin/env python3 +#test_check_design.py +#* +#* -------------------------------------------------------------------------- +#* Licensed under MIT (https://git.biohpc.swmed.edu/BICF/Astrocyte/cellranger_count/blob/develop/LICENSE) +#* -------------------------------------------------------------------------- +#* import pytest import pandas as pd @@ -19,3 +25,7 @@ def test_count301_design(): @pytest.mark.count302 def test_count302_design(): assert os.path.exists(os.path.join(test_output_path, 'design.checked.csv')) + +@pytest.mark.count310 +def test_count310_design(): + assert os.path.exists(os.path.join(test_output_path, 'design.checked.csv')) \ No newline at end of file diff --git a/workflow/tests/test_count.py b/workflow/tests/test_count.py index b1bafe439b74fbe84e88f891e28e7880d653b1c3..86623ca6057dd298ae0294caa1b6ce91d32296ad 100644 --- a/workflow/tests/test_count.py +++ b/workflow/tests/test_count.py @@ -1,4 +1,10 @@ #!/usr/bin/env python3 +#test_count.py +#* +#* -------------------------------------------------------------------------- +#* Licensed under MIT (https://git.biohpc.swmed.edu/BICF/Astrocyte/cellranger_count/blob/develop/LICENSE) +#* -------------------------------------------------------------------------- +#* import pytest import pandas as pd @@ -23,3 +29,8 @@ def test_count301_count(): def test_count302_count(): assert os.path.exists(os.path.join(test_output_path, 'count302', 'sample1_metrics_summary.tsv')) assert os.path.exists(os.path.join(test_output_path, 'count302', 'sample1', 'outs')) + +@pytest.mark.count310 +def test_count310_count(): + assert os.path.exists(os.path.join(test_output_path, 'count310', 'sample1_metrics_summary.tsv')) + assert os.path.exists(os.path.join(test_output_path, 'count310', 'sample1', 'outs')) \ No newline at end of file diff --git a/workflow/tests/test_multiqc.py b/workflow/tests/test_multiqc.py index d625e4088219cc3f875d1e55e7d17d3153e017e7..7ca8d237484434e83052e1b38b7b232cb59b2740 100644 --- a/workflow/tests/test_multiqc.py +++ b/workflow/tests/test_multiqc.py @@ -1,4 +1,10 @@ #!/usr/bin/env python3 +#test_multiqc.py +#* +#* -------------------------------------------------------------------------- +#* Licensed under MIT (https://git.biohpc.swmed.edu/BICF/Astrocyte/cellranger_count/blob/develop/LICENSE) +#* -------------------------------------------------------------------------- +#* import pytest import pandas as pd @@ -19,3 +25,7 @@ def test_count301_multiqc(): @pytest.mark.count302 def test_count302_multiqc(): assert os.path.exists(os.path.join(test_output_path, 'multiqc_report.html')) + +@pytest.mark.count310 +def test_count310_multiqc(): + assert os.path.exists(os.path.join(test_output_path, 'multiqc_report.html')) \ No newline at end of file diff --git a/workflow/tests/test_versions.py b/workflow/tests/test_versions.py index 07a233c459c087051441780f1d0a42d00f6c6d65..535e029ffc5f9a1d0eadc63b286397c81a2427c0 100644 --- a/workflow/tests/test_versions.py +++ b/workflow/tests/test_versions.py @@ -1,4 +1,10 @@ #!/usr/bin/env python3 +#test_versions.py +#* +#* -------------------------------------------------------------------------- +#* Licensed under MIT (https://git.biohpc.swmed.edu/BICF/Astrocyte/cellranger_count/blob/develop/LICENSE) +#* -------------------------------------------------------------------------- +#* import pytest import pandas as pd @@ -22,3 +28,8 @@ def test_count301_versions(): def test_count302_versions(): assert os.path.exists(os.path.join(test_output_path, 'versions_mqc.yaml')) assert os.path.exists(os.path.join(test_output_path, 'references_mqc.yaml')) + +@pytest.mark.count310 +def test_count310_versions(): + assert os.path.exists(os.path.join(test_output_path, 'versions_mqc.yaml')) + assert os.path.exists(os.path.join(test_output_path, 'references_mqc.yaml')) \ No newline at end of file