Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added kallistobustools #56

Merged
merged 10 commits into from Apr 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/workflows/ci.yml
Expand Up @@ -19,9 +19,14 @@ jobs:
NXF_ANSI_LOG: false
strategy:
matrix:
profile: ['test,docker', 'test_kallisto,docker', 'test,docker --aligner star']
profile:
[
"test,docker --aligner alevin",
"test,docker --aligner kallisto",
"test,docker --aligner star",
]
# Nextflow versions: check pipeline minimum and current latest
nxf_ver: ['20.10.0', '21.03.0-edge']
nxf_ver: ["20.10.0", "21.03.0-edge"]
steps:
- name: Check out pipeline code
uses: actions/checkout@v2
Expand Down Expand Up @@ -55,4 +60,3 @@ jobs:
# Remember that you can parallelise this by using strategy.matrix
run: |
nextflow run ${GITHUB_WORKSPACE} -profile ${{ matrix.profile }}

3 changes: 0 additions & 3 deletions conf/base.config
Expand Up @@ -34,7 +34,4 @@ process {
errorStrategy = 'retry'
maxRetries = 2
}
withName:PLASMIDID {
errorStrategy = 'ignore'
}
}
11 changes: 10 additions & 1 deletion conf/modules.config
Expand Up @@ -39,7 +39,16 @@ params {
args = ""
}
'star_align' {
args = "--soloType CB_UMI_Simple --readFilesCommand zcat --runDirPerm All_RWX --outWigType bedGraph --twopassMode Basic --outSAMtype BAM SortedByCoordinate"
args = "--readFilesCommand zcat --runDirPerm All_RWX --outWigType bedGraph --twopassMode Basic --outSAMtype BAM SortedByCoordinate"
}
'kallistobustools_ref' {
args = ""
}
'kallistobustools_count' {
args = ""
}
'multiqc_kb' {
args = ""
}
}
}
8 changes: 3 additions & 5 deletions conf/test.config
Expand Up @@ -16,12 +16,10 @@ params {
max_time = 48.h

// Input data
input_paths = [
['S10_L001',
['https://github.com/nf-core/test-datasets/raw/scrnaseq/testdata/S10_L001_R1_001.fastq.gz',
'https://github.com/nf-core/test-datasets/raw/scrnaseq/testdata/S10_L001_R2_001.fastq.gz']]]
fasta = 'https://github.com/nf-core/test-datasets/raw/scrnaseq/reference/GRCm38.p6.genome.chr19.fa'
input = 'https://github.com/nf-core/test-datasets/raw/scrnaseq/samplesheet.csv'
genome_fasta = 'https://github.com/nf-core/test-datasets/raw/scrnaseq/reference/GRCm38.p6.genome.chr19.fa'
gtf = 'https://github.com/nf-core/test-datasets/raw/scrnaseq/reference/gencode.vM19.annotation.chr19.gtf'
protocol = '10XV2'
// Ignore `--input` as otherwise the parameter validation will throw an error
schema_ignore_params = 'genomes,input_paths,input'
}
31 changes: 0 additions & 31 deletions conf/test_kallisto.config

This file was deleted.

