diff --git a/CHANGELOG.md b/CHANGELOG.md index 756b9f8..bd03efe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [unreleased] +- Sample sheet must include a `control` type to indicate which samples are the reference for the differential expression pipeline. + ## [v0.4.1] ### Changed - Updated docker container with Pychopper to support LSK114. diff --git a/README.md b/README.md index de23b17..7d86e80 100644 --- a/README.md +++ b/README.md @@ -190,16 +190,16 @@ Differential Expression requires at least 2 replicates of each sample to compare The sample sheet should be a comma separated values file (.csv) and include at least three columns named `barcode`, `alias` and `condition`. - Each `barcode` should refer to a directory of the same name in the input FASTQ directory (in the example below `barcode01` to `barcode06` reflect the `test_data` directory). - The `alias` column allows you to rename each barcode to an alias that will be used in the report and other output files. -- The condition column will need to contain one of two keys to indicate the two samples being compared. for example: treated/untreated, sample/control etc. +- The condition column will need to contain one of two keys to indicate the two samples being compared. Control must be one of the keys, used to indicate which samples will be used as the reference in the differential expression analysis. In the default `sample_sheet.csv` available in the test_data directory we have used the following. eg. sample_sheet.csv ``` barcode,alias,condition -barcode01,sample01,untreated -barcode02,sample02,untreated -barcode03,sample03,untreated +barcode01,sample01,control +barcode02,sample02,control +barcode03,sample03,control barcode04,sample04,treated barcode05,sample05,treated barcode06,sample06,treated diff --git a/bin/de_analysis.R b/bin/de_analysis.R index f60dcc8..1538930 100755 --- a/bin/de_analysis.R +++ b/bin/de_analysis.R @@ -19,7 +19,11 @@ cts <- as.matrix(read.csv("merged/all_counts.tsv", sep="\t", row.names="Referenc coldata <- read.csv("de_analysis/coldata.tsv", row.names="alias", sep=",", stringsAsFactors=TRUE) coldata$sample_id <- rownames(coldata) -coldata$condition <- factor(coldata$condition, levels=rev(levels(coldata$condition))) +# check if control condition exists, sets as reference +if(!"control" %in% coldata$condition) + stop("sample_sheet.csv does not contain 'control' + condition - unable to set reference.") +coldata$condition <- relevel(coldata$condition, ref = "control") cat("Loading annotation database.\n") diff --git a/bin/workflow_glue/check_sample_sheet_condition.py b/bin/workflow_glue/check_sample_sheet_condition.py index b02617e..afe0ae4 100755 --- a/bin/workflow_glue/check_sample_sheet_condition.py +++ b/bin/workflow_glue/check_sample_sheet_condition.py @@ -1,5 +1,6 @@ #!/usr/bin/env python """Check if a sample sheet is valid.""" +from collections import Counter import csv import sys @@ -11,30 +12,27 @@ def main(args): logger = get_named_logger("checkSheetCondition") with open(args.sample_sheet, "r") as f: csv_reader = csv.DictReader(f) - unique_controls = [] - controls_dic = {} + conditions_count = Counter() for row in csv_reader: - if 'condition' in list(row.keys()): - unique_controls.append(row['condition']) - if row['condition'] not in controls_dic: - controls_dic[row['condition']] = 1 - else: - controls_dic[row['condition']] += 1 + if "condition" in row: + conditions_count[row['condition']] += 1 else: sys.exit( "Sample sheet has no condition column " "which is required for the " "differential expression subworkflow.") - if len(list(set(controls_dic.keys()))) != 2: + if len(conditions_count.keys()) != 2: sys.exit( "There must be only two unique conditions " "in the condition column of the sample sheet.") - for val in list(controls_dic.values()): - if val < 2: - sys.exit( - "There must be at least 2 repeats for each " - "condition indicated in the sample sheet.") - + if "control" not in conditions_count: + sys.exit( + "One of the condition types must be control, " + "to indicate which samples to use as the reference.") + if any(v < 2 for v in conditions_count.values()): + sys.exit( + "There must be at least 2 repeats for each " + "condition indicated in the sample sheet.") logger.info(f"Checked sample sheet for condition column {args.sample_sheet}.") diff --git a/bin/workflow_glue/tests/test_check_sample_sheet_condition.py b/bin/workflow_glue/tests/test_check_sample_sheet_condition.py index af414cc..b281a31 100755 --- a/bin/workflow_glue/tests/test_check_sample_sheet_condition.py +++ b/bin/workflow_glue/tests/test_check_sample_sheet_condition.py @@ -10,6 +10,7 @@ ERROR_MESSAGES = [ ("sample_sheet_1.csv", "There must be only two unique conditions in the condition column of the sample sheet."), # noqa: E501 ("sample_sheet_2.csv", "Sample sheet has no condition column which is required for the differential expression subworkflow."), # noqa: E501 ("sample_sheet_3.csv", "There must be at least 2 repeats for each condition indicated in the sample sheet."), # noqa: E501 + ("sample_sheet_4.csv", "One of the condition types must be control, to indicate which samples to use as the reference."), # noqa: E501 ] diff --git a/docs/quickstart.md b/docs/quickstart.md index a008dea..e1530d9 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -115,16 +115,16 @@ Differential Expression requires at least 2 replicates of each sample to compare The sample sheet should be a comma separated values file (.csv) and include at least three columns named `barcode`, `alias` and `condition`. - Each `barcode` should refer to a directory of the same name in the input FASTQ directory (in the example below `barcode01` to `barcode06` reflect the `test_data` directory). - The `alias` column allows you to rename each barcode to an alias that will be used in the report and other output files. -- The condition column will need to contain one of two keys to indicate the two samples being compared. for example: treated/untreated, sample/control etc. +- The condition column will need to contain one of two keys to indicate the two samples being compared. Control must be one of the keys, used to indicate which samples will be used as the reference in the differential expression analysis. In the default `sample_sheet.csv` available in the test_data directory we have used the following. eg. sample_sheet.csv ``` barcode,alias,condition -barcode01,sample01,untreated -barcode02,sample02,untreated -barcode03,sample03,untreated +barcode01,sample01,control +barcode02,sample02,control +barcode03,sample03,control barcode04,sample04,treated barcode05,sample05,treated barcode06,sample06,treated diff --git a/nextflow_schema.json b/nextflow_schema.json index 1ceb9b3..4bdabd7 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -97,10 +97,10 @@ "properties": { "sample_sheet": { "type": "string", - "title": "Sample sheet", + "title": "Sample and condition sheet", "format": "file-path", - "description": "A CSV file used to map barcodes to sample aliases. The sample sheet can be provided when the input data is a directory containing sub-directories with FASTQ files. If you are running the differential expression workflow, there should be an additional column `condition` with any two distinct labels eg. `treated`,`untreated`. There should be at least 3 repeats for each condition.", - "help_text": "The sample sheet is a CSV file with, minimally, columns named `barcode` and `alias`. Extra columns are allowed. A `type` column is required for certain workflows and should have the following values; `test_sample`, `positive_control`, `negative_control`, `no_template_control`." + "description": "A CSV file used to map barcodes to sample aliases. The sample sheet can be provided when the input data is a directory containing sub-directories with FASTQ files. If you are running the differential expression workflow, there must be an additional column `condition` with two labels, one of which must be `control` (e.g. `control` and `treated`). Control will indicate which samples will be used as the reference. There should be at least 3 repeats for each condition.", + "help_text": "The sample sheet is a CSV file with, minimally, columns named `barcode` and `alias`. Extra columns are allowed." }, "sample": { "type": "string", diff --git a/test_data/sample_sheet.csv b/test_data/sample_sheet.csv index 61f376c..87c50ce 100644 --- a/test_data/sample_sheet.csv +++ b/test_data/sample_sheet.csv @@ -1,7 +1,7 @@ barcode,sample_id,alias,condition -barcode01,sample01,sample01,untreated -barcode02,sample02,sample02,untreated -barcode03,sample03,sample03,untreated +barcode01,sample01,sample01,control +barcode02,sample02,sample02,control +barcode03,sample03,sample03,control barcode04,sample04,sample04,treated barcode05,sample05,sample05,treated barcode06,sample06,sample06,treated diff --git a/test_data/workflow_glue/check_sample_sheet_condition/sample_sheet_1.csv b/test_data/workflow_glue/check_sample_sheet_condition/sample_sheet_1.csv index 3a0f657..3e6b91e 100644 --- a/test_data/workflow_glue/check_sample_sheet_condition/sample_sheet_1.csv +++ b/test_data/workflow_glue/check_sample_sheet_condition/sample_sheet_1.csv @@ -1,7 +1,7 @@ barcode,sample_id,alias,condition -barcode01,sample01,sample01,untreated -barcode02,sample02,sample02,untreated -barcode03,sample03,sample03,untreated +barcode01,sample01,sample01,control +barcode02,sample02,sample02,control +barcode03,sample03,sample03,control barcode04,sample04,sample04,treated barcode05,sample05,sample05,treated barcode06,sample06,sample06,other \ No newline at end of file diff --git a/test_data/workflow_glue/check_sample_sheet_condition/sample_sheet_3.csv b/test_data/workflow_glue/check_sample_sheet_condition/sample_sheet_3.csv index ecc8f39..82859af 100644 --- a/test_data/workflow_glue/check_sample_sheet_condition/sample_sheet_3.csv +++ b/test_data/workflow_glue/check_sample_sheet_condition/sample_sheet_3.csv @@ -1,3 +1,3 @@ barcode,sample_id,alias,condition -barcode01,sample01,sample01,untreated +barcode01,sample01,sample01,control barcode04,sample04,sample04,treated diff --git a/test_data/workflow_glue/check_sample_sheet_condition/sample_sheet_4.csv b/test_data/workflow_glue/check_sample_sheet_condition/sample_sheet_4.csv new file mode 100644 index 0000000..61f376c --- /dev/null +++ b/test_data/workflow_glue/check_sample_sheet_condition/sample_sheet_4.csv @@ -0,0 +1,7 @@ +barcode,sample_id,alias,condition +barcode01,sample01,sample01,untreated +barcode02,sample02,sample02,untreated +barcode03,sample03,sample03,untreated +barcode04,sample04,sample04,treated +barcode05,sample05,sample05,treated +barcode06,sample06,sample06,treated