44 changes: 20 additions & 24 deletions lib/NfcoreSchema.groovy
Expand Up @@ -191,11 +191,11 @@ class NfcoreSchema {

// Remove an element from a JSONArray
private static JSONArray removeElement(jsonArray, element){
def list = []
def list = []
int len = jsonArray.length()
for (int i=0;i<len;i++){
for (int i=0;i<len;i++){
list.add(jsonArray.get(i).toString())
}
}
list.remove(element)
JSONArray jsArray = new JSONArray(list)
return jsArray
Expand All @@ -213,7 +213,7 @@ class NfcoreSchema {
// If the param was required, change this
if (definition[key].has("required")) {
def cleaned_required = removeElement(definition[key].required, ignore_param)
definition[key].put("required", cleaned_required)
definition[key].put("required", cleaned_required)
}
}
}
Expand Down Expand Up @@ -243,7 +243,7 @@ class NfcoreSchema {
}
// Cast Duration to String
if (p['value'].getClass() == nextflow.util.Duration) {
new_params.replace(p.key, p['value'].toString())
new_params.replace(p.key, p['value'].toString().replaceFirst(/d(?!\S)/, "day"))
}
// Cast LinkedHashMap to String
if (p['value'].getClass() == LinkedHashMap) {
Expand Down Expand Up @@ -482,10 +482,10 @@ class NfcoreSchema {
}
workflow_summary['runName'] = workflow.runName
if (workflow.containerEngine) {
workflow_summary['containerEngine'] = "$workflow.containerEngine"
workflow_summary['containerEngine'] = workflow.containerEngine
}
if (workflow.container) {
workflow_summary['container'] = "$workflow.container"
workflow_summary['container'] = workflow.container
}
workflow_summary['launchDir'] = workflow.launchDir
workflow_summary['workDir'] = workflow.workDir
Expand All @@ -506,17 +506,7 @@ class NfcoreSchema {
def params_value = params.get(param)
def schema_value = group_params.get(param).default
def param_type = group_params.get(param).type
if (schema_value == null) {
if (param_type == 'boolean') {
schema_value = false
}
if (param_type == 'string') {
schema_value = ''
}
if (param_type == 'integer') {
schema_value = 0
}
} else {
if (schema_value != null) {
if (param_type == 'string') {
if (schema_value.contains('$projectDir') || schema_value.contains('${projectDir}')) {
def sub_string = schema_value.replace('\$projectDir', '')
Expand All @@ -535,8 +525,13 @@ class NfcoreSchema {
}
}

if (params_value != schema_value) {
sub_params.put("$param", params_value)
// We have a default in the schema, and this isn't it
if (schema_value != null && params_value != schema_value) {
sub_params.put(param, params_value)
}
// No default in the schema, and this isn't empty
else if (schema_value == null && params_value != "" && params_value != null && params_value != false) {
sub_params.put(param, params_value)
}
}
}
Expand All @@ -549,22 +544,23 @@ class NfcoreSchema {
* Beautify parameters for summary and return as string
*/
private static String params_summary_log(workflow, params, json_schema) {
Map colors = log_colours(params.monochrome_logs)
String output = ''
def params_map = params_summary_map(workflow, params, json_schema)
def max_chars = params_max_chars(params_map)
for (group in params_map.keySet()) {
def group_params = params_map.get(group) // This gets the parameters of that particular group
if (group_params) {
output += group + '\n'
output += colors.bold + group + colors.reset + '\n'
for (param in group_params.keySet()) {
output += " \u001B[1m" + param.padRight(max_chars) + ": \u001B[1m" + group_params.get(param) + '\n'
output += " " + colors.blue + param.padRight(max_chars) + ": " + colors.green + group_params.get(param) + colors.reset + '\n'
}
output += '\n'
}
}
output += "[Only displaying parameters that differ from pipeline default]\n"
output += dashed_line(params.monochrome_logs)
output += '\n\n' + dashed_line(params.monochrome_logs)
output += colors.dim + "\n Only displaying parameters that differ from defaults.\n" + colors.reset
output += dashed_line(params.monochrome_logs)
return output
}

Expand Down
82 changes: 82 additions & 0 deletions lib/Workflow.groovy
Expand Up @@ -54,4 +54,86 @@ class Workflow {
yaml_file_text += "${summary_section}"
return yaml_file_text
}

/*
* Format the protocol
* Given the protocol paramter (params.protocol) and the aligner (params.aligner),
* this function formats the protocol such that it is fit for the respective
* subworkflow
*/
static formatProtocol(protocol, aligner) {
String new_protocol = protocol
String chemistry = ""

// alevin
if (aligner == "alevin") {
switch(protocol) {
case "10XV1":
new_protocol = "chromium"
chemistry = "V1"
break
case "10XV2":
new_protocol = "chromium"
chemistry = "V2"
break
case "10XV3":
new_protocol = "chromiumV3"
chemistry = "V3"
break
case "dropseq":
new_protocol = "dropseq"
}
}

// star
else if (aligner == "star") {
switch(protocol) {
case "10XV1":
new_protocol = "CB_UMI_Simple"
chemistry = "V1"
break
case "10XV2":
new_protocol = "CB_UMI_Simple"
chemistry = "V2"
break
case "10XV3":
new_protocol = "CB_UMI_Simple"
chemistry = "V3"
break
case "dropseq":
new_protocol = "CB_UMI_Simple"
break
case "smartseq":
new_protocol = "SmartSeq"
}
}

// kallisto bustools
else if (aligner = "kallisto" ) {
switch(protocol) {
case "10XV1":
new_protocol = "10XV1"
chemistry = "V1"
break
case "10XV2":
new_protocol = "10XV2"
chemistry = "V2"
break
case "10XV3":
new_protocol = "10XV3"
chemistry = "V3"
break
case "dropseq":
new_protocol = "DROPSEQ"
break
case "smartseq":
new_protocol = "SMARTSEQ"
}
}
KevinMenden marked this conversation as resolved.
Show resolved Hide resolved
else {
exit 1, "Aligner not recognized."
}

return [new_protocol, chemistry]
}
}
40 changes: 40 additions & 0 deletions modules/local/gene_map.nf
@@ -0,0 +1,40 @@
// Import generic module functions
include { saveFiles } from './functions'

params.options = [:]

/*
* Reformat design file and check validity
*/
process GENE_MAP {
tag "$gtf"
publishDir "${params.outdir}",
mode: params.publish_dir_mode,
saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', publish_id:'') }

conda (params.enable_conda ? "conda-forge::python=3.8.3" : null)
if (workflow.containerEngine == 'singularity' && !params.pull_docker_container) {
container "https://depot.galaxyproject.org/singularity/python:3.8.3"
} else {
container "quay.io/biocontainers/python:3.8.3"
}

input:
path gtf

output:
path "transcripts_to_genes.txt" , emit: gene_map

script:
if("${gtf}".endsWith('.gz')){
name = "${gtf.baseName}"
unzip = "gunzip -f ${gtf}"
} else {
unzip = ""
name = "${gtf}"
}
"""
$unzip
cat $name | t2g.py --use_version > transcripts_to_genes.txt
"""
}
56 changes: 56 additions & 0 deletions modules/local/kallistobustools_count.nf
@@ -0,0 +1,56 @@
// Import generic module functions
include { initOptions; saveFiles; getSoftwareName } from './functions'

params.options = [:]
options = initOptions(params.options)

process KALLISTOBUSTOOLS_COUNT {
tag "$meta.id"
label 'process_medium'
publishDir "${params.outdir}",
mode: params.publish_dir_mode,
saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:getSoftwareName(task.process), publish_id:meta.id) }

conda (params.enable_conda ? "bioconda::kb-python=0.25.1" : null)
if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) {
container "https://depot.galaxyproject.org/singularity/kb-python:0.25.1--py_0"
} else {
container "quay.io/biocontainers/kb-python:0.25.1--py_0"
}

input:
tuple val(meta), path(reads)
path index
path t2g
path t1c
path t2c
val use_t1c
val use_t2c
val workflow
val technology

output:
tuple val(meta), path ("*_kallistobustools_count*") , emit: counts
path "*.version.txt" , emit: version

script:
def software = getSoftwareName(task.process)
def prefix = options.suffix ? "${meta.id}${options.suffix}" : "${meta.id}"
def cdna = use_t1c ? "-c1 $t1c" : ''
def introns = use_t2c ? "-c2 $t2c" : ''
"""
kb count \\
-t $task.cpus \\
-i $index \\
-g $t2g \\
$cdna \\
$introns \\
--workflow $workflow \\
-x $technology \\
$options.args \\
-o ${prefix}_kallistobustools_count \\
${reads[0]} ${reads[1]}

echo \$(kb 2>&1) | sed 's/^kb_python //; s/Usage.*\$//' > ${software}.version.txt
"""
}