From 93bf83aa51550c09e4af5dc6eb44843e955e6a16 Mon Sep 17 00:00:00 2001 From: nservant Date: Fri, 18 Oct 2019 13:31:40 +0200 Subject: [PATCH 01/36] dump v1.1.1dev --- .travis.yml | 2 +- Dockerfile | 2 +- environment.yml | 2 +- nextflow.config | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index da79ee6..2dd43f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ before_install: - docker pull nfcore/hic:dev # Fake the tag locally so that the pipeline runs properly # Looks weird when this is :dev to :dev, but makes sense when testing code for a release (:dev to :1.0.1) - - docker tag nfcore/hic:dev nfcore/hic:1.1.0 + - docker tag nfcore/hic:dev nfcore/hic:dev install: # Install Nextflow diff --git a/Dockerfile b/Dockerfile index 8b6ee9b..4714783 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,4 +7,4 @@ RUN apt-get update && apt-get install -y gcc g++ && apt-get clean -y COPY environment.yml / RUN conda env create -f /environment.yml && conda clean -a -ENV PATH /opt/conda/envs/nf-core-hic-1.1.0/bin:$PATH +ENV PATH /opt/conda/envs/nf-core-hic-1.1.1dev/bin:$PATH diff --git a/environment.yml b/environment.yml index 4d9c20c..271f3f5 100644 --- a/environment.yml +++ b/environment.yml @@ -1,6 +1,6 @@ # You can use this file to create a conda environment for this pipeline: # conda env create -f environment.yml -name: nf-core-hic-1.1.0 +name: nf-core-hic-1.1.1dev channels: - conda-forge - bioconda diff --git a/nextflow.config b/nextflow.config index a521f3f..5d69802 100644 --- a/nextflow.config +++ b/nextflow.config @@ -45,7 +45,7 @@ params { // Container slug. Stable releases should specify release tag! // Developmental code should specify :dev -process.container = 'nfcore/hic:1.1.0' +process.container = 'nfcore/hic:dev' // Load base.config by default for all pipelines includeConfig 'conf/base.config' @@ -102,7 +102,7 @@ manifest { description = 'Analysis of Chromosome Conformation Capture data (Hi-C)' mainScript = 'main.nf' nextflowVersion = '>=19.04.0' - version = '1.1.0' + version = '1.1.1dev' } // Function to ensure that resource requirements don't go beyond From b6950062e14fd78c6a37d6b7b45c6da0b8b9ee5a Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Tue, 19 Nov 2019 09:17:48 +0100 Subject: [PATCH 02/36] Readme: Fix example commands --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c2ae60f..def8c35 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This pipeline is based on the [HiC-Pro workflow](https://github.com/nservant/HiC-Pro). -It was designed to process Hi-C data from raw fastq files (paired-end Illumina +It was designed to process Hi-C data from raw FastQ files (paired-end Illumina data) to normalized contact maps. The current version supports most protocols, including digestion protocols as well as protocols that do not require restriction enzymes such as DNase Hi-C. @@ -50,13 +50,13 @@ ii. Install one of [`docker`](https://docs.docker.com/engine/installation/), iii. Download the pipeline and test it on a minimal dataset with a single command ```bash -nextflow run hic -profile test, +nextflow run nf-core/hic -profile test, ``` iv. Start running your own analysis! ```bash -nextflow run hic -profile --reads '*_R{1,2}.fastq.gz' --genome GRCh37 +nextflow run nf-core/hic -profile --reads '*_R{1,2}.fastq.gz' --genome GRCh37 ``` See [usage docs](docs/usage.md) for all of the available options when running the pipeline. From 95cbe76a112115f0d6901dd3c15abda8c83d4108 Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 19 Nov 2019 16:46:44 +0100 Subject: [PATCH 03/36] Fix typo in help message --- main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.nf b/main.nf index 31f73a8..82365f1 100644 --- a/main.nf +++ b/main.nf @@ -42,7 +42,7 @@ def helpMessage() { --restriction_site Cutting motif(s) of restriction enzyme(s) (comma separated). Default: 'A^AGCTT' --ligation_site Ligation motifs to trim (comma separated). Default: 'AAGCTAGCTT' --min_restriction_fragment_size Minimum size of restriction fragments to consider. Default: None - --max_restriction_framgnet_size Maximum size of restriction fragmants to consider. Default: None + --max_restriction_fragment_size Maximum size of restriction fragments to consider. Default: None --min_insert_size Minimum insert size of mapped reads to consider. Default: None --max_insert_size Maximum insert size of mapped reads to consider. Default: None --saveInteractionBAM Save BAM file with interaction tags (dangling-end, self-circle, etc.). Default: False From 637e22bb038df084f8b5d3207db375133ac9d555 Mon Sep 17 00:00:00 2001 From: nservant Date: Mon, 27 Jan 2020 10:16:45 +0100 Subject: [PATCH 04/36] [BUG] Change regex for read extensions --- main.nf | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/main.nf b/main.nf index 82365f1..2b8c2ec 100644 --- a/main.nf +++ b/main.nf @@ -497,8 +497,8 @@ if (!params.dnase){ set val(oname), file("${prefix}.mapstat") into all_mapstat script: - sample = prefix.toString() - ~/(_R1$|_R2$|_val_1$|_val_2$|_1$|_2$)/ - tag = prefix.toString() =~/_R1$|_val_1$|_1$/ ? "R1" : "R2" + sample = prefix.toString() - ~/(_R1|_R2|_val_1|_val_2|_1$|_2)/ + tag = prefix.toString() =~/_R1|_val_1|_1/ ? "R1" : "R2" oname = prefix.toString() - ~/(\.[0-9]+)$/ """ @@ -538,8 +538,8 @@ if (!params.dnase){ set val(oname), file("${prefix}.mapstat") into all_mapstat script: - sample = prefix.toString() - ~/(_R1$|_R2$|_val_1$|_val_2$|_1$|_2$)/ - tag = prefix.toString() =~/_R1$|_val_1$|_1$/ ? "R1" : "R2" + sample = prefix.toString() - ~/(_R1|_R2|_val_1|_val_2|_1|_2)/ + tag = prefix.toString() =~/_R1|_val_1|_1/ ? "R1" : "R2" oname = prefix.toString() - ~/(\.[0-9]+)$/ """ @@ -555,6 +555,7 @@ if (!params.dnase){ } } +println(bwt2_merged_bam) process combine_mapped_files{ tag "$sample = $r1_prefix + $r2_prefix" @@ -715,7 +716,7 @@ process merge_sample { file("mstats/") into all_mstats script: - sample = prefix.toString() - ~/(_R1$|_R2$|_val_1$|_val_2$|_1$|_2$)/ + sample = prefix.toString() - ~/(_R1|_R2|_val_1|_val_2|_1|_2)/ if ( (fstat =~ /.mapstat/) ){ ext = "mmapstat" } if ( (fstat =~ /.pairstat/) ){ ext = "mpairstat" } if ( (fstat =~ /.RSstat/) ){ ext = "mRSstat" } From ca2723da30cac11b8947feb32bf054c42da1ca8f Mon Sep 17 00:00:00 2001 From: nservant Date: Thu, 30 Jan 2020 19:25:00 +0100 Subject: [PATCH 05/36] Add nproc in hicpro2higlass --- main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.nf b/main.nf index 31f73a8..53a7cf2 100644 --- a/main.nf +++ b/main.nf @@ -796,7 +796,7 @@ process generate_cool{ script: """ - hicpro2higlass.sh -i $vpairs -r 5000 -c ${chrsize} -n + hicpro2higlass.sh -p ${task.cpus} -i $vpairs -r 5000 -c ${chrsize} -n """ } From 47319ffe4de0c091133b72c0ca3dbb48fbccb3e9 Mon Sep 17 00:00:00 2001 From: nservant Date: Thu, 30 Jan 2020 19:26:55 +0100 Subject: [PATCH 06/36] update curie config --- conf/curie.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/curie.config b/conf/curie.config index ab85a2d..be34946 100644 --- a/conf/curie.config +++ b/conf/curie.config @@ -4,8 +4,8 @@ singularity { process { executor = 'pbs' - queue = params.queue - //beforeScript = 'export PATH=/bioinfo/pipelines/sandbox/dev/nfcore/rnaseq/modules/conda/envs/nf-core-rnaseq-1.2/bin:$PATH' + //queue = params.queue + beforeScript = 'export PATH=/data/tmp/nservant/conda/nf-core-hic/bin/:$PATH' } params { From c7a67709fd9dbfa0ceee47a4c5fb6c417d93f427 Mon Sep 17 00:00:00 2001 From: nservant Date: Thu, 30 Jan 2020 19:29:29 +0100 Subject: [PATCH 07/36] update hicpro2higlass --- bin/hicpro2higlass.sh | 18 +++++++++++------- conf/base.config | 5 +++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/bin/hicpro2higlass.sh b/bin/hicpro2higlass.sh index 5cc09b7..ff11aee 100755 --- a/bin/hicpro2higlass.sh +++ b/bin/hicpro2higlass.sh @@ -103,6 +103,7 @@ function help { echo " -i|--input INPUT : allValidPairs or matrix file generated by HiC-Pro" echo " -r|--res RESOLUTION : .matrix file resolution or maximum resolution to reach from the .allValidPairs input file" echo " -c|--chrom CHROMSIZE : chromosome size file" + echo " -p|--proc NB_CPU : number of CPUs for cooler" echo " [-n|--norm] : run cooler matrix balancing algorithm" echo " [-o|--out] : output path. Default is current path" echo " [-t|--temp] TEMP : path to tmp folder. Default is current path" @@ -125,6 +126,7 @@ for arg in "$@"; do "--bed") set -- "$@" "-b" ;; "--res") set -- "$@" "-r" ;; "--chrom") set -- "$@" "-c" ;; + "--proc") set -- "$@" "-p" ;; "--out") set -- "$@" "-o" ;; "--temp") set -- "$@" "-t" ;; "--norm") set -- "$@" "-n" ;; @@ -136,18 +138,20 @@ done INPUT_HICPRO="" INPUT_BED="" NORMALIZE=0 +NPROC=1 CHROMSIZES_FILE="" RES=10000 OUT="./" TEMP="./" -while getopts ":i:b:c:r:o:t:nh" OPT +while getopts ":i:b:c:p:r:o:t:nh" OPT do case $OPT in i) INPUT_HICPRO=$OPTARG;; b) INPUT_BED=$OPTARG;; n) NORMALIZE=1;; c) CHROMSIZES_FILE=$OPTARG;; + p) NPROC=$OPTARG;; r) RES=$OPTARG;; o) OUT=$OPTARG;; t) TEMP=$OPTARG;; @@ -223,9 +227,9 @@ if [[ $DATATYPE == "MATRIX" ]]; then echo -e "\nZoomify .cool file ..." if [[ $NORMALIZE == 1 ]]; then - cooler zoomify --balance $tmp_dir/$out + cooler zoomify --nproc ${NPROC} --balance $tmp_dir/$out else - cooler zoomify --no-balance $tmp_dir/$out + cooler zoomify --nproc ${NPROC} $tmp_dir/$out fi out=$(basename $INPUT_HICPRO | sed -e 's/.mat.*/.mcool/') @@ -233,19 +237,19 @@ elif [[ $DATATYPE == "VALID" ]]; then out=$(basename $INPUT_HICPRO | sed -e 's/.allValidPairs.*/.cool/') awk '{OFS="\t";print $2,$3,$4,$5,$6,$7,1}' $INPUT_HICPRO | sed -e 's/+/1/g' -e 's/-/16/g' > $tmp_dir/contacts.txt - cooler csort --nproc 2 -c1 1 -p1 2 -s1 3 -c2 4 -p2 5 -s2 6 \ + cooler csort --nproc ${NPROC} -c1 1 -p1 2 -s1 3 -c2 4 -p2 5 -s2 6 \ -o $tmp_dir/contacts.sorted.txt.gz \ $tmp_dir/contacts.txt \ $CHROMSIZES_FILE cooler makebins $CHROMSIZES_FILE $RES > $tmp_dir/bins.bed - cooler cload pairix $tmp_dir/bins.bed $tmp_dir/contacts.sorted.txt.gz $tmp_dir/$out + cooler cload pairix --nproc ${NPROC} $tmp_dir/bins.bed $tmp_dir/contacts.sorted.txt.gz $tmp_dir/$out echo -e "\nZoomify .cool file ..." if [[ $NORMALIZE == 1 ]]; then - cooler zoomify --balance $tmp_dir/$out + cooler zoomify --nproc ${NPROC} --balance $tmp_dir/$out else - cooler zoomify --no-balance $tmp_dir/$out + cooler zoomify --nproc ${NPROC} $tmp_dir/$out fi out=$(basename $INPUT_HICPRO | sed -e 's/.allValidPairs.*/.mcool/') fi diff --git a/conf/base.config b/conf/base.config index 28b4679..706ca6c 100644 --- a/conf/base.config +++ b/conf/base.config @@ -66,6 +66,11 @@ process { memory = { check_max( 10.GB * task.attempt, 'memory' ) } time = { check_max( 5.h * task.attempt, 'time' ) } } + withName:generate_cool { + cpus = check_max( 2, 'cpus' ) } + memory = { check_max( 16.GB * task.attempt, 'memory' ) } + time = { check_max( 4.h * task.attempt, 'time' ) } + } } params { From c79ca2f76e1c98ab3d3523b3e20a6197c68f435a Mon Sep 17 00:00:00 2001 From: nservant Date: Thu, 30 Jan 2020 19:30:33 +0100 Subject: [PATCH 08/36] update hicpro2higlass --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aac5146..d03d30f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## v1.1.0 - 2019-10-15 +* Update hicpro2higlass with `-p` parameter * Support 'N' base motif in restriction/ligation sites * Support multiple restriction enzymes/ligattion sites (comma separated) ([#31](https://github.com/nf-core/hic/issues/31)) * Add --saveInteractionBAM option From b79370f18e7326b78f43a130520efcb1586959b4 Mon Sep 17 00:00:00 2001 From: nservant Date: Thu, 30 Jan 2020 20:14:22 +0100 Subject: [PATCH 09/36] fix typo in base.conf --- conf/base.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/base.config b/conf/base.config index 706ca6c..142439f 100644 --- a/conf/base.config +++ b/conf/base.config @@ -67,7 +67,7 @@ process { time = { check_max( 5.h * task.attempt, 'time' ) } } withName:generate_cool { - cpus = check_max( 2, 'cpus' ) } + cpus = { check_max( 2, 'cpus' ) } memory = { check_max( 16.GB * task.attempt, 'memory' ) } time = { check_max( 4.h * task.attempt, 'time' ) } } From 41a42a25da3df9d7e2b0e7f333ffa14041311a22 Mon Sep 17 00:00:00 2001 From: MaxUlysse Date: Tue, 11 Feb 2020 15:17:09 +0100 Subject: [PATCH 10/36] add social preview image --- assets/nf-core-hic_social_preview.png | Bin 0 -> 41200 bytes assets/nf-core-hic_social_preview.svg | 448 ++++++++++++++++++++++++++ 2 files changed, 448 insertions(+) create mode 100644 assets/nf-core-hic_social_preview.png create mode 100644 assets/nf-core-hic_social_preview.svg diff --git a/assets/nf-core-hic_social_preview.png b/assets/nf-core-hic_social_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..54784f0201bec3769e57e00a9a4f3c69c64dc055 GIT binary patch literal 41200 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + Analysis of Chromosome Conformation Capture data (Hi-C) + hic + + + + + + + + + + + + + + + + + + + + + + + + + From 12b1de567a6712df49e8d8d7088fa5a06273021a Mon Sep 17 00:00:00 2001 From: nservant Date: Wed, 1 Apr 2020 09:14:53 +0200 Subject: [PATCH 11/36] [MODIF] Fix bug in tag --- CHANGELOG.md | 4 ++++ main.nf | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d03d30f..2019e42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # nf-core/hic: Changelog +## v1.1.1 + +* Fix bug in tag. Remove '[' + ## v1.1.0 - 2019-10-15 * Update hicpro2higlass with `-p` parameter diff --git a/main.nf b/main.nf index 576882e..d363298 100644 --- a/main.nf +++ b/main.nf @@ -380,7 +380,7 @@ if(!params.chromosome_size && params.fasta){ if(!params.restriction_fragments && params.fasta && !params.dnase){ process getRestrictionFragments { - tag "$fasta [${params.restriction_site}]" + tag "$fasta - ${params.restriction_site}" publishDir path: { params.saveReference ? "${params.outdir}/reference_genome" : params.outdir }, saveAs: { params.saveReference ? it : null }, mode: 'copy' From e013105dc4015a9cb2434fcde6089598f5ad3f40 Mon Sep 17 00:00:00 2001 From: nservant Date: Mon, 11 May 2020 17:04:05 +0200 Subject: [PATCH 12/36] Template update for nf-core/tools version 1.9 --- .github/CONTRIBUTING.md | 50 +- .github/ISSUE_TEMPLATE/bug_report.md | 43 +- .github/ISSUE_TEMPLATE/feature_request.md | 18 +- .github/PULL_REQUEST_TEMPLATE.md | 28 +- .github/markdownlint.yml | 5 + .github/workflows/branch.yml | 16 + .github/workflows/ci.yml | 30 ++ .github/workflows/linting.yml | 50 ++ .gitignore | 4 +- .travis.yml | 37 -- CHANGELOG.md | 14 +- CODE_OF_CONDUCT.md | 2 +- Dockerfile | 12 +- README.md | 76 ++- Singularity | 18 - assets/email_template.html | 2 + assets/email_template.txt | 29 +- {conf => assets}/multiqc_config.yaml | 6 +- assets/nf-core-hic_logo.png | Bin 0 -> 10282 bytes assets/sendmail_template.txt | 48 +- .../scrape_software_versions.cpython-36.pyc | Bin 1324 -> 0 bytes bin/markdown_to_html.py | 100 ++++ bin/markdown_to_html.r | 51 -- bin/scrape_software_versions.py | 27 +- conf/awsbatch.config | 13 - conf/base.config | 46 +- conf/igenomes.config | 451 ++++++++++++++---- conf/test.config | 9 +- docs/README.md | 10 +- docs/configuration/adding_your_own.md | 86 ---- docs/configuration/local.md | 46 -- docs/configuration/reference_genomes.md | 49 -- docs/images/nf-core-hic_logo.png | Bin 0 -> 17777 bytes docs/installation.md | 110 ----- docs/output.md | 6 +- docs/troubleshooting.md | 30 -- docs/usage.md | 193 +++++--- environment.yml | 12 +- main.nf | 378 +++++++++------ nextflow.config | 81 ++-- 40 files changed, 1282 insertions(+), 904 deletions(-) create mode 100644 .github/markdownlint.yml create mode 100644 .github/workflows/branch.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/linting.yml delete mode 100644 .travis.yml delete mode 100644 Singularity rename {conf => assets}/multiqc_config.yaml (79%) create mode 100644 assets/nf-core-hic_logo.png delete mode 100644 bin/__pycache__/scrape_software_versions.cpython-36.pyc create mode 100755 bin/markdown_to_html.py delete mode 100755 bin/markdown_to_html.r delete mode 100644 conf/awsbatch.config delete mode 100644 docs/configuration/adding_your_own.md delete mode 100644 docs/configuration/local.md delete mode 100644 docs/configuration/reference_genomes.md create mode 100644 docs/images/nf-core-hic_logo.png delete mode 100644 docs/installation.md delete mode 100644 docs/troubleshooting.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index fda99de..276f0e6 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,45 +1,57 @@ # nf-core/hic: Contributing Guidelines -Hi there! Many thanks for taking an interest in improving nf-core/hic. +Hi there! +Many thanks for taking an interest in improving nf-core/hic. -We try to manage the required tasks for nf-core/hic using GitHub issues, you probably came to this page when creating one. Please use the pre-filled template to save time. +We try to manage the required tasks for nf-core/hic using GitHub issues, you probably came to this page when creating one. +Please use the pre-filled template to save time. -However, don't be put off by this template - other more general issues and suggestions are welcome! Contributions to the code are even more welcome ;) +However, don't be put off by this template - other more general issues and suggestions are welcome! +Contributions to the code are even more welcome ;) -> If you need help using or modifying nf-core/hic then the best place to go is the Gitter chatroom where you can ask us questions directly: https://gitter.im/nf-core/Lobby +> If you need help using or modifying nf-core/hic then the best place to ask is on the nf-core Slack [#hic](https://nfcore.slack.com/channels/hic) channel ([join our Slack here](https://nf-co.re/join/slack)). ## Contribution workflow -If you'd like to write some code for nf-core/hic, the standard workflow -is as follows: -1. Check that there isn't already an issue about your idea in the - [nf-core/hic issues](https://github.com/nf-core/hic/issues) to avoid - duplicating work. +If you'd like to write some code for nf-core/hic, the standard workflow is as follows: + +1. Check that there isn't already an issue about your idea in the [nf-core/hic issues](https://github.com/nf-core/hic/issues) to avoid duplicating work * If there isn't one already, please create one so that others know you're working on this -2. Fork the [nf-core/hic repository](https://github.com/nf-core/hic) to your GitHub account +2. [Fork](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) the [nf-core/hic repository](https://github.com/nf-core/hic) to your GitHub account 3. Make the necessary changes / additions within your forked repository -4. Submit a Pull Request against the `dev` branch and wait for the code to be reviewed and merged. - -If you're not used to this workflow with git, you can start with some [basic docs from GitHub](https://help.github.com/articles/fork-a-repo/) or even their [excellent interactive tutorial](https://try.github.io/). +4. Submit a Pull Request against the `dev` branch and wait for the code to be reviewed and merged +If you're not used to this workflow with git, you can start with some [docs from GitHub](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests) or even their [excellent `git` resources](https://try.github.io/). ## Tests -When you create a pull request with changes, [Travis CI](https://travis-ci.org/) will run automatic tests. + +When you create a pull request with changes, [GitHub Actions](https://github.com/features/actions) will run automatic tests. Typically, pull-requests are only fully reviewed when these tests are passing, though of course we can help out before then. There are typically two types of tests that run: ### Lint Tests -The nf-core has a [set of guidelines](http://nf-co.re/guidelines) which all pipelines must adhere to. + +`nf-core` has a [set of guidelines](https://nf-co.re/developers/guidelines) which all pipelines must adhere to. To enforce these and ensure that all pipelines stay in sync, we have developed a helper tool which runs checks on the pipeline code. This is in the [nf-core/tools repository](https://github.com/nf-core/tools) and once installed can be run locally with the `nf-core lint ` command. If any failures or warnings are encountered, please follow the listed URL for more documentation. ### Pipeline Tests -Each nf-core pipeline should be set up with a minimal set of test-data. -Travis CI then runs the pipeline on this data to ensure that it exists successfully. + +Each `nf-core` pipeline should be set up with a minimal set of test-data. +`GitHub Actions` then runs the pipeline on this data to ensure that it exits successfully. If there are any failures then the automated tests fail. -These tests are run both with the latest available version of Nextflow and also the minimum required version that is stated in the pipeline code. +These tests are run both with the latest available version of `Nextflow` and also the minimum required version that is stated in the pipeline code. + +## Patch + +: warning: Only in the unlikely and regretful event of a release happening with a bug. + +* On your own fork, make a new branch `patch` based on `upstream/master`. +* Fix the bug, and bump version (X.Y.Z+1). +* A PR should be made on `master` from patch to directly this particular bug. ## Getting help -For further information/help, please consult the [nf-core/hic documentation](https://github.com/nf-core/hic#documentation) and don't hesitate to get in touch on [Gitter](https://gitter.im/nf-core/Lobby) + +For further information/help, please consult the [nf-core/hic documentation](https://nf-co.re/nf-core/hic/docs) and don't hesitate to get in touch on the nf-core Slack [#hic](https://nfcore.slack.com/channels/hic) channel ([join our Slack here](https://nf-co.re/join/slack)). diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 8112c95..2b92033 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,31 +1,42 @@ +# nf-core/hic bug report + Hi there! -Thanks for telling us about a problem with the pipeline. Please delete this text and anything that's not relevant from the template below: +Thanks for telling us about a problem with the pipeline. +Please delete this text and anything that's not relevant from the template below: + +## Describe the bug -#### Describe the bug A clear and concise description of what the bug is. -#### Steps to reproduce +## Steps to reproduce + Steps to reproduce the behaviour: + 1. Command line: `nextflow run ...` 2. See error: _Please provide your error message_ -#### Expected behaviour +## Expected behaviour + A clear and concise description of what you expected to happen. -#### System: - - Hardware: [e.g. HPC, Desktop, Cloud...] - - Executor: [e.g. slurm, local, awsbatch...] - - OS: [e.g. CentOS Linux, macOS, Linux Mint...] - - Version [e.g. 7, 10.13.6, 18.3...] +## System + +- Hardware: +- Executor: +- OS: +- Version + +## Nextflow Installation + +- Version: + +## Container engine -#### Nextflow Installation: - - Version: [e.g. 0.31.0] +- Engine: +- version: +- Image tag: -#### Container engine: - - Engine: [e.g. Conda, Docker or Singularity] - - version: [e.g. 1.0.0] - - Image tag: [e.g. nfcore/hic:1.0.0] +## Additional context -#### Additional context Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 1f025b7..57fa7f7 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,16 +1,24 @@ +# nf-core/hic feature request + Hi there! -Thanks for suggesting a new feature for the pipeline! Please delete this text and anything that's not relevant from the template below: +Thanks for suggesting a new feature for the pipeline! +Please delete this text and anything that's not relevant from the template below: + +## Is your feature request related to a problem? Please describe -#### Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. + Ex. I'm always frustrated when [...] -#### Describe the solution you'd like +## Describe the solution you'd like + A clear and concise description of what you want to happen. -#### Describe alternatives you've considered +## Describe alternatives you've considered + A clear and concise description of any alternative solutions or features you've considered. -#### Additional context +## Additional context + Add any other context about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 473c41d..50d7959 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,15 +1,19 @@ -Many thanks to contributing to nf-core/hic! +# nf-core/hic pull request -Please fill in the appropriate checklist below (delete whatever is not relevant). These are the most common things requested on pull requests (PRs). +Many thanks for contributing to nf-core/hic! + +Please fill in the appropriate checklist below (delete whatever is not relevant). +These are the most common things requested on pull requests (PRs). ## PR checklist - - [ ] This comment contains a description of changes (with reason) - - [ ] If you've fixed a bug or added code that should be tested, add tests! - - [ ] If necessary, also make a PR on the [nf-core/hic branch on the nf-core/test-datasets repo]( https://github.com/nf-core/test-datasets/pull/new/nf-core/hic) - - [ ] Ensure the test suite passes (`nextflow run . -profile test,docker`). - - [ ] Make sure your code lints (`nf-core lint .`). - - [ ] Documentation in `docs` is updated - - [ ] `CHANGELOG.md` is updated - - [ ] `README.md` is updated - -**Learn more about contributing:** https://github.com/nf-core/hic/tree/master/.github/CONTRIBUTING.md + +- [ ] This comment contains a description of changes (with reason) +- [ ] If you've fixed a bug or added code that should be tested, add tests! +- [ ] If necessary, also make a PR on the [nf-core/hic branch on the nf-core/test-datasets repo](https://github.com/nf-core/test-datasets/pull/new/nf-core/hic) +- [ ] Ensure the test suite passes (`nextflow run . -profile test,docker`). +- [ ] Make sure your code lints (`nf-core lint .`). +- [ ] Documentation in `docs` is updated +- [ ] `CHANGELOG.md` is updated +- [ ] `README.md` is updated + +**Learn more about contributing:** [CONTRIBUTING.md](https://github.com/nf-core/hic/tree/master/.github/CONTRIBUTING.md) \ No newline at end of file diff --git a/.github/markdownlint.yml b/.github/markdownlint.yml new file mode 100644 index 0000000..96b12a7 --- /dev/null +++ b/.github/markdownlint.yml @@ -0,0 +1,5 @@ +# Markdownlint configuration file +default: true, +line-length: false +no-duplicate-header: + siblings_only: true diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml new file mode 100644 index 0000000..e95804c --- /dev/null +++ b/.github/workflows/branch.yml @@ -0,0 +1,16 @@ +name: nf-core branch protection +# This workflow is triggered on PRs to master branch on the repository +# It fails when someone tries to make a PR against the nf-core `master` branch instead of `dev` +on: + pull_request: + branches: + - master + +jobs: + test: + runs-on: ubuntu-18.04 + steps: + # PRs are only ok if coming from an nf-core `dev` branch or a fork `patch` branch + - name: Check PRs + run: | + { [[ $(git remote get-url origin) == *nf-core/hic ]] && [[ ${GITHUB_HEAD_REF} = "dev" ]]; } || [[ ${GITHUB_HEAD_REF} == "patch" ]] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2fe7083 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,30 @@ +name: nf-core CI +# This workflow is triggered on pushes and PRs to the repository. +# It runs the pipeline with the minimal test dataset to check that it completes without any syntax errors +on: [push, pull_request] + +jobs: + test: + env: + NXF_VER: ${{ matrix.nxf_ver }} + NXF_ANSI_LOG: false + runs-on: ubuntu-latest + strategy: + matrix: + # Nextflow versions: check pipeline minimum and current latest + nxf_ver: ['19.10.0', ''] + steps: + - uses: actions/checkout@v2 + - name: Install Nextflow + run: | + wget -qO- get.nextflow.io | bash + sudo mv nextflow /usr/local/bin/ + - name: Pull docker image + run: | + docker pull nfcore/hic:dev + docker tag nfcore/hic:dev nfcore/hic:dev + - name: Run pipeline with test data + run: | + # TODO nf-core: You can customise CI pipeline run tests as required + # (eg. adding multiple test runs with different parameters) + nextflow run ${GITHUB_WORKSPACE} -profile test,docker diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml new file mode 100644 index 0000000..1e0827a --- /dev/null +++ b/.github/workflows/linting.yml @@ -0,0 +1,50 @@ +name: nf-core linting +# This workflow is triggered on pushes and PRs to the repository. +# It runs the `nf-core lint` and markdown lint tests to ensure that the code meets the nf-core guidelines +on: + push: + pull_request: + release: + types: [published] + +jobs: + Markdown: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: '10' + - name: Install markdownlint + run: npm install -g markdownlint-cli + - name: Run Markdownlint + run: markdownlint ${GITHUB_WORKSPACE} -c ${GITHUB_WORKSPACE}/.github/markdownlint.yml + YAML: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: '10' + - name: Install yaml-lint + run: npm install -g yaml-lint + - name: Run yaml-lint + run: yamllint $(find ${GITHUB_WORKSPACE} -type f -name "*.yml") + nf-core: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install Nextflow + run: | + wget -qO- get.nextflow.io | bash + sudo mv nextflow /usr/local/bin/ + - uses: actions/setup-python@v1 + with: + python-version: '3.6' + architecture: 'x64' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install nf-core + - name: Run nf-core lint + run: nf-core lint ${GITHUB_WORKSPACE} diff --git a/.gitignore b/.gitignore index 46f69e4..6354f37 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ work/ data/ results/ .DS_Store -tests/test_data +tests/ +testing/ +*.pyc diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 381c4cf..0000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -sudo: required -language: python -jdk: openjdk8 -services: docker -python: '3.6' -cache: pip -matrix: - fast_finish: true - -before_install: - # PRs to master are only ok if coming from dev branch - - '[ $TRAVIS_PULL_REQUEST = "false" ] || [ $TRAVIS_BRANCH != "master" ] || ([ $TRAVIS_PULL_REQUEST_SLUG = $TRAVIS_REPO_SLUG ] && [ $TRAVIS_PULL_REQUEST_BRANCH = "dev" ])' - # Pull the docker image first so the test doesn't wait for this - - docker pull nfcore/hic:dev - # Fake the tag locally so that the pipeline runs properly - - docker tag nfcore/hic:dev nfcore/hic:latest - -install: - # Install Nextflow - - mkdir /tmp/nextflow && cd /tmp/nextflow - - wget -qO- get.nextflow.io | bash - - sudo ln -s /tmp/nextflow/nextflow /usr/local/bin/nextflow - # Install nf-core/tools - - pip install --upgrade pip - - pip install nf-core - # Reset - - mkdir ${TRAVIS_BUILD_DIR}/tests && cd ${TRAVIS_BUILD_DIR}/tests - -env: - - NXF_VER='0.32.0' # Specify a minimum NF version that should be tested and work - - NXF_VER='' # Plus: get the latest NF version and check that it works - -script: - # Lint the pipeline code - - nf-core lint ${TRAVIS_BUILD_DIR} - # Run the pipeline with the test profile - - nextflow run ${TRAVIS_BUILD_DIR} -profile test,docker diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b88e32..7566331 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,16 @@ # nf-core/hic: Changelog -## v1.0dev - +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## v1.1.1dev - [date] + Initial release of nf-core/hic, created with the [nf-core](http://nf-co.re/) template. + +### `Added` + +### `Fixed` + +### `Dependencies` + +### `Deprecated` diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 2109619..cf930c8 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team on the [Gitter channel](https://gitter.im/nf-core/Lobby). The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team on [Slack](https://nf-co.re/join/slack). The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. diff --git a/Dockerfile b/Dockerfile index 4d28385..2c53847 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,13 @@ -FROM nfcore/base +FROM nfcore/base:1.9 LABEL authors="Nicolas Servant" \ - description="Docker image containing all requirements for nf-core/hic pipeline" + description="Docker image containing all software requirements for the nf-core/hic pipeline" +# Install the conda environment COPY environment.yml / RUN conda env create -f /environment.yml && conda clean -a -ENV PATH /opt/conda/envs/nf-core-hic-1.0dev/bin:$PATH + +# Add conda installation dir to PATH (instead of doing 'conda activate') +ENV PATH /opt/conda/envs/nf-core-hic-1.1.1dev/bin:$PATH + +# Dump the details of the installed packages to a file for posterity +RUN conda env export --name nf-core-hic-1.1.1dev > nf-core-hic-1.1.1dev.yml diff --git a/README.md b/README.md index 192fa0d..51bef77 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,77 @@ -# nf-core/hic -**Analysis of Chromosome Conformation Capture data (Hi-C)** +# ![nf-core/hic](docs/images/nf-core-hic_logo.png) -[![Build Status](https://travis-ci.org/nf-core/hic.svg?branch=master)](https://travis-ci.org/nf-core/hic) -[![Nextflow](https://img.shields.io/badge/nextflow-%E2%89%A50.32.0-brightgreen.svg)](https://www.nextflow.io/) +**Analysis of Chromosome Conformation Capture data (Hi-C)**. + +[![GitHub Actions CI Status](https://github.com/nf-core/hic/workflows/nf-core%20CI/badge.svg)](https://github.com/nf-core/hic/actions) +[![GitHub Actions Linting Status](https://github.com/nf-core/hic/workflows/nf-core%20linting/badge.svg)](https://github.com/nf-core/hic/actions) +[![Nextflow](https://img.shields.io/badge/nextflow-%E2%89%A519.10.0-brightgreen.svg)](https://www.nextflow.io/) [![install with bioconda](https://img.shields.io/badge/install%20with-bioconda-brightgreen.svg)](http://bioconda.github.io/) [![Docker](https://img.shields.io/docker/automated/nfcore/hic.svg)](https://hub.docker.com/r/nfcore/hic) -![Singularity Container available]( -https://img.shields.io/badge/singularity-available-7E4C74.svg) -### Introduction -The pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It comes with docker / singularity containers making installation trivial and results highly reproducible. +## Introduction + +The pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It comes with docker containers making installation trivial and results highly reproducible. + +## Quick Start + +i. Install [`nextflow`](https://nf-co.re/usage/installation) + +ii. Install either [`Docker`](https://docs.docker.com/engine/installation/) or [`Singularity`](https://www.sylabs.io/guides/3.0/user-guide/) for full pipeline reproducibility (please only use [`Conda`](https://conda.io/miniconda.html) as a last resort; see [docs](https://nf-co.re/usage/configuration#basic-configuration-profiles)) + +iii. Download the pipeline and test it on a minimal dataset with a single command + +```bash +nextflow run nf-core/hic -profile test, +``` + +> Please check [nf-core/configs](https://github.com/nf-core/configs#documentation) to see if a custom config file to run nf-core pipelines already exists for your Institute. If so, you can simply use `-profile ` in your command. This will enable either `docker` or `singularity` and set the appropriate execution settings for your local compute environment. + +iv. Start running your own analysis! + + +```bash +nextflow run nf-core/hic -profile --reads '*_R{1,2}.fastq.gz' --genome GRCh37 +``` + +See [usage docs](docs/usage.md) for all of the available options when running the pipeline. + +## Documentation -### Documentation The nf-core/hic pipeline comes with documentation about the pipeline, found in the `docs/` directory: -1. [Installation](docs/installation.md) +1. [Installation](https://nf-co.re/usage/installation) 2. Pipeline configuration - * [Local installation](docs/configuration/local.md) - * [Adding your own system](docs/configuration/adding_your_own.md) - * [Reference genomes](docs/configuration/reference_genomes.md) + * [Local installation](https://nf-co.re/usage/local_installation) + * [Adding your own system config](https://nf-co.re/usage/adding_own_config) + * [Reference genomes](https://nf-co.re/usage/reference_genomes) 3. [Running the pipeline](docs/usage.md) 4. [Output and how to interpret the results](docs/output.md) -5. [Troubleshooting](docs/troubleshooting.md) +5. [Troubleshooting](https://nf-co.re/usage/troubleshooting) -### Credits +## Credits + nf-core/hic was originally written by Nicolas Servant. + +## Contributions and Support + +If you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md). + +For further information or help, don't hesitate to get in touch on [Slack](https://nfcore.slack.com/channels/hic) (you can join with [this invite](https://nf-co.re/join/slack)). + +## Citation + + + + +You can cite the `nf-core` publication as follows: + +> **The nf-core framework for community-curated bioinformatics pipelines.** +> +> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen. +> +> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x). +> ReadCube: [Full Access Link](https://rdcu.be/b1GjZ) diff --git a/Singularity b/Singularity deleted file mode 100644 index 927866f..0000000 --- a/Singularity +++ /dev/null @@ -1,18 +0,0 @@ -From:nfcore/base -Bootstrap:docker - -%labels - MAINTAINER Nicolas Servant - DESCRIPTION Singularity image containing all requirements for the nf-core/hic pipeline - VERSION 1.0dev - -%environment - PATH=/opt/conda/envs/nf-core-hic-1.0dev/bin:$PATH - export PATH - -%files - environment.yml / - -%post - /opt/conda/bin/conda env create -f /environment.yml - /opt/conda/bin/conda clean -a diff --git a/assets/email_template.html b/assets/email_template.html index bf19807..177bccd 100644 --- a/assets/email_template.html +++ b/assets/email_template.html @@ -11,6 +11,8 @@
+ +

nf-core/hic v${version}

Run Name: $runName

diff --git a/assets/email_template.txt b/assets/email_template.txt index 59d7b54..a951c5e 100644 --- a/assets/email_template.txt +++ b/assets/email_template.txt @@ -1,6 +1,12 @@ -======================================== - nf-core/hic v${version} -======================================== +---------------------------------------------------- + ,--./,-. + ___ __ __ __ ___ /,-._.--~\\ + |\\ | |__ __ / ` / \\ |__) |__ } { + | \\| | \\__, \\__/ | \\ |___ \\`-._,-`-, + `._,._,' + nf-core/hic v${version} +---------------------------------------------------- + Run Name: $runName <% if (success){ @@ -17,23 +23,6 @@ ${errorReport} } %> -<% if (!success){ - out << """#################################################### -## nf-core/hic execution completed unsuccessfully! ## -#################################################### -The exit status of the task that caused the workflow execution to fail was: $exitStatus. -The full error message was: - -${errorReport} -""" -} else { - out << "## nf-core/hic execution completed successfully! ##" -} -%> - - - - The workflow was completed at $dateComplete (duration: $duration) The command used to launch the workflow was as follows: diff --git a/conf/multiqc_config.yaml b/assets/multiqc_config.yaml similarity index 79% rename from conf/multiqc_config.yaml rename to assets/multiqc_config.yaml index f2a738c..41468ca 100644 --- a/conf/multiqc_config.yaml +++ b/assets/multiqc_config.yaml @@ -3,5 +3,9 @@ report_comment: > analysis pipeline. For information about how to interpret these results, please see the documentation. report_section_order: - nf-core/hic-software-versions: + software_versions: order: -1000 + nf-core-hic-summary: + order: -1001 + +export_plots: true diff --git a/assets/nf-core-hic_logo.png b/assets/nf-core-hic_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6b364161664e70224fac3a83fb9f02ed0acbd9f8 GIT binary patch literal 10282 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 literal 0 HcmV?d00001 diff --git a/assets/sendmail_template.txt b/assets/sendmail_template.txt index fd1cd73..9afc480 100644 --- a/assets/sendmail_template.txt +++ b/assets/sendmail_template.txt @@ -1,11 +1,53 @@ To: $email Subject: $subject Mime-Version: 1.0 -Content-Type: multipart/related;boundary="nfmimeboundary" +Content-Type: multipart/related;boundary="nfcoremimeboundary" ---nfmimeboundary +--nfcoremimeboundary Content-Type: text/html; charset=utf-8 $email_html ---nfmimeboundary-- +--nfcoremimeboundary +Content-Type: image/png;name="nf-core-hic_logo.png" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: inline; filename="nf-core-hic_logo.png" + +<% out << new File("$baseDir/assets/nf-core-hic_logo.png"). + bytes. + encodeBase64(). + toString(). + tokenize( '\n' )*. + toList()*. + collate( 76 )*. + collect { it.join() }. + flatten(). + join( '\n' ) %> + +<% +if (mqcFile){ +def mqcFileObj = new File("$mqcFile") +if (mqcFileObj.length() < mqcMaxSize){ +out << """ +--nfcoremimeboundary +Content-Type: text/html; name=\"multiqc_report\" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: attachment; filename=\"${mqcFileObj.getName()}\" + +${mqcFileObj. + bytes. + encodeBase64(). + toString(). + tokenize( '\n' )*. + toList()*. + collate( 76 )*. + collect { it.join() }. + flatten(). + join( '\n' )} +""" +}} +%> + +--nfcoremimeboundary-- diff --git a/bin/__pycache__/scrape_software_versions.cpython-36.pyc b/bin/__pycache__/scrape_software_versions.cpython-36.pyc deleted file mode 100644 index 07062ad2b5afae9e2bc03e055e9776da9b619a1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1324 zcmZ`&OONA35bjPKkK-is$Ua~%$O=fAh)FE8Xe9=31ez5$28NN?l{LunxGRY>9k-{u zoy}y(DHm@10nSL=`6--y<+OhRaiHuZ(n{>M<*Lu+dVE#g{j}Axf9W4xt!jk)P2O4! z#9!g7{zbtEqnymBPicWGyfUl$)e={^;Tz0gwQ+@+rQBl{;ySZYHhwew8dTTBH(3)* z*78WH_qY0Bs}DW0xPsbrZ%tm1pT57U_?BM>8|sWaA#3{UGrs|iX%q9bz?kl%{pbmS z*1F;!z=8aewWo)0Fg;>NYr3Xjg5{BygjFxd59AfOO{CqQ~M-%n+n=wOs3k&Z=zmd1CIfduv?7^$p^SGiSbWZq0*P#&x{?`*{0t z;>U{6pBICu`vg@fdOdO@} zI6Ut}f(v>2@fYR#vNJq)zxLe1VffzU(!fbbJSs$*DBe&M%j*1o6?zEmn4LP^ckvov z?;wwR0|_Y)BRK9l-4mzV@Ai;!Ux|@^9ZKkLdsJOpK{?`}XzD#VG19r*Mmj%krt?%+V8YcC9!f(`lv$m?G5Ssq?e#;PM!EA|5LByu)~ZB4oT2i4J*Z zXfHo19E#;JJ-lCeE-H_)4P?V*z5M4gKI}d4?Ep`q&LjkZtl%ExjV&)Es${jWR3!L& z62`CqRRD!&K;^Yq!%XG$Ca3e<5Gf=%UF3#@koneb{JE(hl+h%w%|eaJ90`diuZ^Y1 z(!5q)gFlFTgmp^s&+qPaEaGG&TrQ%JyVqIFnR^C_7RrTWu7XG;EOe7mKN86Lv%%*s zkFVYIPESPgbnwhoNUWcR(M>o8g?< + + + + + +
+ """ + footer = """ +
+ + + """ + return header + contents + footer + + +def parse_args(args=None): + parser = argparse.ArgumentParser() + parser.add_argument('mdfile', type=argparse.FileType('r'), nargs='?', + help='File to convert. Defaults to stdin.') + parser.add_argument('-o', '--out', type=argparse.FileType('w'), + default=sys.stdout, + help='Output file name. Defaults to stdout.') + return parser.parse_args(args) + +def main(args=None): + args = parse_args(args) + converted_md = convert_markdown(args.mdfile.name) + html = wrap_html(converted_md) + args.out.write(html) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/bin/markdown_to_html.r b/bin/markdown_to_html.r deleted file mode 100755 index abe1335..0000000 --- a/bin/markdown_to_html.r +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env Rscript - -# Command line argument processing -args = commandArgs(trailingOnly=TRUE) -if (length(args) < 2) { - stop("Usage: markdown_to_html.r ", call.=FALSE) -} -markdown_fn <- args[1] -output_fn <- args[2] - -# Load / install packages -if (!require("markdown")) { - install.packages("markdown", dependencies=TRUE, repos='http://cloud.r-project.org/') - library("markdown") -} - -base_css_fn <- getOption("markdown.HTML.stylesheet") -base_css <- readChar(base_css_fn, file.info(base_css_fn)$size) -custom_css <- paste(base_css, " -body { - padding: 3em; - margin-right: 350px; - max-width: 100%; -} -#toc { - position: fixed; - right: 20px; - width: 300px; - padding-top: 20px; - overflow: scroll; - height: calc(100% - 3em - 20px); -} -#toc_header { - font-size: 1.8em; - font-weight: bold; -} -#toc > ul { - padding-left: 0; - list-style-type: none; -} -#toc > ul ul { padding-left: 20px; } -#toc > ul > li > a { display: none; } -img { max-width: 800px; } -") - -markdownToHTML( - file = markdown_fn, - output = output_fn, - stylesheet = custom_css, - options = c('toc', 'base64_images', 'highlight_code') -) diff --git a/bin/scrape_software_versions.py b/bin/scrape_software_versions.py index 0e98e07..0cdb86e 100755 --- a/bin/scrape_software_versions.py +++ b/bin/scrape_software_versions.py @@ -18,15 +18,23 @@ # Search each file using its regex for k, v in regexes.items(): - with open(v[0]) as x: - versions = x.read() - match = re.search(v[1], versions) - if match: - results[k] = "v{}".format(match.group(1)) + try: + with open(v[0]) as x: + versions = x.read() + match = re.search(v[1], versions) + if match: + results[k] = "v{}".format(match.group(1)) + except IOError: + results[k] = False + +# Remove software set to false in results +for k in list(results): + if not results[k]: + del(results[k]) # Dump to YAML print (''' -id: 'nf-core/hic-software-versions' +id: 'software_versions' section_name: 'nf-core/hic Software Versions' section_href: 'https://github.com/nf-core/hic' plot_type: 'html' @@ -35,5 +43,10 @@
''') for k,v in results.items(): - print("
{}
{}
".format(k,v)) + print("
{}
{}
".format(k,v)) print ("
") + +# Write out regexes as csv file: +with open('software_versions.csv', 'w') as f: + for k,v in results.items(): + f.write("{}\t{}\n".format(k,v)) diff --git a/conf/awsbatch.config b/conf/awsbatch.config deleted file mode 100644 index 79078c7..0000000 --- a/conf/awsbatch.config +++ /dev/null @@ -1,13 +0,0 @@ -/* - * ------------------------------------------------- - * Nextflow config file for AWS Batch - * ------------------------------------------------- - * Imported under the 'awsbatch' Nextflow profile in nextflow.config - * Uses docker for software depedencies automagically, so not specified here. - */ - -aws.region = params.awsregion -process.executor = 'awsbatch' -process.queue = params.awsqueue -executor.awscli = '/home/ec2-user/miniconda/bin/aws' -params.tracedir = './' diff --git a/conf/base.config b/conf/base.config index 23c9e4a..0b2ea22 100644 --- a/conf/base.config +++ b/conf/base.config @@ -11,31 +11,41 @@ process { - container = params.container - // TODO nf-core: Check the defaults for all processes cpus = { check_max( 1 * task.attempt, 'cpus' ) } - memory = { check_max( 8.GB * task.attempt, 'memory' ) } - time = { check_max( 2.h * task.attempt, 'time' ) } + memory = { check_max( 7.GB * task.attempt, 'memory' ) } + time = { check_max( 4.h * task.attempt, 'time' ) } - errorStrategy = { task.exitStatus in [143,137] ? 'retry' : 'finish' } + errorStrategy = { task.exitStatus in [143,137,104,134,139] ? 'retry' : 'finish' } maxRetries = 1 maxErrors = '-1' // Process-specific resource requirements - // TODO nf-core: Customise requirements for specific processes - withName: fastqc { - errorStrategy = { task.exitStatus in [143,137] ? 'retry' : 'ignore' } + // NOTE - Only one of the labels below are used in the fastqc process in the main script. + // If possible, it would be nice to keep the same label naming convention when + // adding in your processes. + // TODO nf-core: Customise requirements for specific processes. + // See https://www.nextflow.io/docs/latest/config.html#config-process-selectors + withLabel:process_low { + cpus = { check_max( 2 * task.attempt, 'cpus' ) } + memory = { check_max( 14.GB * task.attempt, 'memory' ) } + time = { check_max( 6.h * task.attempt, 'time' ) } } - withName: multiqc { - errorStrategy = { task.exitStatus in [143,137] ? 'retry' : 'ignore' } + withLabel:process_medium { + cpus = { check_max( 6 * task.attempt, 'cpus' ) } + memory = { check_max( 42.GB * task.attempt, 'memory' ) } + time = { check_max( 8.h * task.attempt, 'time' ) } } -} - -params { - // Defaults only, expecting to be overwritten - max_memory = 128.GB - max_cpus = 16 - max_time = 240.h - igenomes_base = 's3://ngi-igenomes/igenomes/' + withLabel:process_high { + cpus = { check_max( 12 * task.attempt, 'cpus' ) } + memory = { check_max( 84.GB * task.attempt, 'memory' ) } + time = { check_max( 10.h * task.attempt, 'time' ) } + } + withLabel:process_long { + time = { check_max( 20.h * task.attempt, 'time' ) } + } + withName:get_software_versions { + cache = false + } + } diff --git a/conf/igenomes.config b/conf/igenomes.config index d19e61f..2de9242 100644 --- a/conf/igenomes.config +++ b/conf/igenomes.config @@ -9,139 +9,412 @@ params { // illumina iGenomes reference file paths - // TODO nf-core: Add new reference types and strip out those that are not needed genomes { 'GRCh37' { - bed12 = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/README.txt" + mito_name = "MT" + macs_gsize = "2.7e9" + blacklist = "${baseDir}/assets/blacklists/GRCh37-blacklist.bed" + } + 'GRCh38' { + fasta = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.bed" + mito_name = "chrM" + macs_gsize = "2.7e9" + blacklist = "${baseDir}/assets/blacklists/hg38-blacklist.bed" } 'GRCm38' { - bed12 = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/README.txt" + mito_name = "MT" + macs_gsize = "1.87e9" + blacklist = "${baseDir}/assets/blacklists/GRCm38-blacklist.bed" } 'TAIR10' { - bed12 = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/README.txt" + mito_name = "Mt" } 'EB2' { - bed12 = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/README.txt" } 'UMD3.1' { - bed12 = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/README.txt" + mito_name = "MT" } 'WBcel235' { - bed12 = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.bed" + mito_name = "MtDNA" + macs_gsize = "9e7" } 'CanFam3.1' { - bed12 = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/README.txt" + mito_name = "MT" } 'GRCz10' { - bed12 = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.bed" + mito_name = "MT" } 'BDGP6' { - bed12 = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.bed" + mito_name = "M" + macs_gsize = "1.2e8" } 'EquCab2' { - bed12 = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/README.txt" + mito_name = "MT" } 'EB1' { - bed12 = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/README.txt" } 'Galgal4' { - bed12 = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.bed" + mito_name = "MT" } 'Gm01' { - bed12 = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/README.txt" } 'Mmul_1' { - bed12 = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/README.txt" + mito_name = "MT" } 'IRGSP-1.0' { - bed12 = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.bed" + mito_name = "Mt" } 'CHIMP2.1.4' { - bed12 = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/README.txt" + mito_name = "MT" } 'Rnor_6.0' { - bed12 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.bed" + mito_name = "MT" } 'R64-1-1' { - bed12 = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.bed" + mito_name = "MT" + macs_gsize = "1.2e7" } 'EF2' { - bed12 = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/README.txt" + mito_name = "MT" + macs_gsize = "1.21e7" } 'Sbi1' { - bed12 = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/README.txt" } 'Sscrofa10.2' { - bed12 = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/README.txt" + mito_name = "MT" } 'AGPv3' { - bed12 = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.bed" - fasta = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.gtf" - star = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/STARIndex/" + fasta = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.bed" + mito_name = "Mt" + } + 'hg38' { + fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.bed" + mito_name = "chrM" + macs_gsize = "2.7e9" + blacklist = "${baseDir}/assets/blacklists/hg38-blacklist.bed" + } + 'hg19' { + fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/README.txt" + mito_name = "chrM" + macs_gsize = "2.7e9" + blacklist = "${baseDir}/assets/blacklists/hg19-blacklist.bed" + } + 'mm10' { + fasta = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/README.txt" + mito_name = "chrM" + macs_gsize = "1.87e9" + blacklist = "${baseDir}/assets/blacklists/mm10-blacklist.bed" + } + 'bosTau8' { + fasta = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.bed" + mito_name = "chrM" + } + 'ce10' { + fasta = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/README.txt" + mito_name = "chrM" + macs_gsize = "9e7" + } + 'canFam3' { + fasta = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/README.txt" + mito_name = "chrM" + } + 'danRer10' { + fasta = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.bed" + mito_name = "chrM" + } + 'dm6' { + fasta = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.bed" + mito_name = "chrM" + macs_gsize = "1.2e8" + } + 'equCab2' { + fasta = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/README.txt" + mito_name = "chrM" + } + 'galGal4' { + fasta = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/README.txt" + mito_name = "chrM" + } + 'panTro4' { + fasta = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/README.txt" + mito_name = "chrM" + } + 'rn6' { + fasta = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.bed" + mito_name = "chrM" + } + 'sacCer3' { + fasta = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BismarkIndex/" + readme = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Annotation/README.txt" + mito_name = "chrM" + macs_gsize = "1.2e7" + } + 'susScr3' { + fasta = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BWAIndex/genome.fa" + bowtie2 = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/Bowtie2Index/" + star = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/README.txt" + mito_name = "chrM" } } } diff --git a/conf/test.config b/conf/test.config index a03678b..4cd7b5f 100644 --- a/conf/test.config +++ b/conf/test.config @@ -4,18 +4,21 @@ * ------------------------------------------------- * Defines bundled input files and everything required * to run a fast and simple test. Use as follows: - * nextflow run nf-core/hic -profile test + * nextflow run nf-core/hic -profile test, */ params { - // Limit resources so that this can run on Travis + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + // Limit resources so that this can run on GitHub Actions max_cpus = 2 max_memory = 6.GB max_time = 48.h + // Input data // TODO nf-core: Specify the paths to your test data on nf-core/test-datasets // TODO nf-core: Give any required params for the test so that command line flags are not needed - singleEnd = false + single_end = false readPaths = [ ['Testdata', ['https://github.com/nf-core/test-datasets/raw/exoseq/testdata/Testdata_R1.tiny.fastq.gz', 'https://github.com/nf-core/test-datasets/raw/exoseq/testdata/Testdata_R2.tiny.fastq.gz']], ['SRR389222', ['https://github.com/nf-core/test-datasets/raw/methylseq/testdata/SRR389222_sub1.fastq.gz', 'https://github.com/nf-core/test-datasets/raw/methylseq/testdata/SRR389222_sub2.fastq.gz']] diff --git a/docs/README.md b/docs/README.md index d7dbdac..e160867 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,11 +2,11 @@ The nf-core/hic documentation is split into the following files: -1. [Installation](installation.md) +1. [Installation](https://nf-co.re/usage/installation) 2. Pipeline configuration - * [Local installation](configuration/local.md) - * [Adding your own system](configuration/adding_your_own.md) - * [Reference genomes](configuration/reference_genomes.md) + * [Local installation](https://nf-co.re/usage/local_installation) + * [Adding your own system config](https://nf-co.re/usage/adding_own_config) + * [Reference genomes](https://nf-co.re/usage/reference_genomes) 3. [Running the pipeline](usage.md) 4. [Output and how to interpret the results](output.md) -5. [Troubleshooting](troubleshooting.md) +5. [Troubleshooting](https://nf-co.re/usage/troubleshooting) diff --git a/docs/configuration/adding_your_own.md b/docs/configuration/adding_your_own.md deleted file mode 100644 index bf7f808..0000000 --- a/docs/configuration/adding_your_own.md +++ /dev/null @@ -1,86 +0,0 @@ -# nf-core/hic: Configuration for other clusters - -It is entirely possible to run this pipeline on other clusters, though you will need to set up your own config file so that the pipeline knows how to work with your cluster. - -> If you think that there are other people using the pipeline who would benefit from your configuration (eg. other common cluster setups), please let us know. We can add a new configuration and profile which can used by specifying `-profile ` when running the pipeline. The config file will then be hosted at `nf-core/configs` and will be pulled automatically before the pipeline is executed. - -If you are the only person to be running this pipeline, you can create your config file as `~/.nextflow/config` and it will be applied every time you run Nextflow. Alternatively, save the file anywhere and reference it when running the pipeline with `-c path/to/config` (see the [Nextflow documentation](https://www.nextflow.io/docs/latest/config.html) for more). - -A basic configuration comes with the pipeline, which loads the [`conf/base.config`](../../conf/base.config) by default. This means that you only need to configure the specifics for your system and overwrite any defaults that you want to change. - -## Cluster Environment -By default, pipeline uses the `local` Nextflow executor - in other words, all jobs are run in the login session. If you're using a simple server, this may be fine. If you're using a compute cluster, this is bad as all jobs will run on the head node. - -To specify your cluster environment, add the following line to your config file: - -```nextflow -process.executor = 'YOUR_SYSTEM_TYPE' -``` - -Many different cluster types are supported by Nextflow. For more information, please see the [Nextflow documentation](https://www.nextflow.io/docs/latest/executor.html). - -Note that you may need to specify cluster options, such as a project or queue. To do so, use the `clusterOptions` config option: - -```nextflow -process { - executor = 'SLURM' - clusterOptions = '-A myproject' -} -``` - - -## Software Requirements -To run the pipeline, several software packages are required. How you satisfy these requirements is essentially up to you and depends on your system. If possible, we _highly_ recommend using either Docker or Singularity. - -Please see the [`installation documentation`](../installation.md) for how to run using the below as a one-off. These instructions are about configuring a config file for repeated use. - -### Docker -Docker is a great way to run nf-core/hic, as it manages all software installations and allows the pipeline to be run in an identical software environment across a range of systems. - -Nextflow has [excellent integration](https://www.nextflow.io/docs/latest/docker.html) with Docker, and beyond installing the two tools, not much else is required - nextflow will automatically fetch the [nfcore/hic](https://hub.docker.com/r/nfcore/hic/) image that we have created and is hosted at dockerhub at run time. - -To add docker support to your own config file, add the following: - -```nextflow -docker.enabled = true -process.container = "nfcore/hic" -``` - -Note that the dockerhub organisation name annoyingly can't have a hyphen, so is `nfcore` and not `nf-core`. - - -### Singularity image -Many HPC environments are not able to run Docker due to security issues. -[Singularity](http://singularity.lbl.gov/) is a tool designed to run on such HPC systems which is very similar to Docker. - -To specify singularity usage in your pipeline config file, add the following: - -```nextflow -singularity.enabled = true -process.container = "shub://nf-core/hic" -``` - -If you intend to run the pipeline offline, nextflow will not be able to automatically download the singularity image for you. -Instead, you'll have to do this yourself manually first, transfer the image file and then point to that. - -First, pull the image file where you have an internet connection: - -```bash -singularity pull --name nf-core-hic.simg shub://nf-core/hic -``` - -Then transfer this file and point the config file to the image: - -```nextflow -singularity.enabled = true -process.container = "/path/to/nf-core-hic.simg" -``` - - -### Conda -If you're not able to use Docker or Singularity, you can instead use conda to manage the software requirements. -To use conda in your own config file, add the following: - -```nextflow -process.conda = "$baseDir/environment.yml" -``` diff --git a/docs/configuration/local.md b/docs/configuration/local.md deleted file mode 100644 index 657422f..0000000 --- a/docs/configuration/local.md +++ /dev/null @@ -1,46 +0,0 @@ -# nf-core/hic: Local Configuration - -If running the pipeline in a local environment, we highly recommend using either Docker or Singularity. - -## Docker -Docker is a great way to run `nf-core/hic`, as it manages all software installations and allows the pipeline to be run in an identical software environment across a range of systems. - -Nextflow has [excellent integration](https://www.nextflow.io/docs/latest/docker.html) with Docker, and beyond installing the two tools, not much else is required. The `nf-core/hic` profile comes with a configuration profile for docker, making it very easy to use. This also comes with the required presets to use the AWS iGenomes resource, meaning that if using common reference genomes you just specify the reference ID and it will be automatically downloaded from AWS S3. - -First, install docker on your system: [Docker Installation Instructions](https://docs.docker.com/engine/installation/) - -Then, simply run the analysis pipeline: -```bash -nextflow run nf-core/hic -profile docker --genome '' --design '' -``` - -Nextflow will recognise `nf-core/hic` and download the pipeline from GitHub. The `-profile docker` configuration lists the [nf-core/hic](https://hub.docker.com/r/nfcore/hic/) image that we have created and is hosted at dockerhub, and this is downloaded. - -For more information about how to work with reference genomes, see [`docs/configuration/reference_genomes.md`](reference_genomes.md). - -### Pipeline versions -The public docker images are tagged with the same version numbers as the code, which you can use to ensure reproducibility. When running the pipeline, specify the pipeline version with `-r`, for example `-r 1.0`. This uses pipeline code and docker image from this tagged version. - - -## Singularity image -Many HPC environments are not able to run Docker due to security issues. [Singularity](http://singularity.lbl.gov/) is a tool designed to run on such HPC systems which is very similar to Docker. Even better, it can use create images directly from dockerhub. - -To use the singularity image for a single run, use `-with-singularity`. This will download the docker container from dockerhub and create a singularity image for you dynamically. - -If you intend to run the pipeline offline, nextflow will not be able to automatically download the singularity image for you. Instead, you'll have to do this yourself manually first, transfer the image file and then point to that. - -First, pull the image file where you have an internet connection: - -> NB: The "tag" at the end of this command corresponds to the pipeline version. -> Here, we're pulling the docker image for version 1.0 of the nf-core/hic pipeline -> Make sure that this tag corresponds to the version of the pipeline that you're using - -```bash -singularity pull --name nf-core-hic-1.0.img docker://nf-core/hic:1.0 -``` - -Then transfer this file and run the pipeline with this path: - -```bash -nextflow run /path/to/nf-core-hic -with-singularity /path/to/nf-core-hic-1.0.img -``` diff --git a/docs/configuration/reference_genomes.md b/docs/configuration/reference_genomes.md deleted file mode 100644 index 1fafa8f..0000000 --- a/docs/configuration/reference_genomes.md +++ /dev/null @@ -1,49 +0,0 @@ -# nf-core/hic: Reference Genomes Configuration - -The nf-core/hic pipeline needs a reference genome for alignment and annotation. - -These paths can be supplied on the command line at run time (see the [usage docs](../usage.md)), -but for convenience it's often better to save these paths in a nextflow config file. -See below for instructions on how to do this. -Read [Adding your own system](adding_your_own.md) to find out how to set up custom config files. - -## Adding paths to a config file -Specifying long paths every time you run the pipeline is a pain. -To make this easier, the pipeline comes configured to understand reference genome keywords which correspond to preconfigured paths, meaning that you can just specify `--genome ID` when running the pipeline. - -Note that this genome key can also be specified in a config file if you always use the same genome. - -To use this system, add paths to your config file using the following template: - -```nextflow -params { - genomes { - 'YOUR-ID' { - fasta = '/genome.fa' - } - 'OTHER-GENOME' { - // [..] - } - } - // Optional - default genome. Ignored if --genome 'OTHER-GENOME' specified on command line - genome = 'YOUR-ID' -} -``` - -You can add as many genomes as you like as long as they have unique IDs. - -## illumina iGenomes -To make the use of reference genomes easier, illumina has developed a centralised resource called [iGenomes](https://support.illumina.com/sequencing/sequencing_software/igenome.html). -Multiple reference index types are held together with consistent structure for multiple genomes. - -We have put a copy of iGenomes up onto AWS S3 hosting and this pipeline is configured to use this by default. -The hosting fees for AWS iGenomes are currently kindly funded by a grant from Amazon. -The pipeline will automatically download the required reference files when you run the pipeline. -For more information about the AWS iGenomes, see https://ewels.github.io/AWS-iGenomes/ - -Downloading the files takes time and bandwidth, so we recommend making a local copy of the iGenomes resource. -Once downloaded, you can customise the variable `params.igenomes_base` in your custom configuration file to point to the reference location. -For example: -```nextflow -params.igenomes_base = '/path/to/data/igenomes/' -``` diff --git a/docs/images/nf-core-hic_logo.png b/docs/images/nf-core-hic_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e5fead372861ff430d7f1428e15dad9b045523e8 GIT binary patch literal 17777 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 ## Pipeline overview + The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes data using the following steps: @@ -12,6 +13,7 @@ and processes data using the following steps: * [MultiQC](#multiqc) - aggregate report, describing results of the whole pipeline ## FastQC + [FastQC](http://www.bioinformatics.babraham.ac.uk/projects/fastqc/) gives general quality metrics about your reads. It provides information about the quality score distribution across your reads, the per base sequence content (%T/A/G/C). You get information about adapter contamination and other overrepresented sequences. For further reading and documentation see the [FastQC help](http://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/). @@ -25,8 +27,8 @@ For further reading and documentation see the [FastQC help](http://www.bioinform * `zips/sample_fastqc.zip` * zip file containing the FastQC report, tab-delimited data file and plot images - ## MultiQC + [MultiQC](http://multiqc.info) is a visualisation tool that generates a single HTML report summarising all samples in your project. Most of the pipeline QC results are visualised in the report and further statistics are available in within the report data directory. The pipeline has special steps which allow the software versions used to be reported in the MultiQC output for future traceability. @@ -38,4 +40,4 @@ The pipeline has special steps which allow the software versions used to be repo * `Project_multiqc_data/` * Directory containing parsed statistics from the different tools used in the pipeline -For more information about how to use MultiQC reports, see http://multiqc.info +For more information about how to use MultiQC reports, see [http://multiqc.info](http://multiqc.info) diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md deleted file mode 100644 index 927d1b7..0000000 --- a/docs/troubleshooting.md +++ /dev/null @@ -1,30 +0,0 @@ -# nf-core/hic: Troubleshooting - - - -## Input files not found - -If only no file, only one input file , or only read one and not read two is picked up then something is wrong with your input file declaration - -1. The path must be enclosed in quotes (`'` or `"`) -2. The path must have at least one `*` wildcard character. This is even if you are only running one paired end sample. -3. When using the pipeline with paired end data, the path must use `{1,2}` or `{R1,R2}` notation to specify read pairs. -4. If you are running Single end data make sure to specify `--singleEnd` - -If the pipeline can't find your files then you will get the following error - -``` -ERROR ~ Cannot find any reads matching: *{1,2}.fastq.gz -``` - -Note that if your sample name is "messy" then you have to be very particular with your glob specification. A file name like `L1-1-D-2h_S1_L002_R1_001.fastq.gz` can be difficult enough for a human to read. Specifying `*{1,2}*.gz` wont work give you what you want Whilst `*{R1,R2}*.gz` will. - - -## Data organization -The pipeline can't take a list of multiple input files - it takes a glob expression. If your input files are scattered in different paths then we recommend that you generate a directory with symlinked files. If running in paired end mode please make sure that your files are sensibly named so that they can be properly paired. See the previous point. - -## Extra resources and getting help -If you still have an issue with running the pipeline then feel free to contact us. -Have a look at the [pipeline website](https://github.com/nf-core/hic) to find out how. - -If you have problems that are related to Nextflow and not our pipeline then check out the [Nextflow gitter channel](https://gitter.im/nextflow-io/nextflow) or the [google group](https://groups.google.com/forum/#!forum/nextflow). diff --git a/docs/usage.md b/docs/usage.md index 95d863f..00541b2 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -2,45 +2,45 @@ ## Table of contents -* [Introduction](#general-nextflow-info) +* [Table of contents](#table-of-contents) +* [Introduction](#introduction) * [Running the pipeline](#running-the-pipeline) -* [Updating the pipeline](#updating-the-pipeline) -* [Reproducibility](#reproducibility) + * [Updating the pipeline](#updating-the-pipeline) + * [Reproducibility](#reproducibility) * [Main arguments](#main-arguments) - * [`-profile`](#-profile-single-dash) - * [`awsbatch`](#awsbatch) - * [`conda`](#conda) - * [`docker`](#docker) - * [`singularity`](#singularity) - * [`test`](#test) - * [`--reads`](#--reads) - * [`--singleEnd`](#--singleend) + * [`-profile`](#-profile) + * [`--reads`](#--reads) + * [`--single_end`](#--single_end) * [Reference genomes](#reference-genomes) - * [`--genome`](#--genome) - * [`--fasta`](#--fasta) - * [`--igenomesIgnore`](#--igenomesignore) + * [`--genome` (using iGenomes)](#--genome-using-igenomes) + * [`--fasta`](#--fasta) + * [`--igenomes_ignore`](#--igenomes_ignore) * [Job resources](#job-resources) -* [Automatic resubmission](#automatic-resubmission) -* [Custom resource requests](#custom-resource-requests) -* [AWS batch specific parameters](#aws-batch-specific-parameters) - * [`-awsbatch`](#-awsbatch) - * [`--awsqueue`](#--awsqueue) - * [`--awsregion`](#--awsregion) + * [Automatic resubmission](#automatic-resubmission) + * [Custom resource requests](#custom-resource-requests) +* [AWS Batch specific parameters](#aws-batch-specific-parameters) + * [`--awsqueue`](#--awsqueue) + * [`--awsregion`](#--awsregion) + * [`--awscli`](#--awscli) * [Other command line parameters](#other-command-line-parameters) - * [`--outdir`](#--outdir) - * [`--email`](#--email) - * [`-name`](#-name-single-dash) - * [`-resume`](#-resume-single-dash) - * [`-c`](#-c-single-dash) - * [`--custom_config_version`](#--custom_config_version) - * [`--max_memory`](#--max_memory) - * [`--max_time`](#--max_time) - * [`--max_cpus`](#--max_cpus) - * [`--plaintext_email`](#--plaintext_email) - * [`--multiqc_config`](#--multiqc_config) - - -## General Nextflow info + * [`--outdir`](#--outdir) + * [`--email`](#--email) + * [`--email_on_fail`](#--email_on_fail) + * [`--max_multiqc_email_size`](#--max_multiqc_email_size) + * [`-name`](#-name) + * [`-resume`](#-resume) + * [`-c`](#-c) + * [`--custom_config_version`](#--custom_config_version) + * [`--custom_config_base`](#--custom_config_base) + * [`--max_memory`](#--max_memory) + * [`--max_time`](#--max_time) + * [`--max_cpus`](#--max_cpus) + * [`--plaintext_email`](#--plaintext_email) + * [`--monochrome_logs`](#--monochrome_logs) + * [`--multiqc_config`](#--multiqc_config) + +## Introduction + Nextflow handles job submissions on SLURM or other environments, and supervises running the jobs. Thus the Nextflow process must run until the pipeline is finished. We recommend that you put the process running in the background through `screen` / `tmux` or similar tool. Alternatively you can run nextflow within a cluster job submitted your job scheduler. It is recommended to limit the Nextflow Java virtual machines memory. We recommend adding the following line to your environment (typically in `~/.bashrc` or `~./bash_profile`): @@ -48,9 +48,13 @@ It is recommended to limit the Nextflow Java virtual machines memory. We recomme ```bash NXF_OPTS='-Xms1g -Xmx4g' ``` + + ## Running the pipeline + The typical command for running the pipeline is as follows: + ```bash nextflow run nf-core/hic --reads '*_R{1,2}.fastq.gz' -profile docker ``` @@ -67,6 +71,7 @@ results # Finished results (configurable, see below) ``` ### Updating the pipeline + When you run the above command, Nextflow automatically pulls the pipeline code from GitHub and stores it as a cached version. When running the pipeline after this, it will always use the cached version if available - even if the pipeline has been updated since. To make sure that you're running the latest version of the pipeline, make sure that you regularly update the cached version of the pipeline: ```bash @@ -74,37 +79,48 @@ nextflow pull nf-core/hic ``` ### Reproducibility + It's a good idea to specify a pipeline version when running the pipeline on your data. This ensures that a specific version of the pipeline code and software are used when you run your pipeline. If you keep using the same tag, you'll be running the same version of the pipeline, even if there have been changes to the code since. First, go to the [nf-core/hic releases page](https://github.com/nf-core/hic/releases) and find the latest version number - numeric only (eg. `1.3.1`). Then specify this when running the pipeline with `-r` (one hyphen) - eg. `-r 1.3.1`. This version number will be logged in reports when you run the pipeline, so that you'll know what you used when you look back in the future. - ## Main arguments ### `-profile` -Use this parameter to choose a configuration profile. Profiles can give configuration presets for different compute environments. Note that multiple profiles can be loaded, for example: `-profile docker` - the order of arguments is important! -If `-profile` is not specified at all the pipeline will be run locally and expects all software to be installed and available on the `PATH`. +Use this parameter to choose a configuration profile. Profiles can give configuration presets for different compute environments. + +Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Conda) - see below. + +> We highly recommend the use of Docker or Singularity containers for full pipeline reproducibility, however when this is not possible, Conda is also supported. + +The pipeline also dynamically loads configurations from [https://github.com/nf-core/configs](https://github.com/nf-core/configs) when it runs, making multiple config profiles for various institutional clusters available at run time. For more information and to see if your system is available in these configs please see the [nf-core/configs documentation](https://github.com/nf-core/configs#documentation). + +Note that multiple profiles can be loaded, for example: `-profile test,docker` - the order of arguments is important! +They are loaded in sequence, so later profiles can overwrite earlier profiles. + +If `-profile` is not specified, the pipeline will run locally and expect all software to be installed and available on the `PATH`. This is _not_ recommended. -* `awsbatch` - * A generic configuration profile to be used with AWS Batch. -* `conda` - * A generic configuration profile to be used with [conda](https://conda.io/docs/) - * Pulls most software from [Bioconda](https://bioconda.github.io/) * `docker` - * A generic configuration profile to be used with [Docker](http://docker.com/) - * Pulls software from dockerhub: [`nfcore/hic`](http://hub.docker.com/r/nfcore/hic/) + * A generic configuration profile to be used with [Docker](http://docker.com/) + * Pulls software from dockerhub: [`nfcore/hic`](http://hub.docker.com/r/nfcore/hic/) * `singularity` - * A generic configuration profile to be used with [Singularity](http://singularity.lbl.gov/) - * Pulls software from singularity-hub + * A generic configuration profile to be used with [Singularity](http://singularity.lbl.gov/) + * Pulls software from DockerHub: [`nfcore/hic`](http://hub.docker.com/r/nfcore/hic/) +* `conda` + * Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker or Singularity. + * A generic configuration profile to be used with [Conda](https://conda.io/docs/) + * Pulls most software from [Bioconda](https://bioconda.github.io/) * `test` - * A profile with a complete configuration for automated testing - * Includes links to test data so needs no other parameters + * A profile with a complete configuration for automated testing + * Includes links to test data so needs no other parameters + ### `--reads` + Use this to specify the location of your input FastQ files. For example: ```bash @@ -119,21 +135,22 @@ Please note the following requirements: If left unspecified, a default pattern is used: `data/*{1,2}.fastq.gz` -### `--singleEnd` -By default, the pipeline expects paired-end data. If you have single-end data, you need to specify `--singleEnd` on the command line when you launch the pipeline. A normal glob pattern, enclosed in quotation marks, can then be used for `--reads`. For example: +### `--single_end` + +By default, the pipeline expects paired-end data. If you have single-end data, you need to specify `--single_end` on the command line when you launch the pipeline. A normal glob pattern, enclosed in quotation marks, can then be used for `--reads`. For example: ```bash ---singleEnd --reads '*.fastq' +--single_end --reads '*.fastq' ``` It is not possible to run a mixture of single-end and paired-end files in one run. - ## Reference genomes The pipeline config files come bundled with paths to the illumina iGenomes reference index files. If running with docker or AWS, the configuration is set up to use the [AWS-iGenomes](https://ewels.github.io/AWS-iGenomes/) resource. ### `--genome` (using iGenomes) + There are 31 different species supported in the iGenomes references. To run the pipeline, you must specify which to use with the `--genome` flag. You can find the keys to specify the genomes in the [iGenomes config file](../conf/igenomes.config). Common genomes that are supported are: @@ -154,6 +171,7 @@ Note that you can use the same configuration setup to save sets of reference fil The syntax for this reference configuration is as follows: + ```nextflow params { genomes { @@ -166,33 +184,48 @@ params { ``` + ### `--fasta` + If you prefer, you can specify the full path to your reference genome when you run the pipeline: ```bash --fasta '[path to Fasta reference]' ``` -### `--igenomesIgnore` +### `--igenomes_ignore` + Do not load `igenomes.config` when running the pipeline. You may choose this option if you observe clashes between custom parameters and those supplied in `igenomes.config`. ## Job resources + ### Automatic resubmission + Each step in the pipeline has a default set of requirements for number of CPUs, memory and time. For most of the steps in the pipeline, if the job exits with an error code of `143` (exceeded requested resources) it will automatically resubmit with higher requests (2 x original, then 3 x original). If it still fails after three times then the pipeline is stopped. ### Custom resource requests + Wherever process-specific requirements are set in the pipeline, the default value can be changed by creating a custom config file. See the files hosted at [`nf-core/configs`](https://github.com/nf-core/configs/tree/master/conf) for examples. If you are likely to be running `nf-core` pipelines regularly it may be a good idea to request that your custom config file is uploaded to the `nf-core/configs` git repository. Before you do this please can you test that the config file works with your pipeline of choice using the `-c` parameter (see definition below). You can then create a pull request to the `nf-core/configs` repository with the addition of your config file, associated documentation file (see examples in [`nf-core/configs/docs`](https://github.com/nf-core/configs/tree/master/docs)), and amending [`nfcore_custom.config`](https://github.com/nf-core/configs/blob/master/nfcore_custom.config) to include your custom profile. -If you have any questions or issues please send us a message on [`Slack`](https://nf-core-invite.herokuapp.com/). +If you have any questions or issues please send us a message on [Slack](https://nf-co.re/join/slack). ## AWS Batch specific parameters -Running the pipeline on AWS Batch requires a couple of specific parameters to be set according to your AWS Batch configuration. Please use the `-awsbatch` profile and then specify all of the following parameters. + +Running the pipeline on AWS Batch requires a couple of specific parameters to be set according to your AWS Batch configuration. Please use [`-profile awsbatch`](https://github.com/nf-core/configs/blob/master/conf/awsbatch.config) and then specify all of the following parameters. + ### `--awsqueue` + The JobQueue that you intend to use on AWS Batch. + ### `--awsregion` -The AWS region to run your job in. Default is set to `eu-west-1` but can be adjusted to your needs. + +The AWS region in which to run your job. Default is set to `eu-west-1` but can be adjusted to your needs. + +### `--awscli` + +The [AWS CLI](https://www.nextflow.io/docs/latest/awscloud.html#aws-cli-installation) path in your custom AMI. Default: `/home/ec2-user/miniconda/bin/aws`. Please make sure to also set the `-w/--work-dir` and `--outdir` parameters to a S3 storage bucket of your choice - you'll get an error message notifying you if you didn't. @@ -201,12 +234,23 @@ Please make sure to also set the `-w/--work-dir` and `--outdir` parameters to a ### `--outdir` + The output directory where the results will be saved. ### `--email` -Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits. If set in your user config file (`~/.nextflow/config`) then you don't need to speicfy this on the command line for every run. + +Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits. If set in your user config file (`~/.nextflow/config`) then you don't need to specify this on the command line for every run. + +### `--email_on_fail` + +This works exactly as with `--email`, except emails are only sent if the workflow is not successful. + +### `--max_multiqc_email_size` + +Threshold size for MultiQC report to be attached in notification email. If file generated by pipeline exceeds the threshold, it will not be attached (Default: 25MB). ### `-name` + Name for the pipeline run. If not specified, Nextflow will automatically generate a random mnemonic. This is used in the MultiQC report (if not default) and in the summary HTML / e-mail (always). @@ -214,6 +258,7 @@ This is used in the MultiQC report (if not default) and in the summary HTML / e- **NB:** Single hyphen (core Nextflow option) ### `-resume` + Specify this when restarting a pipeline. Nextflow will used cached results from any pipeline steps where the inputs are the same, continuing from where it got to previously. You can also supply a run name to resume a specific run: `-resume [run-name]`. Use the `nextflow log` command to show previous run names. @@ -221,6 +266,7 @@ You can also supply a run name to resume a specific run: `-resume [run-name]`. U **NB:** Single hyphen (core Nextflow option) ### `-c` + Specify the path to a specific config file (this is a core NextFlow command). **NB:** Single hyphen (core Nextflow option) @@ -228,27 +274,58 @@ Specify the path to a specific config file (this is a core NextFlow command). Note - you can use this to override pipeline defaults. ### `--custom_config_version` -Provide git commit id for custom Institutional configs hosted at `nf-core/configs`. This was implemented for reproducibility purposes. Default is set to `master`. + +Provide git commit id for custom Institutional configs hosted at `nf-core/configs`. This was implemented for reproducibility purposes. Default: `master`. ```bash ## Download and use config file with following git commid id --custom_config_version d52db660777c4bf36546ddb188ec530c3ada1b96 ``` +### `--custom_config_base` + +If you're running offline, nextflow will not be able to fetch the institutional config files +from the internet. If you don't need them, then this is not a problem. If you do need them, +you should download the files from the repo and tell nextflow where to find them with the +`custom_config_base` option. For example: + +```bash +## Download and unzip the config files +cd /path/to/my/configs +wget https://github.com/nf-core/configs/archive/master.zip +unzip master.zip + +## Run the pipeline +cd /path/to/my/data +nextflow run /path/to/pipeline/ --custom_config_base /path/to/my/configs/configs-master/ +``` + +> Note that the nf-core/tools helper package has a `download` command to download all required pipeline +> files + singularity containers + institutional configs in one go for you, to make this process easier. + ### `--max_memory` + Use to set a top-limit for the default memory requirement for each process. Should be a string in the format integer-unit. eg. `--max_memory '8.GB'` ### `--max_time` + Use to set a top-limit for the default time requirement for each process. Should be a string in the format integer-unit. eg. `--max_time '2.h'` ### `--max_cpus` + Use to set a top-limit for the default CPU requirement for each process. Should be a string in the format integer-unit. eg. `--max_cpus 1` ### `--plaintext_email` + Set to receive plain-text e-mails instead of HTML formatted. +### `--monochrome_logs` + +Set to disable colourful command line output and live life in monochrome. + ### `--multiqc_config` + Specify a path to a custom MultiQC configuration file. diff --git a/environment.yml b/environment.yml index 42c74b4..d082016 100644 --- a/environment.yml +++ b/environment.yml @@ -1,9 +1,15 @@ -name: nf-core-hic-1.0dev +# You can use this file to create a conda environment for this pipeline: +# conda env create -f environment.yml +name: nf-core-hic-1.1.1dev channels: - conda-forge - bioconda - defaults dependencies: + - conda-forge::python=3.7.3 + - conda-forge::markdown=3.1.1 + - conda-forge::pymdown-extensions=6.0 + - conda-forge::pygments=2.5.2 # TODO nf-core: Add required software dependencies here - - fastqc=0.11.8 - - multiqc=1.6 + - bioconda::fastqc=0.11.8 + - bioconda::multiqc=1.7 diff --git a/main.nf b/main.nf index 97a07de..7b273a2 100644 --- a/main.nf +++ b/main.nf @@ -9,19 +9,10 @@ ---------------------------------------------------------------------------------------- */ - def helpMessage() { // TODO nf-core: Add to this help message with new command line parameters + log.info nfcoreHeader() log.info""" - ======================================================= - ,--./,-. - ___ __ __ __ ___ /,-._.--~\' - |\\ | |__ __ / ` / \\ |__) |__ } { - | \\| | \\__, \\__/ | \\ |___ \\`-._,-`-, - `._,._,\' - - nf-core/hic v${workflow.manifest.version} - ======================================================= Usage: @@ -30,143 +21,143 @@ def helpMessage() { nextflow run nf-core/hic --reads '*_R{1,2}.fastq.gz' -profile docker Mandatory arguments: - --reads Path to input data (must be surrounded with quotes) - --genome Name of iGenomes reference - -profile Configuration profile to use. Can use multiple (comma separated) - Available: conda, docker, singularity, awsbatch, test and more. + --reads [file] Path to input data (must be surrounded with quotes) + -profile [str] Configuration profile to use. Can use multiple (comma separated) + Available: conda, docker, singularity, test, awsbatch, and more Options: - --singleEnd Specifies that the input is single end reads + --genome [str] Name of iGenomes reference + --single_end [bool] Specifies that the input is single-end reads - References If not specified in the configuration file or you wish to overwrite any of the references. - --fasta Path to Fasta reference + References If not specified in the configuration file or you wish to overwrite any of the references + --fasta [file] Path to fasta reference Other options: - --outdir The output directory where the results will be saved - --email Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits - -name Name for the pipeline run. If not specified, Nextflow will automatically generate a random mnemonic. + --outdir [file] The output directory where the results will be saved + --email [email] Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits + --email_on_fail [email] Same as --email, except only send mail if the workflow is not successful + --max_multiqc_email_size [str] Theshold size for MultiQC report to be attached in notification email. If file generated by pipeline exceeds the threshold, it will not be attached (Default: 25MB) + -name [str] Name for the pipeline run. If not specified, Nextflow will automatically generate a random mnemonic AWSBatch options: - --awsqueue The AWSBatch JobQueue that needs to be set when running on AWSBatch - --awsregion The AWS Region for your AWS Batch job to run on + --awsqueue [str] The AWSBatch JobQueue that needs to be set when running on AWSBatch + --awsregion [str] The AWS Region for your AWS Batch job to run on + --awscli [str] Path to the AWS CLI tool """.stripIndent() } +// Show help message +if (params.help) { + helpMessage() + exit 0 +} + /* * SET UP CONFIGURATION VARIABLES */ -// Show help emssage -if (params.help){ - helpMessage() - exit 0 +// Check if genome exists in the config file +if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) { + exit 1, "The provided genome '${params.genome}' is not available in the iGenomes file. Currently the available genomes are ${params.genomes.keySet().join(", ")}" } // TODO nf-core: Add any reference files that are needed // Configurable reference genomes -fasta = params.genome ? params.genomes[ params.genome ].fasta ?: false : false -if ( params.fasta ){ - fasta = file(params.fasta) - if( !fasta.exists() ) exit 1, "Fasta file not found: ${params.fasta}" -} // // NOTE - THIS IS NOT USED IN THIS PIPELINE, EXAMPLE ONLY -// If you want to use the above in a process, define the following: +// If you want to use the channel below in a process, define the following: // input: -// file fasta from fasta +// file fasta from ch_fasta // - +params.fasta = params.genome ? params.genomes[ params.genome ].fasta ?: false : false +if (params.fasta) { ch_fasta = file(params.fasta, checkIfExists: true) } // Has the run name been specified by the user? // this has the bonus effect of catching both -name and --name custom_runName = params.name -if( !(workflow.runName ==~ /[a-z]+_[a-z]+/) ){ - custom_runName = workflow.runName +if (!(workflow.runName ==~ /[a-z]+_[a-z]+/)) { + custom_runName = workflow.runName } - -if( workflow.profile == 'awsbatch') { - // AWSBatch sanity checking - if (!params.awsqueue || !params.awsregion) exit 1, "Specify correct --awsqueue and --awsregion parameters on AWSBatch!" - if (!workflow.workDir.startsWith('s3') || !params.outdir.startsWith('s3')) exit 1, "Specify S3 URLs for workDir and outdir parameters on AWSBatch!" - // Check workDir/outdir paths to be S3 buckets if running on AWSBatch - // related: https://github.com/nextflow-io/nextflow/issues/813 - if (!workflow.workDir.startsWith('s3:') || !params.outdir.startsWith('s3:')) exit 1, "Workdir or Outdir not on S3 - specify S3 Buckets for each to run on AWSBatch!" +if (workflow.profile.contains('awsbatch')) { + // AWSBatch sanity checking + if (!params.awsqueue || !params.awsregion) exit 1, "Specify correct --awsqueue and --awsregion parameters on AWSBatch!" + // Check outdir paths to be S3 buckets if running on AWSBatch + // related: https://github.com/nextflow-io/nextflow/issues/813 + if (!params.outdir.startsWith('s3:')) exit 1, "Outdir not on S3 - specify S3 Bucket to run on AWSBatch!" + // Prevent trace files to be stored on S3 since S3 does not support rolling files. + if (params.tracedir.startsWith('s3:')) exit 1, "Specify a local tracedir or run without trace! S3 cannot be used for tracefiles." } // Stage config files -ch_multiqc_config = Channel.fromPath(params.multiqc_config) -ch_output_docs = Channel.fromPath("$baseDir/docs/output.md") +ch_multiqc_config = file("$baseDir/assets/multiqc_config.yaml", checkIfExists: true) +ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath(params.multiqc_config, checkIfExists: true) : Channel.empty() +ch_output_docs = file("$baseDir/docs/output.md", checkIfExists: true) /* * Create a channel for input read files */ - if(params.readPaths){ - if(params.singleEnd){ - Channel - .from(params.readPaths) - .map { row -> [ row[0], [file(row[1][0])]] } - .ifEmpty { exit 1, "params.readPaths was empty - no input files supplied" } - .into { read_files_fastqc; read_files_trimming } - } else { - Channel - .from(params.readPaths) - .map { row -> [ row[0], [file(row[1][0]), file(row[1][1])]] } - .ifEmpty { exit 1, "params.readPaths was empty - no input files supplied" } - .into { read_files_fastqc; read_files_trimming } - } - } else { - Channel - .fromFilePairs( params.reads, size: params.singleEnd ? 1 : 2 ) - .ifEmpty { exit 1, "Cannot find any reads matching: ${params.reads}\nNB: Path needs to be enclosed in quotes!\nIf this is single-end data, please specify --singleEnd on the command line." } - .into { read_files_fastqc; read_files_trimming } - } - +if (params.readPaths) { + if (params.single_end) { + Channel + .from(params.readPaths) + .map { row -> [ row[0], [ file(row[1][0], checkIfExists: true) ] ] } + .ifEmpty { exit 1, "params.readPaths was empty - no input files supplied" } + .into { ch_read_files_fastqc; ch_read_files_trimming } + } else { + Channel + .from(params.readPaths) + .map { row -> [ row[0], [ file(row[1][0], checkIfExists: true), file(row[1][1], checkIfExists: true) ] ] } + .ifEmpty { exit 1, "params.readPaths was empty - no input files supplied" } + .into { ch_read_files_fastqc; ch_read_files_trimming } + } +} else { + Channel + .fromFilePairs(params.reads, size: params.single_end ? 1 : 2) + .ifEmpty { exit 1, "Cannot find any reads matching: ${params.reads}\nNB: Path needs to be enclosed in quotes!\nIf this is single-end data, please specify --single_end on the command line." } + .into { ch_read_files_fastqc; ch_read_files_trimming } +} // Header log info -log.info """======================================================= - ,--./,-. - ___ __ __ __ ___ /,-._.--~\' - |\\ | |__ __ / ` / \\ |__) |__ } { - | \\| | \\__, \\__/ | \\ |___ \\`-._,-`-, - `._,._,\' - -nf-core/hic v${workflow.manifest.version}" -=======================================================""" +log.info nfcoreHeader() def summary = [:] -summary['Pipeline Name'] = 'nf-core/hic' -summary['Pipeline Version'] = workflow.manifest.version -summary['Run Name'] = custom_runName ?: workflow.runName +if (workflow.revision) summary['Pipeline Release'] = workflow.revision +summary['Run Name'] = custom_runName ?: workflow.runName // TODO nf-core: Report custom parameters here -summary['Reads'] = params.reads -summary['Fasta Ref'] = params.fasta -summary['Data Type'] = params.singleEnd ? 'Single-End' : 'Paired-End' -summary['Max Memory'] = params.max_memory -summary['Max CPUs'] = params.max_cpus -summary['Max Time'] = params.max_time -summary['Output dir'] = params.outdir -summary['Working dir'] = workflow.workDir -summary['Container Engine'] = workflow.containerEngine -if(workflow.containerEngine) summary['Container'] = workflow.container -summary['Current home'] = "$HOME" -summary['Current user'] = "$USER" -summary['Current path'] = "$PWD" -summary['Working dir'] = workflow.workDir -summary['Output dir'] = params.outdir -summary['Script dir'] = workflow.projectDir +summary['Reads'] = params.reads +summary['Fasta Ref'] = params.fasta +summary['Data Type'] = params.single_end ? 'Single-End' : 'Paired-End' +summary['Max Resources'] = "$params.max_memory memory, $params.max_cpus cpus, $params.max_time time per job" +if (workflow.containerEngine) summary['Container'] = "$workflow.containerEngine - $workflow.container" +summary['Output dir'] = params.outdir +summary['Launch dir'] = workflow.launchDir +summary['Working dir'] = workflow.workDir +summary['Script dir'] = workflow.projectDir +summary['User'] = workflow.userName +if (workflow.profile.contains('awsbatch')) { + summary['AWS Region'] = params.awsregion + summary['AWS Queue'] = params.awsqueue + summary['AWS CLI'] = params.awscli +} summary['Config Profile'] = workflow.profile -if(workflow.profile == 'awsbatch'){ - summary['AWS Region'] = params.awsregion - summary['AWS Queue'] = params.awsqueue +if (params.config_profile_description) summary['Config Description'] = params.config_profile_description +if (params.config_profile_contact) summary['Config Contact'] = params.config_profile_contact +if (params.config_profile_url) summary['Config URL'] = params.config_profile_url +if (params.email || params.email_on_fail) { + summary['E-mail Address'] = params.email + summary['E-mail on failure'] = params.email_on_fail + summary['MultiQC maxsize'] = params.max_multiqc_email_size } -if(params.email) summary['E-mail Address'] = params.email -log.info summary.collect { k,v -> "${k.padRight(15)}: $v" }.join("\n") -log.info "=========================================" +log.info summary.collect { k,v -> "${k.padRight(18)}: $v" }.join("\n") +log.info "-\033[2m--------------------------------------------------\033[0m-" +// Check the hostnames against configured profiles +checkHostname() -def create_workflow_summary(summary) { - def yaml_file = workDir.resolve('workflow_summary_mqc.yaml') - yaml_file.text = """ +Channel.from(summary.collect{ [it.key, it.value] }) + .map { k,v -> "

$k
${v ?: 'N/A'}
" } + .reduce { a, b -> return [a, b].join("\n ") } + .map { x -> """ id: 'nf-core-hic-summary' description: " - this information is collected when the pipeline is started." section_name: 'nf-core/hic Workflow Summary' @@ -174,21 +165,24 @@ def create_workflow_summary(summary) { plot_type: 'html' data: |
-${summary.collect { k,v -> "
$k
${v ?: 'N/A'}
" }.join("\n")} + $x
- """.stripIndent() - - return yaml_file -} - + """.stripIndent() } + .set { ch_workflow_summary } /* * Parse software version numbers */ process get_software_versions { + publishDir "${params.outdir}/pipeline_info", mode: 'copy', + saveAs: { filename -> + if (filename.indexOf(".csv") > 0) filename + else null + } output: - file 'software_versions_mqc.yaml' into software_versions_yaml + file 'software_versions_mqc.yaml' into ch_software_versions_yaml + file "software_versions.csv" script: // TODO nf-core: Get all tools to print their version number here @@ -197,34 +191,33 @@ process get_software_versions { echo $workflow.nextflow.version > v_nextflow.txt fastqc --version > v_fastqc.txt multiqc --version > v_multiqc.txt - scrape_software_versions.py > software_versions_mqc.yaml + scrape_software_versions.py &> software_versions_mqc.yaml """ } - - /* * STEP 1 - FastQC */ process fastqc { tag "$name" + label 'process_medium' publishDir "${params.outdir}/fastqc", mode: 'copy', - saveAs: {filename -> filename.indexOf(".zip") > 0 ? "zips/$filename" : "$filename"} + saveAs: { filename -> + filename.indexOf(".zip") > 0 ? "zips/$filename" : "$filename" + } input: - set val(name), file(reads) from read_files_fastqc + set val(name), file(reads) from ch_read_files_fastqc output: - file "*_fastqc.{zip,html}" into fastqc_results + file "*_fastqc.{zip,html}" into ch_fastqc_results script: """ - fastqc -q $reads + fastqc --quiet --threads $task.cpus $reads """ } - - /* * STEP 2 - MultiQC */ @@ -232,32 +225,33 @@ process multiqc { publishDir "${params.outdir}/MultiQC", mode: 'copy' input: - file multiqc_config from ch_multiqc_config + file (multiqc_config) from ch_multiqc_config + file (mqc_custom_config) from ch_multiqc_custom_config.collect().ifEmpty([]) // TODO nf-core: Add in log files from your new processes for MultiQC to find! - file ('fastqc/*') from fastqc_results.collect().ifEmpty([]) - file ('software_versions/*') from software_versions_yaml - file workflow_summary from create_workflow_summary(summary) + file ('fastqc/*') from ch_fastqc_results.collect().ifEmpty([]) + file ('software_versions/*') from ch_software_versions_yaml.collect() + file workflow_summary from ch_workflow_summary.collectFile(name: "workflow_summary_mqc.yaml") output: - file "*multiqc_report.html" into multiqc_report + file "*multiqc_report.html" into ch_multiqc_report file "*_data" + file "multiqc_plots" script: rtitle = custom_runName ? "--title \"$custom_runName\"" : '' rfilename = custom_runName ? "--filename " + custom_runName.replaceAll('\\W','_').replaceAll('_+','_') + "_multiqc_report" : '' + custom_config_file = params.multiqc_config ? "--config $mqc_custom_config" : '' // TODO nf-core: Specify which MultiQC modules to use with -m for a faster run time """ - multiqc -f $rtitle $rfilename --config $multiqc_config . + multiqc -f $rtitle $rfilename $custom_config_file . """ } - - /* * STEP 3 - Output Description HTML */ process output_documentation { - publishDir "${params.outdir}/Documentation", mode: 'copy' + publishDir "${params.outdir}/pipeline_info", mode: 'copy' input: file output_docs from ch_output_docs @@ -267,12 +261,10 @@ process output_documentation { script: """ - markdown_to_html.r $output_docs results_description.html + markdown_to_html.py $output_docs -o results_description.html """ } - - /* * Completion e-mail notification */ @@ -280,8 +272,8 @@ workflow.onComplete { // Set up the e-mail variables def subject = "[nf-core/hic] Successful: $workflow.runName" - if(!workflow.success){ - subject = "[nf-core/hic] FAILED: $workflow.runName" + if (!workflow.success) { + subject = "[nf-core/hic] FAILED: $workflow.runName" } def email_fields = [:] email_fields['version'] = workflow.manifest.version @@ -299,13 +291,34 @@ workflow.onComplete { email_fields['summary']['Date Completed'] = workflow.complete email_fields['summary']['Pipeline script file path'] = workflow.scriptFile email_fields['summary']['Pipeline script hash ID'] = workflow.scriptId - if(workflow.repository) email_fields['summary']['Pipeline repository Git URL'] = workflow.repository - if(workflow.commitId) email_fields['summary']['Pipeline repository Git Commit'] = workflow.commitId - if(workflow.revision) email_fields['summary']['Pipeline Git branch/tag'] = workflow.revision + if (workflow.repository) email_fields['summary']['Pipeline repository Git URL'] = workflow.repository + if (workflow.commitId) email_fields['summary']['Pipeline repository Git Commit'] = workflow.commitId + if (workflow.revision) email_fields['summary']['Pipeline Git branch/tag'] = workflow.revision email_fields['summary']['Nextflow Version'] = workflow.nextflow.version email_fields['summary']['Nextflow Build'] = workflow.nextflow.build email_fields['summary']['Nextflow Compile Timestamp'] = workflow.nextflow.timestamp + // TODO nf-core: If not using MultiQC, strip out this code (including params.max_multiqc_email_size) + // On success try attach the multiqc report + def mqc_report = null + try { + if (workflow.success) { + mqc_report = ch_multiqc_report.getVal() + if (mqc_report.getClass() == ArrayList) { + log.warn "[nf-core/hic] Found multiple reports from process 'multiqc', will use only one" + mqc_report = mqc_report[0] + } + } + } catch (all) { + log.warn "[nf-core/hic] Could not attach MultiQC report to summary email" + } + + // Check if we are only sending emails on failure + email_address = params.email + if (!params.email && params.email_on_fail && !workflow.success) { + email_address = params.email_on_fail + } + // Render the TXT template def engine = new groovy.text.GStringTemplateEngine() def tf = new File("$baseDir/assets/email_template.txt") @@ -318,35 +331,96 @@ workflow.onComplete { def email_html = html_template.toString() // Render the sendmail template - def smail_fields = [ email: params.email, subject: subject, email_txt: email_txt, email_html: email_html, baseDir: "$baseDir" ] + def smail_fields = [ email: email_address, subject: subject, email_txt: email_txt, email_html: email_html, baseDir: "$baseDir", mqcFile: mqc_report, mqcMaxSize: params.max_multiqc_email_size.toBytes() ] def sf = new File("$baseDir/assets/sendmail_template.txt") def sendmail_template = engine.createTemplate(sf).make(smail_fields) def sendmail_html = sendmail_template.toString() // Send the HTML e-mail - if (params.email) { + if (email_address) { try { - if( params.plaintext_email ){ throw GroovyException('Send plaintext e-mail, not HTML') } - // Try to send HTML e-mail using sendmail - [ 'sendmail', '-t' ].execute() << sendmail_html - log.info "[nf-core/hic] Sent summary e-mail to $params.email (sendmail)" + if (params.plaintext_email) { throw GroovyException('Send plaintext e-mail, not HTML') } + // Try to send HTML e-mail using sendmail + [ 'sendmail', '-t' ].execute() << sendmail_html + log.info "[nf-core/hic] Sent summary e-mail to $email_address (sendmail)" } catch (all) { - // Catch failures and try with plaintext - [ 'mail', '-s', subject, params.email ].execute() << email_txt - log.info "[nf-core/hic] Sent summary e-mail to $params.email (mail)" + // Catch failures and try with plaintext + [ 'mail', '-s', subject, email_address ].execute() << email_txt + log.info "[nf-core/hic] Sent summary e-mail to $email_address (mail)" } } // Write summary e-mail HTML to a file - def output_d = new File( "${params.outdir}/Documentation/" ) - if( !output_d.exists() ) { - output_d.mkdirs() + def output_d = new File("${params.outdir}/pipeline_info/") + if (!output_d.exists()) { + output_d.mkdirs() } - def output_hf = new File( output_d, "pipeline_report.html" ) + def output_hf = new File(output_d, "pipeline_report.html") output_hf.withWriter { w -> w << email_html } - def output_tf = new File( output_d, "pipeline_report.txt" ) + def output_tf = new File(output_d, "pipeline_report.txt") output_tf.withWriter { w -> w << email_txt } - log.info "[nf-core/hic] Pipeline Complete" + c_green = params.monochrome_logs ? '' : "\033[0;32m"; + c_purple = params.monochrome_logs ? '' : "\033[0;35m"; + c_red = params.monochrome_logs ? '' : "\033[0;31m"; + c_reset = params.monochrome_logs ? '' : "\033[0m"; + + if (workflow.stats.ignoredCount > 0 && workflow.success) { + log.info "-${c_purple}Warning, pipeline completed, but with errored process(es) ${c_reset}-" + log.info "-${c_red}Number of ignored errored process(es) : ${workflow.stats.ignoredCount} ${c_reset}-" + log.info "-${c_green}Number of successfully ran process(es) : ${workflow.stats.succeedCount} ${c_reset}-" + } + + if (workflow.success) { + log.info "-${c_purple}[nf-core/hic]${c_green} Pipeline completed successfully${c_reset}-" + } else { + checkHostname() + log.info "-${c_purple}[nf-core/hic]${c_red} Pipeline completed with errors${c_reset}-" + } + +} + +def nfcoreHeader() { + // Log colors ANSI codes + c_black = params.monochrome_logs ? '' : "\033[0;30m"; + c_blue = params.monochrome_logs ? '' : "\033[0;34m"; + c_cyan = params.monochrome_logs ? '' : "\033[0;36m"; + c_dim = params.monochrome_logs ? '' : "\033[2m"; + c_green = params.monochrome_logs ? '' : "\033[0;32m"; + c_purple = params.monochrome_logs ? '' : "\033[0;35m"; + c_reset = params.monochrome_logs ? '' : "\033[0m"; + c_white = params.monochrome_logs ? '' : "\033[0;37m"; + c_yellow = params.monochrome_logs ? '' : "\033[0;33m"; + + return """ -${c_dim}--------------------------------------------------${c_reset}- + ${c_green},--.${c_black}/${c_green},-.${c_reset} + ${c_blue} ___ __ __ __ ___ ${c_green}/,-._.--~\'${c_reset} + ${c_blue} |\\ | |__ __ / ` / \\ |__) |__ ${c_yellow}} {${c_reset} + ${c_blue} | \\| | \\__, \\__/ | \\ |___ ${c_green}\\`-._,-`-,${c_reset} + ${c_green}`._,._,\'${c_reset} + ${c_purple} nf-core/hic v${workflow.manifest.version}${c_reset} + -${c_dim}--------------------------------------------------${c_reset}- + """.stripIndent() +} + +def checkHostname() { + def c_reset = params.monochrome_logs ? '' : "\033[0m" + def c_white = params.monochrome_logs ? '' : "\033[0;37m" + def c_red = params.monochrome_logs ? '' : "\033[1;91m" + def c_yellow_bold = params.monochrome_logs ? '' : "\033[1;93m" + if (params.hostnames) { + def hostname = "hostname".execute().text.trim() + params.hostnames.each { prof, hnames -> + hnames.each { hname -> + if (hostname.contains(hname) && !workflow.profile.contains(prof)) { + log.error "====================================================\n" + + " ${c_red}WARNING!${c_reset} You are running with `-profile $workflow.profile`\n" + + " but your machine hostname is ${c_white}'$hostname'${c_reset}\n" + + " ${c_yellow_bold}It's highly recommended that you use `-profile $prof${c_reset}`\n" + + "============================================================" + } + } + } + } } diff --git a/nextflow.config b/nextflow.config index 5f363c6..7338b5a 100644 --- a/nextflow.config +++ b/nextflow.config @@ -3,83 +3,104 @@ * nf-core/hic Nextflow config file * ------------------------------------------------- * Default config options for all environments. - * Cluster-specific config options should be saved - * in the conf folder and imported under a profile - * name here. */ // Global default params, used in configs params { - // Container slug. Stable releases should specify release tag! - // Developmental code should specify :latest - container = 'nfcore/hic:latest' - // Workflow flags // TODO nf-core: Specify your pipeline's command line flags + genome = false reads = "data/*{1,2}.fastq.gz" - singleEnd = false + single_end = false outdir = './results' // Boilerplate options name = false - multiqc_config = "$baseDir/conf/multiqc_config.yaml" + multiqc_config = false email = false + email_on_fail = false + max_multiqc_email_size = 25.MB plaintext_email = false + monochrome_logs = false help = false - igenomes_base = "./iGenomes" + igenomes_base = 's3://ngi-igenomes/igenomes/' tracedir = "${params.outdir}/pipeline_info" - clusterOptions = false - awsqueue = false - awsregion = 'eu-west-1' - igenomesIgnore = false + igenomes_ignore = false custom_config_version = 'master' + custom_config_base = "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}" + hostnames = false + config_profile_description = false + config_profile_contact = false + config_profile_url = false + + // Defaults only, expecting to be overwritten + max_memory = 128.GB + max_cpus = 16 + max_time = 240.h + } +// Container slug. Stable releases should specify release tag! +// Developmental code should specify :dev +process.container = 'nfcore/hic:dev' + // Load base.config by default for all pipelines includeConfig 'conf/base.config' // Load nf-core custom profiles from different Institutions -includeConfig "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}/nfcore_custom.config" +try { + includeConfig "${params.custom_config_base}/nfcore_custom.config" +} catch (Exception e) { + System.err.println("WARNING: Could not load nf-core/config profiles: ${params.custom_config_base}/nfcore_custom.config") +} profiles { - awsbatch { includeConfig 'conf/awsbatch.config' } conda { process.conda = "$baseDir/environment.yml" } debug { process.beforeScript = 'echo $HOSTNAME' } docker { docker.enabled = true - process.container = params.container + // Avoid this error: + // WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap. + // Testing this in nf-core after discussion here https://github.com/nf-core/tools/pull/351 + // once this is established and works well, nextflow might implement this behavior as new default. + docker.runOptions = '-u \$(id -u):\$(id -g)' } singularity { singularity.enabled = true - process.container = {"shub://${params.container.replace('nfcore', 'nf-core')}"} + singularity.autoMounts = true } test { includeConfig 'conf/test.config' } } // Load igenomes.config if required -if(!params.igenomesIgnore){ +if (!params.igenomes_ignore) { includeConfig 'conf/igenomes.config' } +// Export this variable to prevent local Python libraries from conflicting with those in the container +env { + PYTHONNOUSERSITE = 1 +} + // Capture exit codes from upstream processes when piping process.shell = ['/bin/bash', '-euo', 'pipefail'] timeline { enabled = true - file = "${params.tracedir}/nf-core/hic_timeline.html" + file = "${params.tracedir}/execution_timeline.html" } report { enabled = true - file = "${params.tracedir}/nf-core/hic_report.html" + file = "${params.tracedir}/execution_report.html" } trace { enabled = true - file = "${params.tracedir}/nf-core/hic_trace.txt" + file = "${params.tracedir}/execution_trace.txt" } dag { enabled = true - file = "${params.tracedir}/nf-core/hic_dag.svg" + file = "${params.tracedir}/pipeline_dag.svg" } manifest { @@ -88,16 +109,16 @@ manifest { homePage = 'https://github.com/nf-core/hic' description = 'Analysis of Chromosome Conformation Capture data (Hi-C)' mainScript = 'main.nf' - nextflowVersion = '>=0.32.0' - version = '1.0dev' + nextflowVersion = '>=19.10.0' + version = '1.1.1dev' } // Function to ensure that resource requirements don't go beyond // a maximum limit def check_max(obj, type) { - if(type == 'memory'){ + if (type == 'memory') { try { - if(obj.compareTo(params.max_memory as nextflow.util.MemoryUnit) == 1) + if (obj.compareTo(params.max_memory as nextflow.util.MemoryUnit) == 1) return params.max_memory as nextflow.util.MemoryUnit else return obj @@ -105,9 +126,9 @@ def check_max(obj, type) { println " ### ERROR ### Max memory '${params.max_memory}' is not valid! Using default value: $obj" return obj } - } else if(type == 'time'){ + } else if (type == 'time') { try { - if(obj.compareTo(params.max_time as nextflow.util.Duration) == 1) + if (obj.compareTo(params.max_time as nextflow.util.Duration) == 1) return params.max_time as nextflow.util.Duration else return obj @@ -115,7 +136,7 @@ def check_max(obj, type) { println " ### ERROR ### Max time '${params.max_time}' is not valid! Using default value: $obj" return obj } - } else if(type == 'cpus'){ + } else if (type == 'cpus') { try { return Math.min( obj, params.max_cpus as int ) } catch (all) { From 0b0764ede139c4c05aff3692a769c25a743781a9 Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 12 May 2020 10:32:30 +0200 Subject: [PATCH 13/36] [MODIF] update yml + python3 --- CHANGELOG.md | 9 +- bin/digest_genome.py | 150 +++++++------ bin/mapped_2hic_dnase.py | 121 +++++------ bin/mapped_2hic_fragments.py | 188 ++++++++-------- bin/mergeSAM.py | 403 +++++++++++++++++------------------ conf/base.config | 15 +- environment.yml | 23 +- main.nf | 160 +++++++------- 8 files changed, 528 insertions(+), 541 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8de4bf1..7c1941a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### `Added` -* Bump v1.2.0 +* Bump v1.2.0dev * Merge template nf-core 1.9 +* Move some options to camel_case +* Update conda environment file +* Update python scripts for python3 +### `Deprecated` + +* --skipMaps, --skipIce, --skipCool, --skipMultiQC are deprecated and replaced by --skip_maps, --skip_ice, --skip_cool, --skip_multiqc +* --saveReference, --saveAlignedIntermediates, --saveInteractionBAM are replaced by --save_reference, --save_aligned_intermediates, --save_interaction_bam ## v1.1.1 diff --git a/bin/digest_genome.py b/bin/digest_genome.py index ac6d8da..2c29a49 100755 --- a/bin/digest_genome.py +++ b/bin/digest_genome.py @@ -26,48 +26,47 @@ def find_re_sites(filename, sequences, offset): - infile = open(filename) - chr_id = None - big_str = "" - indices = [] - all_indices = [] - contig_names = [] - c = 0 - for line in infile: - c += 1 - if line.startswith(">"): - print line.split()[0][1:], "..." - # If this is not the first chromosome, find the indices and append - # them to the list - if chr_id is not None: - for rs in range(len(sequences)): - pattern = "(?=%s)" % sequences[rs].lower() - indices += [m.start() + offset[rs] - for m in re.finditer(pattern, big_str)] - indices.sort() - all_indices.append(indices) - indices = [] - - # This is a new chromosome. Empty the sequence string, and add the - # correct chrom id - big_str = "" - chr_id = line.split()[0][1:] - if chr_id in contig_names: - print "The fasta file contains several instance of", - print chr_id, ". Exit." - sys.exit(-1) - contig_names.append(chr_id) - else: - # As long as we don't change chromosomes, continue reading the - # file, and appending the sequences - big_str += line.lower().strip() - # Add the indices for the last chromosome - for rs in range(len(sequences)): - pattern = "(?=%s)" % sequences[rs].lower() - indices += [m.start() + offset[rs] - for m in re.finditer(pattern, big_str)] - indices.sort() - all_indices.append(indices) + with open(filename, 'r') as infile: + chr_id = None + big_str = "" + indices = [] + all_indices = [] + contig_names = [] + c = 0 + for line in infile: + c += 1 + if line.startswith(">"): + print("{}...".format(line.split()[0][1:])) + # If this is not the first chromosome, find the indices and append + # them to the list + if chr_id is not None: + for rs in range(len(sequences)): + pattern = "(?={})".format(sequences[rs].lower()) + indices += [m.start() + offset[rs]\ + for m in re.finditer(pattern, big_str)] + indices.sort() + all_indices.append(indices) + indices = [] + + # This is a new chromosome. Empty the sequence string, and add the + # correct chrom id + big_str = "" + chr_id = line.split()[0][1:] + if chr_id in contig_names: + print("The fasta file contains several instance of {}. Exit.".format(chr_id)) + sys.exit(-1) + contig_names.append(chr_id) + else: + # As long as we don't change chromosomes, continue reading the + # file, and appending the sequences + big_str += line.lower().strip() + # Add the indices for the last chromosome + for rs in range(len(sequences)): + pattern = "(?={})".format(sequences[rs].lower()) + indices += [m.start() + offset[rs] + for m in re.finditer(pattern, big_str)] + indices.sort() + all_indices.append(indices) return contig_names, all_indices @@ -76,27 +75,27 @@ def find_chromsomose_lengths(reference_filename): chromosome_lengths = [] chromosome_names = [] length = None - infile = open(reference_filename) - for line in infile: - if line.startswith(">"): - chromosome_names.append(line[1:].strip()) - if length is not None: - chromosome_lengths.append(length) - length = 0 - else: - length += len(line.strip()) - chromosome_lengths.append(length) + with open(reference_filename, 'r') as infile: + for line in infile: + if line.startswith(">"): + chromosome_names.append(line[1:].strip()) + if length is not None: + chromosome_lengths.append(length) + length = 0 + else: + length += len(line.strip()) + chromosome_lengths.append(length) return chromosome_names, np.array(chromosome_lengths) def replaceN(cs): npos = int(cs.find('N')) cseql = [] - if npos!= -1: + if npos != -1: for nuc in ["A","C","G","T"]: tmp = cs.replace('N', nuc, 1) tmpl = replaceN(tmp) - if type(tmpl)==list: + if type(tmpl) == list: cseql = cseql + tmpl else: cseql.append(tmpl) @@ -138,15 +137,15 @@ def replaceN(cs): offpos = int(cseq.find('^')) if offpos == -1: - print "Unable to detect offset for", cseq - print "Please, use '^' to specified the cutting position,", - print "i.e A^GATCT for HindIII digestion" + print("Unable to detect offset for {}. Please, use '^' to specify the cutting position,\ + i.e A^GATCT for HindIII digestion.".format(cseq)) sys.exit(-1) for nuc in list(set(cs)): - if nuc != 'A' and nuc != 'C' and nuc != 'G' and nuc != 'T' and nuc != 'N' and nuc != '^': - print "Find unexpected character ['",nuc,"']in restriction motif" - print "Note that multiple motifs should be separated by a space (not a comma !)" + if nuc not in ['A','T','G','C','N','^']: + print("Find unexpected character ['{}']in restriction motif".format(nuc)) + print("Note that multiple motifs should be separated by a space (not a comma !)") + sys.exit(-1) offset.append(offpos) @@ -166,9 +165,9 @@ def replaceN(cs): if out is None: out = os.path.splitext(filename)[0] + "_fragments.bed" - print "Analyzing", filename - print "Restriction site(s)", ",".join(sequences) - print "Offset(s)", ','.join(str(x) for x in offset) + print("Analyzing", filename) + print("Restriction site(s)", ",".join(sequences)) + print("Offset(s)", ','.join(str(x) for x in offset)) # Read fasta file and look for rs per chromosome contig_names, all_indices = find_re_sites(filename, sequences, offset=offset) @@ -183,17 +182,14 @@ def replaceN(cs): valid_fragments.append(valid_fragments_chr) # Write results - print "Writing to", out, "..." - outfile = open(out, "w") - for chrom_name, indices in zip(contig_names, valid_fragments): - frag_id = 0 - for begin, end in indices: - # allow to remove cases where the enzyme cut at - # the first position of the chromosome - if end > begin: - frag_id += 1 - frag_name = "HIC_%s_%d" % (chrom_name, frag_id) - outfile.write( - "%s\t%d\t%d\t%s\t0\t+\n" % (chrom_name, begin, - end, frag_name)) - outfile.close() + print("Writing to {} ...".format(out)) + with open(out, 'w') as outfile: + for chrom_name, indices in zip(contig_names, valid_fragments): + frag_id = 0 + for begin, end in indices: + # allow to remove cases where the enzyme cut at + # the first position of the chromosome + if end > begin: + frag_id += 1 + frag_name = "HIC_{}_{}".format(str(chrom_name), int(frag_id)) + outfile.write("{}\t{}\t{}\t{}\t0\t+\n".format(str(chrom_name), int(begin), int(end), str(frag_name))) diff --git a/bin/mapped_2hic_dnase.py b/bin/mapped_2hic_dnase.py index 36c5a60..dd023b0 100755 --- a/bin/mapped_2hic_dnase.py +++ b/bin/mapped_2hic_dnase.py @@ -21,14 +21,14 @@ def usage(): """Usage function""" - print "Usage : python mapped_2hic_dnase.py" - print "-r/--mappedReadsFile " - print "[-o/--outputDir] " - print "[-d/--minCisDist] " - print "[-g/--gtag] " - print "[-a/--all] " - print "[-v/--verbose] " - print "[-h/--help] " + print("Usage : python mapped_2hic_dnase.py") + print("-r/--mappedReadsFile ") + print("[-o/--outputDir] ") + print("[-d/--minCisDist] ") + print("[-g/--gtag] ") + print("[-a/--all] ") + print("[-v/--verbose] ") + print("[-h/--help] ") return @@ -78,11 +78,11 @@ def get_read_pos(read, st="start"): list of aligned reads """ if st == "middle": - pos = read.pos + int(read.alen/2) + pos = read.reference_start + int(read.alen/2) elif st =="start": pos = get_read_start(read) elif st == "left": - pos = read.pos + pos = read.reference_start return pos @@ -92,9 +92,9 @@ def get_read_start(read): Return the 5' end of the read """ if read.is_reverse: - pos = read.pos + read.alen -1 + pos = read.reference_start + read.alen -1 else: - pos = read.pos + pos = read.reference_start return pos @@ -108,20 +108,16 @@ def get_ordered_reads(read1, read2): read1 = [AlignedRead] read2 = [AlignedRead] """ - if read1.tid == read2.tid: + if read1.reference_id == read2.reference_id: if get_read_pos(read1) < get_read_pos(read2): - r1 = read1 - r2 = read2 + r1, r2 = read1, read2 else: - r1 = read2 - r2 = read1 + r1, r2 = read2, read1 else: - if read1.tid < read2.tid: - r1 = read1 - r2 = read2 + if read1.reference_id < read2.reference_id: + r1, r2 = read1, read2 else: - r1 = read2 - r2 = read1 + r1, r2 = read2, read1 return r1, r2 @@ -134,7 +130,7 @@ def isIntraChrom(read1, read2): read2 : [AlignedRead] """ - if read1.tid == read2.tid: + if read1.reference_id == read2.reference_id: return True else: return False @@ -187,7 +183,7 @@ def get_cis_dist(read1, read2): def get_read_tag(read, tag): - for t in read.tags: + for t in read.get_tags(): if t[0] == tag: return t[1] return None @@ -229,11 +225,11 @@ def get_read_tag(read, tag): # Verbose mode if verbose: - print "## overlapMapped2HiCFragments.py" - print "## mappedReadsFile=", mappedReadsFile - print "## minCisDist=", minDist - print "## allOuput=", allOutput - print "## verbose=", verbose, "\n" + print("## overlapMapped2HiCFragments.py") + print("## mappedReadsFile=", mappedReadsFile) + print("## minCisDist=", minDist) + print("## allOuput=", allOutput) + print("## verbose={}\n".format(verbose)) # Initialize variables reads_counter = 0 @@ -271,7 +267,7 @@ def get_read_tag(read, tag): # Read the SAM/BAM file if verbose: - print "## Opening SAM/BAM file '", mappedReadsFile, "'..." + print("## Opening SAM/BAM file {} ...".format(mappedReadsFile)) samfile = pysam.Samfile(mappedReadsFile, "rb") # Reads are 0-based too (for both SAM and BAM format) @@ -286,7 +282,7 @@ def get_read_tag(read, tag): if read.is_read1: r1 = read if not r1.is_unmapped: - r1_chrom = samfile.getrname(r1.tid) + r1_chrom = samfile.get_reference_name(r1.reference_id) else: r1_chrom = None @@ -294,11 +290,11 @@ def get_read_tag(read, tag): elif read.is_read2: r2 = read if not r2.is_unmapped: - r2_chrom = samfile.getrname(r2.tid) + r2_chrom = samfile.get_reference_name(r2.reference_id) else: r2_chrom = None - if isIntraChrom(r1,r2): + if isIntraChrom(r1, r2): dist = get_cis_dist(r1, r2) else: dist = None @@ -368,8 +364,8 @@ def get_read_tag(read, tag): ##reorient reads to ease duplicates removal or1, or2 = get_ordered_reads(r1, r2) - or1_chrom = samfile.getrname(or1.tid) - or2_chrom = samfile.getrname(or2.tid) + or1_chrom = samfile.get_reference_name(or1.reference_id) + or2_chrom = samfile.get_reference_name(or2.reference_id) ##reset as tag now that the reads are oriented r1as = get_read_tag(or1, gtag) @@ -378,7 +374,7 @@ def get_read_tag(read, tag): htag = str(r1as)+"-"+str(r2as) cur_handler.write( - or1.qname + "\t" + + or1.query_name + "\t" + or1_chrom + "\t" + str(get_read_pos(or1)+1) + "\t" + str(get_read_strand(or1)) + "\t" + @@ -394,7 +390,7 @@ def get_read_tag(read, tag): elif r2.is_unmapped and not r1.is_unmapped: cur_handler.write( - r1.qname + "\t" + + r1.query_name + "\t" + r1_chrom + "\t" + str(get_read_pos(r1)+1) + "\t" + str(get_read_strand(r1)) + "\t" + @@ -408,7 +404,7 @@ def get_read_tag(read, tag): "*" + "\n") elif r1.is_unmapped and not r2.is_unmapped: cur_handler.write( - r2.qname + "\t" + + r2.query_name + "\t" + "*" + "\t" + "*" + "\t" + "*" + "\t" + @@ -422,7 +418,7 @@ def get_read_tag(read, tag): str(r2.mapping_quality) + "\n") if (reads_counter % 100000 == 0 and verbose): - print "##", reads_counter + print("##", reads_counter) # Close handler handle_valid.close() @@ -432,33 +428,28 @@ def get_read_tag(read, tag): handle_filt.close() # Write stats file - handle_stat = open(outputDir + '/' + baseReadsFile + '.RSstat', 'w') - handle_stat.write("## Hi-C processing - no restriction fragments\n") - handle_stat.write("Valid_interaction_pairs\t" + str(valid_counter) + "\n") - handle_stat.write( - "Valid_interaction_pairs_FF\t" + str(valid_counter_FF) + "\n") - handle_stat.write( - "Valid_interaction_pairs_RR\t" + str(valid_counter_RR) + "\n") - handle_stat.write( - "Valid_interaction_pairs_RF\t" + str(valid_counter_RF) + "\n") - handle_stat.write( - "Valid_interaction_pairs_FR\t" + str(valid_counter_FR) + "\n") - handle_stat.write("Single-end_pairs\t" + str(single_counter) + "\n") - handle_stat.write("Filtered_pairs\t" + str(filt_counter) + "\n") - handle_stat.write("Dumped_pairs\t" + str(dump_counter) + "\n") + with open(outputDir + '/' + baseReadsFile + '.RSstat', 'w') as handle_stat: + handle_stat.write("## Hi-C processing - no restriction fragments\n") + handle_stat.write("Valid_interaction_pairs\t" + str(valid_counter) + "\n") + handle_stat.write("Valid_interaction_pairs_FF\t" + str(valid_counter_FF) + "\n") + handle_stat.write("Valid_interaction_pairs_RR\t" + str(valid_counter_RR) + "\n") + handle_stat.write("Valid_interaction_pairs_RF\t" + str(valid_counter_RF) + "\n") + handle_stat.write("Valid_interaction_pairs_FR\t" + str(valid_counter_FR) + "\n") + handle_stat.write("Single-end_pairs\t" + str(single_counter) + "\n") + handle_stat.write("Filtered_pairs\t" + str(filt_counter) + "\n") + handle_stat.write("Dumped_pairs\t" + str(dump_counter) + "\n") ## Write AS report - if gtag is not None: - handle_stat.write("## ======================================\n") - handle_stat.write("## Allele specific information\n") - handle_stat.write("Valid_pairs_from_ref_genome_(1-1)\t" + str(G1G1_ascounter) + "\n") - handle_stat.write("Valid_pairs_from_ref_genome_with_one_unassigned_mate_(0-1/1-0)\t" + str(UG1_ascounter+G1U_ascounter) + "\n") - handle_stat.write("Valid_pairs_from_alt_genome_(2-2)\t" + str(G2G2_ascounter) + "\n") - handle_stat.write("Valid_pairs_from_alt_genome_with_one_unassigned_mate_(0-2/2-0)\t" + str(UG2_ascounter+G2U_ascounter) + "\n") - handle_stat.write("Valid_pairs_from_alt_and_ref_genome_(1-2/2-1)\t" + str(G1G2_ascounter+G2G1_ascounter) + "\n") - handle_stat.write("Valid_pairs_with_both_unassigned_mated_(0-0)\t" + str(UU_ascounter) + "\n") - handle_stat.write("Valid_pairs_with_at_least_one_conflicting_mate_(3-)\t" + str(CF_ascounter) + "\n") - - handle_stat.close() + if gtag is not None: + handle_stat.write("## ======================================\n") + handle_stat.write("## Allele specific information\n") + handle_stat.write("Valid_pairs_from_ref_genome_(1-1)\t" + str(G1G1_ascounter) + "\n") + handle_stat.write("Valid_pairs_from_ref_genome_with_one_unassigned_mate_(0-1/1-0)\t" + str(UG1_ascounter+G1U_ascounter) + "\n") + handle_stat.write("Valid_pairs_from_alt_genome_(2-2)\t" + str(G2G2_ascounter) + "\n") + handle_stat.write("Valid_pairs_from_alt_genome_with_one_unassigned_mate_(0-2/2-0)\t" + str(UG2_ascounter+G2U_ascounter) + "\n") + handle_stat.write("Valid_pairs_from_alt_and_ref_genome_(1-2/2-1)\t" + str(G1G2_ascounter+G2G1_ascounter) + "\n") + handle_stat.write("Valid_pairs_with_both_unassigned_mated_(0-0)\t" + str(UU_ascounter) + "\n") + handle_stat.write("Valid_pairs_with_at_least_one_conflicting_mate_(3-)\t" + str(CF_ascounter) + "\n") + diff --git a/bin/mapped_2hic_fragments.py b/bin/mapped_2hic_fragments.py index d4790ee..e823ee0 100755 --- a/bin/mapped_2hic_fragments.py +++ b/bin/mapped_2hic_fragments.py @@ -12,7 +12,6 @@ Script to keep only valid 3C products - DE and SC are removed Output is : readname / """ - import time import getopt import sys @@ -24,20 +23,20 @@ def usage(): """Usage function""" - print "Usage : python mapped_2hic_fragments.py" - print "-f/--fragmentFile " - print "-r/--mappedReadsFile " - print "[-o/--outputDir] " - print "[-s/--shortestInsertSize] " - print "[-l/--longestInsertSize] " - print "[-t/--shortestFragmentLength] " - print "[-m/--longestFragmentLength] " - print "[-d/--minCisDist] " - print "[-g/--gtag] " - print "[-a/--all] " - print "[-S/--sam] " - print "[-v/--verbose] " - print "[-h/--help] " + print("Usage : python mapped_2hic_fragments.py") + print("-f/--fragmentFile ") + print("-r/--mappedReadsFile ") + print("[-o/--outputDir] ") + print("[-s/--shortestInsertSize] ") + print("[-l/--longestInsertSize] ") + print("[-t/--shortestFragmentLength] ") + print("[-m/--longestFragmentLength] ") + print("[-d/--minCisDist] ") + print("[-g/--gtag] ") + print("[-a/--all] ") + print("[-S/--sam] ") + print("[-v/--verbose] ") + print("[-h/--help] ") return @@ -67,7 +66,7 @@ def timing(function, *args): """ startTime = time.time() result = function(*args) - print '%s function took %0.3f ms' % (function.func_name, (time.time() - startTime) * 1000) + print('{} function took {:.3f}ms'.format(function.__name__, (time.time() - startTime) * 1000)) return result @@ -96,8 +95,7 @@ def isIntraChrom(read1, read2): """ if read1.tid == read2.tid: return True - else: - return False + return False def get_cis_dist(read1, read2): @@ -114,8 +112,7 @@ def get_cis_dist(read1, read2): if not read1.is_unmapped and not read2.is_unmapped: ## Contact distances can be calculated for intrachromosomal reads only if isIntraChrom(read1, read2): - r1pos = get_read_pos(read1) - r2pos = get_read_pos(read2) + r1pos, r2pos = get_read_pos(read1), get_read_pos(read2) dist = abs(r1pos - r2pos) return dist @@ -138,11 +135,11 @@ def get_read_pos(read, st="start"): """ if st == "middle": - pos = read.pos + int(read.alen/2) + pos = read.reference_start + int(read.alen/2) elif st =="start": pos = get_read_start(read) elif st == "left": - pos = read.pos + pos = read.reference_start return pos @@ -152,9 +149,9 @@ def get_read_start(read): Return the 5' end of the read """ if read.is_reverse: - pos = read.pos + read.alen -1 + pos = read.reference_start + read.alen -1 else: - pos = read.pos + pos = read.reference_start return pos def get_ordered_reads(read1, read2): @@ -178,18 +175,14 @@ def get_ordered_reads(read1, read2): """ if read1.tid == read2.tid: if get_read_pos(read1) < get_read_pos(read2): - r1 = read1 - r2 = read2 + r1, r2 = read1, read2 else: - r1 = read2 - r2 = read1 + r1, r2 = read2, read1 else: if read1.tid < read2.tid: - r1 = read1 - r2 = read2 + r1, r2 = read1, read2 else: - r1 = read2 - r2 = read1 + r1, r2 = read2, read1 return r1, r2 @@ -206,46 +199,44 @@ def load_restriction_fragment(in_file, minfragsize=None, maxfragsize=None, verbo """ resFrag = {} if verbose: - print "## Loading Restriction File Intervals '", in_file, "'..." - + print("## Loading Restriction File Intervals {} ...".format(in_file)) bed_handle = open(in_file) nline = 0 nfilt = 0 for line in bed_handle: - nline +=1 - bedtab = line.split("\t") - try: - chromosome, start, end, name = bedtab[:4] - except ValueError: - print "Warning : wrong input format in line", nline,". Not a BED file !?" - continue + nline += 1 + bedtab = line.split("\t") + try: + chromosome, start, end, name = bedtab[:4] + except ValueError: + print("Warning : wrong input format in line {}. Not a BED file ?!".format(nline)) + continue # BED files are zero-based as Intervals objects - start = int(start) # + 1 - end = int(end) - fragl = abs(end - start) - name = name.strip() - - ## Discard fragments outside the size range - filt=False - if minfragsize != None and int(fragl) < int(minfragsize): - nfilt+=1 - filt=True - elif maxfragsize != None and int(fragl) > int(maxfragsize): - nfilt+=1 - filt=True + start = int(start) # + 1 + end = int(end) + fragl = abs(end - start) + name = name.strip() + + ## Discard fragments outside the size range + filt = False + if minfragsize != None and int(fragl) < int(minfragsize): + nfilt += 1 + filt = True + elif maxfragsize != None and int(fragl) > int(maxfragsize): + nfilt += 1 + filt = True - if chromosome in resFrag: - tree = resFrag[chromosome] - tree.add_interval(Interval(start, end, value={'name': name, 'filter': filt})) - else: - tree = Intersecter() - tree.add_interval(Interval(start, end, value={'name': name, 'filter': filt})) - resFrag[chromosome] = tree + if chromosome in resFrag: + tree = resFrag[chromosome] + tree.add_interval(Interval(start, end, value={'name': name, 'filter': filt})) + else: + tree = Intersecter() + tree.add_interval(Interval(start, end, value={'name': name, 'filter': filt})) + resFrag[chromosome] = tree if nfilt > 0: - print "Warning : ", nfilt ,"fragment(s) outside of range and discarded. ", nline - nfilt, " remaining." - + print("Warning : {} fragment(s) outside of range and discarded. {} remaining.".format(nfilt, nline - nfilt)) bed_handle.close() return resFrag @@ -260,22 +251,22 @@ def get_overlapping_restriction_fragment(resFrag, chrom, read): read = the read to intersect [AlignedRead] """ - # Get read position (middle or 5' end) + # Get read position (middle or start) pos = get_read_pos(read, st="middle") if chrom in resFrag: # Overlap with the position of the read (zero-based) resfrag = resFrag[chrom].find(pos, pos+1) if len(resfrag) > 1: - print "Warning : ", len(resfrag), " restriction fragments found for ", read.qname, "- skipped" + print("Warning : {} restictions fragments found for {} -skipped".format(len(resfrag), read.query_name)) return None elif len(resfrag) == 0: - print "Warning - no restriction fragments for ", read.qname ," at ", chrom, ":", pos + print("Warning - no restriction fragments for {} at {} : {}".format(read.query_name, chrom, pos)) return None else: return resfrag[0] else: - print "Warning - no restriction fragments for ", read.qname," at ", chrom, ":", pos + print("Warning - no restriction fragments for {} at {} : {}".format(read.qname, chrom, pos)) return None @@ -301,11 +292,11 @@ def is_religation(read1, read2, frag1, frag2): Check the orientation of reads -><- """ - ret=False + ret = False if are_contiguous_fragments(frag1, frag2, read1.tid, read2.tid): #r1, r2 = get_ordered_reads(read1, read2) #if get_read_strand(r1) == "+" and get_read_strand(r2) == "-": - ret=True + ret = True return ret @@ -374,8 +365,8 @@ def get_PE_fragment_size(read1, read2, resFrag1, resFrag2, interactionType): read1 : [AlignedRead] read2 : [AlignedRead] - resfrag1 = restrictin fragment overlapping the R1 read [interval] - resfrag1 = restrictin fragment overlapping the R1 read [interval] + resfrag1 = restriction fragment overlapping the R1 read [interval] + resfrag1 = restriction fragment overlapping the R1 read [interval] interactionType : Type of interaction from get_interaction_type() [str] """ @@ -463,7 +454,7 @@ def get_interaction_type(read1, read1_chrom, resfrag1, read2, def get_read_tag(read, tag): - for t in read.tags: + for t in read.get_tags(): if t[0] == tag: return t[1] return None @@ -520,16 +511,16 @@ def get_read_tag(read, tag): # Verbose mode if verbose: - print "## overlapMapped2HiCFragments.py" - print "## mappedReadsFile=", mappedReadsFile - print "## fragmentFile=", fragmentFile - print "## minInsertSize=", minInsertSize - print "## maxInsertSize=", maxInsertSize - print "## minFragSize=", minFragSize - print "## maxFragSize=", maxFragSize - print "## allOuput=", allOutput - print "## SAM ouput=", samOut - print "## verbose=", verbose, "\n" + print("## overlapMapped2HiCFragments.py") + print("## mappedReadsFile=", mappedReadsFile) + print("## fragmentFile=", fragmentFile) + print("## minInsertSize=", minInsertSize) + print("## maxInsertSize=", maxInsertSize) + print("## minFragSize=", minFragSize) + print("## maxFragSize=", maxFragSize) + print("## allOuput=", allOutput) + print("## SAM ouput=", samOut) + print("## verbose={}\n".format(verbose)) # Initialize variables reads_counter = 0 @@ -576,7 +567,7 @@ def get_read_tag(read, tag): # Read the SAM/BAM file if verbose: - print "## Opening SAM/BAM file '", mappedReadsFile, "'..." + print("## Opening SAM/BAM file {} ...".format(mappedReadsFile)) samfile = pysam.Samfile(mappedReadsFile, "rb") if samOut: @@ -585,7 +576,7 @@ def get_read_tag(read, tag): # Reads are 0-based too (for both SAM and BAM format) # Loop on all reads if verbose: - print "## Classifying Interactions ..." + print("## Classifying Interactions ...") for read in samfile.fetch(until_eof=True): reads_counter += 1 @@ -596,7 +587,7 @@ def get_read_tag(read, tag): if read.is_read1: r1 = read if not r1.is_unmapped: - r1_chrom = samfile.getrname(r1.tid) + r1_chrom = samfile.get_reference_name(r1.tid) r1_resfrag = get_overlapping_restriction_fragment(resFrag, r1_chrom, r1) else: r1_resfrag = None @@ -606,7 +597,7 @@ def get_read_tag(read, tag): elif read.is_read2: r2 = read if not r2.is_unmapped: - r2_chrom = samfile.getrname(r2.tid) + r2_chrom = samfile.get_reference_name(r2.tid) r2_resfrag = get_overlapping_restriction_fragment(resFrag, r2_chrom, r2) else: r2_resfrag = None @@ -706,8 +697,8 @@ def get_read_tag(read, tag): if not r1.is_unmapped and not r2.is_unmapped: ##reorient reads to ease duplicates removal or1, or2 = get_ordered_reads(r1, r2) - or1_chrom = samfile.getrname(or1.tid) - or2_chrom = samfile.getrname(or2.tid) + or1_chrom = samfile.get_reference_name(or1.tid) + or2_chrom = samfile.get_reference_name(or2.tid) ##reset as tag now that the reads are oriented r1as = get_read_tag(or1, gtag) @@ -734,7 +725,7 @@ def get_read_tag(read, tag): or2_fragname = 'None' cur_handler.write( - or1.qname + "\t" + + or1.query_name + "\t" + or1_chrom + "\t" + str(get_read_pos(or1)+1) + "\t" + str(get_read_strand(or1)) + "\t" + @@ -753,7 +744,7 @@ def get_read_tag(read, tag): r1_fragname = r1_resfrag.value['name'] cur_handler.write( - r1.qname + "\t" + + r1.query_name + "\t" + r1_chrom + "\t" + str(get_read_pos(r1)+1) + "\t" + str(get_read_strand(r1)) + "\t" + @@ -770,7 +761,7 @@ def get_read_tag(read, tag): r2_fragname = r2_resfrag.value['name'] cur_handler.write( - r2.qname + "\t" + + r2.query_name + "\t" + "*" + "\t" + "*" + "\t" + "*" + "\t" + @@ -791,7 +782,7 @@ def get_read_tag(read, tag): handle_sam.write(r2) if (reads_counter % 100000 == 0 and verbose): - print "##", reads_counter + print("##", reads_counter) # Close handler handle_valid.close() @@ -808,14 +799,10 @@ def get_read_tag(read, tag): handle_stat = open(outputDir + '/' + baseReadsFile + '.RSstat', 'w') handle_stat.write("## Hi-C processing\n") handle_stat.write("Valid_interaction_pairs\t" + str(valid_counter) + "\n") - handle_stat.write( - "Valid_interaction_pairs_FF\t" + str(valid_counter_FF) + "\n") - handle_stat.write( - "Valid_interaction_pairs_RR\t" + str(valid_counter_RR) + "\n") - handle_stat.write( - "Valid_interaction_pairs_RF\t" + str(valid_counter_RF) + "\n") - handle_stat.write( - "Valid_interaction_pairs_FR\t" + str(valid_counter_FR) + "\n") + handle_stat.write("Valid_interaction_pairs_FF\t" + str(valid_counter_FF) + "\n") + handle_stat.write("Valid_interaction_pairs_RR\t" + str(valid_counter_RR) + "\n") + handle_stat.write("Valid_interaction_pairs_RF\t" + str(valid_counter_RF) + "\n") + handle_stat.write("Valid_interaction_pairs_FR\t" + str(valid_counter_FR) + "\n") handle_stat.write("Dangling_end_pairs\t" + str(de_counter) + "\n") handle_stat.write("Religation_pairs\t" + str(re_counter) + "\n") handle_stat.write("Self_Cycle_pairs\t" + str(sc_counter) + "\n") @@ -839,4 +826,3 @@ def get_read_tag(read, tag): if samOut: samfile.close() - diff --git a/bin/mergeSAM.py b/bin/mergeSAM.py index fdf0c67..12917b1 100755 --- a/bin/mergeSAM.py +++ b/bin/mergeSAM.py @@ -19,20 +19,19 @@ import os import re import pysam -from itertools import izip def usage(): """Usage function""" - print "Usage : python mergeSAM.py" - print "-f/--forward " - print "-r/--reverse " - print "[-o/--output] " - print "[-s/--single] " - print "[-m/--multi] " - print "[-q/--qual] " - print "[-t/--stat] " - print "[-v/--verbose] " - print "[-h/--help] " + print("Usage : python mergeSAM.py") + print("-f/--forward ") + print("-r/--reverse ") + print("[-o/--output] ") + print("[-s/--single] ") + print("[-m/--multi] ") + print("[-q/--qual] ") + print("[-t/--stat] ") + print("[-v/--verbose] ") + print("[-h/--help] ") return @@ -53,37 +52,36 @@ def get_args(): def is_unique_bowtie2(read): - ret = False - if not read.is_unmapped and read.has_tag('AS'): - if read.has_tag('XS'): - primary = read.get_tag('AS') - secondary = read.get_tag('XS') - if (primary > secondary): - ret = True - else: - ret = True - - return ret + ret = False + if not read.is_unmapped and read.has_tag('AS'): + if read.has_tag('XS'): + primary = read.get_tag('AS') + secondary = read.get_tag('XS') + if (primary > secondary): + ret = True + else: + ret = True + return ret ## Remove everything after "/" or " " in read's name def get_read_name(read): - name = read.qname + name = read.query_name #return name.split("/",1)[0] return re.split('/| ', name)[0] def sam_flag(read1, read2, hr1, hr2): + + f1 = read1.flag + f2 = read2.flag - f1 = read1.flag - f2 = read2.flag - - if r1.is_unmapped == False: - r1_chrom = hr1.getrname(r1.tid) - else: - r1_chrom="*" - if r2.is_unmapped == False: - r2_chrom = hr2.getrname(r2.tid) - else: - r2_chrom="*" + if r1.is_unmapped == False: + r1_chrom = hr1.get_reference_name(r1.reference_id) + else: + r1_chrom = "*" + if r2.is_unmapped == False: + r2_chrom = hr2.get_reference_name(r2.reference_id) + else: + r2_chrom="*" ##Relevant bitwise flags (flag in an 11-bit binary number) @@ -101,226 +99,221 @@ def sam_flag(read1, read2, hr1, hr2): ##Output example: a paired-end read that aligns to the reverse strand ##and is the first mate in the pair will have flag 83 (= 64 + 16 + 2 + 1) - if f1 & 0x4: - f1 = f1 | 0x8 + if f1 & 0x4: + f1 = f1 | 0x8 - if f2 & 0x4: - f2 = f2 | 0x8 + if f2 & 0x4: + f2 = f2 | 0x8 - if (not (f1 & 0x4) and not (f2 & 0x4)): + if (not (f1 & 0x4) and not (f2 & 0x4)): ##The flag should now indicate this is paired-end data - f1 = f1 | 0x1 - f1 = f1 | 0x2 - f2 = f2 | 0x1 - f2 = f2 | 0x2 + f1 = f1 | 0x1 + f1 = f1 | 0x2 + f2 = f2 | 0x1 + f2 = f2 | 0x2 ##Indicate if the pair is on the reverse strand - if f1 & 0x10: - f2 = f2 | 0x20 + if f1 & 0x10: + f2 = f2 | 0x20 - if f2 & 0x10: - f1 = f1 | 0x20 + if f2 & 0x10: + f1 = f1 | 0x20 ##Is this first or the second pair? - f1 = f1 | 0x40 - f2 = f2 | 0x80 + f1 = f1 | 0x40 + f2 = f2 | 0x80 ##Insert the modified bitwise flags into the reads - read1.flag = f1 - read2.flag = f2 - - ##Determine the RNEXT and PNEXT values (i.e. the positional values of a read's pair) - #RNEXT - if r1_chrom == r2_chrom: - read1.rnext = r1.tid - read2.rnext = r1.tid - else: - read1.rnext = r2.tid - read2.rnext = r1.tid - - #PNEXT - read1.pnext = read2.pos - read2.pnext = read1.pos - - return(read1, read2) + read1.flag = f1 + read2.flag = f2 + + ##Determine the RNEXT and PNEXT values (i.e. the positional values of a read's pair) + #RNEXT + if r1_chrom == r2_chrom: + read1.next_reference_id = r1.reference_id + read2.next_reference_id = r1.reference_id + else: + read1.next_reference_id = r2.reference_id + read2.next_reference_id = r1.reference_id + #PNEXT + read1.next_reference_start = read2.reference_start + read2.next_reference_start = read1.reference_start + + return(read1, read2) if __name__ == "__main__": ## Read command line arguments - opts = get_args() - inputFile = None - outputFile = None - mapq = None - report_single = False - report_multi = False - verbose = False - stat = False - output = "-" - - if len(opts) == 0: - usage() - sys.exit() - - for opt, arg in opts: - if opt in ("-h", "--help"): - usage() - sys.exit() - elif opt in ("-f", "--forward"): - R1file = arg - elif opt in ("-r", "--reverse"): - R2file = arg - elif opt in ("-o", "--output"): - output = arg - elif opt in ("-q", "--qual"): - mapq = arg - elif opt in ("-s", "--single"): - report_single = True - elif opt in ("-m", "--multi"): - report_multi = True - elif opt in ("-t", "--stat"): - stat = True - elif opt in ("-v", "--verbose"): - verbose = True - else: - assert False, "unhandled option" + opts = get_args() + inputFile = None + outputFile = None + mapq = None + report_single = False + report_multi = False + verbose = False + stat = False + output = "-" + + if len(opts) == 0: + usage() + sys.exit() + + for opt, arg in opts: + if opt in ("-h", "--help"): + usage() + sys.exit() + elif opt in ("-f", "--forward"): + R1file = arg + elif opt in ("-r", "--reverse"): + R2file = arg + elif opt in ("-o", "--output"): + output = arg + elif opt in ("-q", "--qual"): + mapq = arg + elif opt in ("-s", "--single"): + report_single = True + elif opt in ("-m", "--multi"): + report_multi = True + elif opt in ("-t", "--stat"): + stat = True + elif opt in ("-v", "--verbose"): + verbose = True + else: + assert False, "unhandled option" ## Verbose mode - if verbose: - print "## mergeBAM.py" - print "## forward=", R1file - print "## reverse=", R2file - print "## output=", output - print "## min mapq=", mapq - print "## report_single=", report_single - print "## report_multi=", report_multi - print "## verbose=", verbose + if verbose: + print("## mergeBAM.py") + print("## forward=", R1file) + print("## reverse=", R2file) + print("## output=", output) + print("## min mapq=", mapq) + print("## report_single=", report_single) + print("## report_multi=", report_multi) + print("## verbose=", verbose) ## Initialize variables - tot_pairs_counter = 0 - multi_pairs_counter = 0 - uniq_pairs_counter = 0 - unmapped_pairs_counter = 0 - lowq_pairs_counter = 0 - multi_singles_counter = 0 - uniq_singles_counter = 0 - lowq_singles_counter = 0 + tot_pairs_counter = 0 + multi_pairs_counter = 0 + uniq_pairs_counter = 0 + unmapped_pairs_counter = 0 + lowq_pairs_counter = 0 + multi_singles_counter = 0 + uniq_singles_counter = 0 + lowq_singles_counter = 0 #local_counter = 0 - paired_reads_counter = 0 - singleton_counter = 0 - reads_counter = 0 - r1 = None - r2 = None + paired_reads_counter = 0 + singleton_counter = 0 + reads_counter = 0 + r1 = None + r2 = None ## Reads are 0-based too (for both SAM and BAM format) ## Loop on all reads - if verbose: - print "## Merging forward and reverse tags ..." - - with pysam.Samfile(R1file, "rb") as hr1, pysam.Samfile(R2file, "rb") as hr2: - if output == "-": - outfile = pysam.AlignmentFile(output, "w", template=hr1) - else: - outfile = pysam.AlignmentFile(output, "wb", template=hr1) - for r1, r2 in izip(hr1.fetch(until_eof=True), hr2.fetch(until_eof=True)): - reads_counter +=1 + if verbose: + print("## Merging forward and reverse tags ...") + with pysam.Samfile(R1file, "rb") as hr1, pysam.Samfile(R2file, "rb") as hr2: + if output == "-": + outfile = pysam.AlignmentFile(output, "w", template=hr1) + else: + outfile = pysam.AlignmentFile(output, "wb", template=hr1) + for r1, r2 in zip(hr1.fetch(until_eof=True), hr2.fetch(until_eof=True)): + reads_counter +=1 #print r1 #print r2 #print hr1.getrname(r1.tid) #print hr2.getrname(r2.tid) - if (reads_counter % 1000000 == 0 and verbose): - print "##", reads_counter + if (reads_counter % 1000000 == 0 and verbose): + print("##", reads_counter) - if get_read_name(r1) == get_read_name(r2): + if get_read_name(r1) == get_read_name(r2): ## both unmapped - if r1.is_unmapped == True and r2.is_unmapped == True: - unmapped_pairs_counter += 1 - continue + if r1.is_unmapped == True and r2.is_unmapped == True: + unmapped_pairs_counter += 1 + continue ## both mapped - elif r1.is_unmapped == False and r2.is_unmapped == False: + elif r1.is_unmapped == False and r2.is_unmapped == False: ## quality - if mapq != None and (r1.mapping_quality < int(mapq) or r2.mapping_quality < int(mapq)): - lowq_pairs_counter += 1 - continue + if mapq != None and (r1.mapping_quality < int(mapq) or r2.mapping_quality < int(mapq)): + lowq_pairs_counter += 1 + continue ## Unique mapping - if is_unique_bowtie2(r1) == True and is_unique_bowtie2(r2) == True: - uniq_pairs_counter += 1 - else: - multi_pairs_counter += 1 - if report_multi == False: - continue + if is_unique_bowtie2(r1) == True and is_unique_bowtie2(r2) == True: + uniq_pairs_counter += 1 + else: + multi_pairs_counter += 1 + if report_multi == False: + continue # one end mapped, other is not - else: - singleton_counter += 1 - if report_single == False: - continue - if r1.is_unmapped == False: ## first end is mapped, second is not + else: + singleton_counter += 1 + if report_single == False: + continue + if r1.is_unmapped == False: ## first end is mapped, second is not ## quality - if mapq != None and (r1.mapping_quality < int(mapq)): - lowq_singles_counter += 1 - continue + if mapq != None and (r1.mapping_quality < int(mapq)): + lowq_singles_counter += 1 + continue ## Unique mapping - if is_unique_bowtie2(r1) == True: - uniq_singles_counter += 1 - else: - multi_singles_counter += 1 - if report_multi == False: - continue - else: ## second end is mapped, first is not + if is_unique_bowtie2(r1) == True: + uniq_singles_counter += 1 + else: + multi_singles_counter += 1 + if report_multi == False: + continue + else: ## second end is mapped, first is not ## quality - if mapq != None and (r2.mapping_quality < int(mapq)): - lowq_singles_counter += 1 - continue + if mapq != None and (r2.mapping_quality < int(mapq)): + lowq_singles_counter += 1 + continue ## Unique mapping - if is_unique_bowtie2(r2) == True: - uniq_singles_counter += 1 - else: - multi_singles_counter += 1 - if report_multi == False: - continue + if is_unique_bowtie2(r2) == True: + uniq_singles_counter += 1 + else: + multi_singles_counter += 1 + if report_multi == False: + continue - tot_pairs_counter += 1 - (r1, r2) = sam_flag(r1,r2, hr1, hr2) + tot_pairs_counter += 1 + (r1, r2) = sam_flag(r1,r2, hr1, hr2) #print hr1.getrname(r1.tid) #print hr2.getrname(r2.tid) #print r1 #print r2 ## Write output - outfile.write(r1) - outfile.write(r2) - - else: - print "Forward and reverse reads not paired. Check that BAM files have the same read names and are sorted." - sys.exit(1) - - if stat: - if output == '-': - statfile = "pairing.stat" - else: - statfile = re.sub('\.bam$', '.pairstat', output) - handle_stat = open(statfile, 'w') - - handle_stat.write("Total_pairs_processed\t" + str(reads_counter) + "\t" + str(round(float(reads_counter)/float(reads_counter)*100,3)) + "\n") - handle_stat.write("Unmapped_pairs\t" + str(unmapped_pairs_counter) + "\t" + str(round(float(unmapped_pairs_counter)/float(reads_counter)*100,3)) + "\n") - handle_stat.write("Low_qual_pairs\t" + str(lowq_pairs_counter) + "\t" + str(round(float(lowq_pairs_counter)/float(reads_counter)*100,3)) + "\n") - handle_stat.write("Unique_paired_alignments\t" + str(uniq_pairs_counter) + "\t" + str(round(float(uniq_pairs_counter)/float(reads_counter)*100,3)) + "\n") - handle_stat.write("Multiple_pairs_alignments\t" + str(multi_pairs_counter) + "\t" + str(round(float(multi_pairs_counter)/float(reads_counter)*100,3)) + "\n") - handle_stat.write("Pairs_with_singleton\t" + str(singleton_counter) + "\t" + str(round(float(singleton_counter)/float(reads_counter)*100,3)) + "\n") - handle_stat.write("Low_qual_singleton\t" + str(lowq_singles_counter) + "\t" + str(round(float(lowq_singles_counter)/float(reads_counter)*100,3)) + "\n") - handle_stat.write("Unique_singleton_alignments\t" + str(uniq_singles_counter) + "\t" + str(round(float(uniq_singles_counter)/float(reads_counter)*100,3)) + "\n") - handle_stat.write("Multiple_singleton_alignments\t" + str(multi_singles_counter) + "\t" + str(round(float(multi_singles_counter)/float(reads_counter)*100,3)) + "\n") - handle_stat.write("Reported_pairs\t" + str(tot_pairs_counter) + "\t" + str(round(float(tot_pairs_counter)/float(reads_counter)*100,3)) + "\n") - handle_stat.close() - - hr1.close() - hr2.close() - outfile.close() + outfile.write(r1) + outfile.write(r2) + + else: + print("Forward and reverse reads not paired. Check that BAM files have the same read names and are sorted.") + sys.exit(1) + + if stat: + if output == '-': + statfile = "pairing.stat" + else: + statfile = re.sub('\.bam$', '.pairstat', output) + with open(statfile, 'w') as handle_stat: + handle_stat.write("Total_pairs_processed\t" + str(reads_counter) + "\t" + str(round(float(reads_counter)/float(reads_counter)*100,3)) + "\n") + handle_stat.write("Unmapped_pairs\t" + str(unmapped_pairs_counter) + "\t" + str(round(float(unmapped_pairs_counter)/float(reads_counter)*100,3)) + "\n") + handle_stat.write("Low_qual_pairs\t" + str(lowq_pairs_counter) + "\t" + str(round(float(lowq_pairs_counter)/float(reads_counter)*100,3)) + "\n") + handle_stat.write("Unique_paired_alignments\t" + str(uniq_pairs_counter) + "\t" + str(round(float(uniq_pairs_counter)/float(reads_counter)*100,3)) + "\n") + handle_stat.write("Multiple_pairs_alignments\t" + str(multi_pairs_counter) + "\t" + str(round(float(multi_pairs_counter)/float(reads_counter)*100,3)) + "\n") + handle_stat.write("Pairs_with_singleton\t" + str(singleton_counter) + "\t" + str(round(float(singleton_counter)/float(reads_counter)*100,3)) + "\n") + handle_stat.write("Low_qual_singleton\t" + str(lowq_singles_counter) + "\t" + str(round(float(lowq_singles_counter)/float(reads_counter)*100,3)) + "\n") + handle_stat.write("Unique_singleton_alignments\t" + str(uniq_singles_counter) + "\t" + str(round(float(uniq_singles_counter)/float(reads_counter)*100,3)) + "\n") + handle_stat.write("Multiple_singleton_alignments\t" + str(multi_singles_counter) + "\t" + str(round(float(multi_singles_counter)/float(reads_counter)*100,3)) + "\n") + handle_stat.write("Reported_pairs\t" + str(tot_pairs_counter) + "\t" + str(round(float(tot_pairs_counter)/float(reads_counter)*100,3)) + "\n") + hr1.close() + hr2.close() + outfile.close() diff --git a/conf/base.config b/conf/base.config index 021b3f4..d655a76 100644 --- a/conf/base.config +++ b/conf/base.config @@ -25,23 +25,26 @@ process { // nf-core: Customise requirements for specific processes. // See https://www.nextflow.io/docs/latest/config.html#config-process-selectors withLabel:process_low { - cpus = { check_max( 2 * task.attempt, 'cpus' ) } - memory = { check_max( 14.GB * task.attempt, 'memory' ) } + cpus = { check_max( 1 * task.attempt, 'cpus' ) } + memory = { check_max( 4.GB * task.attempt, 'memory' ) } time = { check_max( 6.h * task.attempt, 'time' ) } } withLabel:process_medium { - cpus = { check_max( 6 * task.attempt, 'cpus' ) } - memory = { check_max( 42.GB * task.attempt, 'memory' ) } + cpus = { check_max( 4 * task.attempt, 'cpus' ) } + memory = { check_max( 8.GB * task.attempt, 'memory' ) } time = { check_max( 8.h * task.attempt, 'time' ) } } withLabel:process_high { - cpus = { check_max( 12 * task.attempt, 'cpus' ) } - memory = { check_max( 84.GB * task.attempt, 'memory' ) } + cpus = { check_max( 8 * task.attempt, 'cpus' ) } + memory = { check_max( 64.GB * task.attempt, 'memory' ) } time = { check_max( 10.h * task.attempt, 'time' ) } } withLabel:process_long { time = { check_max( 20.h * task.attempt, 'time' ) } } + withLabel:process_highmem { + memory = { check_max( 12.GB * task.attempt, 'memory' ) } + } withName:get_software_versions { cache = false } diff --git a/environment.yml b/environment.yml index c1e113e..9d0d609 100644 --- a/environment.yml +++ b/environment.yml @@ -6,16 +6,13 @@ channels: - bioconda - defaults dependencies: - - python=2.7.15 - - pip=19.1 - - scipy=1.2.1 - - numpy=1.16.3 - - r-markdown=0.9 - - bx-python=0.8.2 - - pysam=0.15.2 - - cooler=0.8.5 - - bowtie2=2.3.5 - - samtools=1.9 - - multiqc=1.7 - - pip: - - iced==0.5.1 + - conda-forge::python=3.7.6 + - conda-forge::scipy=1.4.1 + - conda-forge::numpy=1.18.1 + - bioconda::iced=0.5.4 + - bioconda::bx-python=0.8.8 + - bioconda::pysam=0.15.4 + - bioconda::cooler=0.8.6 + - bioconda::bowtie2=2.3.5 + - bioconda::samtools=1.9 + - bioconda::multiqc=1.8 diff --git a/main.nf b/main.nf index 18c0526..85b4154 100644 --- a/main.nf +++ b/main.nf @@ -21,62 +21,64 @@ def helpMessage() { nextflow run nf-core/hic --reads '*_R{1,2}.fastq.gz' -profile conda Mandatory arguments: - --reads Path to input data (must be surrounded with quotes) - -profile Configuration profile to use. Can use multiple (comma separated) - Available: conda, docker, singularity, awsbatch, test and more. - - References If not specified in the configuration file or you wish to overwrite any of the references. - --genome Name of iGenomes reference - --bwt2_index Path to Bowtie2 index - --fasta Path to Fasta reference - --chromosome_size Path to chromosome size file - --restriction_fragments Path to restriction fragment file (bed) - --saveReference Save reference genome to output folder. Default: False - --saveAlignedIntermediates Save intermediates alignment files. Default: False + --reads [file] Path to input data (must be surrounded with quotes) + -profile [str] Configuration profile to use. Can use multiple (comma separated) + Available: conda, docker, singularity, awsbatch, test and more. + + References If not specified in the configuration file or you wish to overwrite any of the references. + --genome [str] Name of iGenomes reference + --bwt2_index [file] Path to Bowtie2 index + --fasta [file] Path to Fasta reference + --chromosome_size [file] Path to chromosome size file + --restriction_fragments [file] Path to restriction fragment file (bed) + --save_reference [bool] Save reference genome to output folder. Default: False + --save_aligned_intermediates [bool] Save intermediates alignment files. Default: False Alignments - --bwt2_opts_end2end Options for bowtie2 end-to-end mappinf (first mapping step). See hic.config for default. - --bwt2_opts_trimmed Options for bowtie2 mapping after ligation site trimming. See hic.config for default. - --min_mapq Minimum mapping quality values to consider. Default: 10 - --restriction_site Cutting motif(s) of restriction enzyme(s) (comma separated). Default: 'A^AGCTT' - --ligation_site Ligation motifs to trim (comma separated). Default: 'AAGCTAGCTT' - --rm_singleton Remove singleton reads. Default: true - --rm_multi Remove multi-mapped reads. Default: true - --rm_dup Remove duplicates. Default: true + --bwt2_opts_end2end [str] Options for bowtie2 end-to-end mappinf (first mapping step). See hic.config for default. + --bwt2_opts_trimmed [str] Options for bowtie2 mapping after ligation site trimming. See hic.config for default. + --min_mapq [int] Minimum mapping quality values to consider. Default: 10 + --restriction_site [str] Cutting motif(s) of restriction enzyme(s) (comma separated). Default: 'A^AGCTT' + --ligation_site [str] Ligation motifs to trim (comma separated). Default: 'AAGCTAGCTT' + --rm_singleton [bool] Remove singleton reads. Default: true + --rm_multi [bool] Remove multi-mapped reads. Default: true + --rm_dup [bool] Remove duplicates. Default: true Contacts calling - --min_restriction_fragment_size Minimum size of restriction fragments to consider. Default: None - --max_restriction_fragment_size Maximum size of restriction fragments to consider. Default: None - --min_insert_size Minimum insert size of mapped reads to consider. Default: None - --max_insert_size Maximum insert size of mapped reads to consider. Default: None - --saveInteractionBAM Save BAM file with interaction tags (dangling-end, self-circle, etc.). Default: False + --min_restriction_fragment_size [int] Minimum size of restriction fragments to consider. Default: None + --max_restriction_fragment_size [int] Maximum size of restriction fragments to consider. Default: None + --min_insert_size [int] Minimum insert size of mapped reads to consider. Default: None + --max_insert_size [int] Maximum insert size of mapped reads to consider. Default: None + --save_interaction_bam [bool] Save BAM file with interaction tags (dangling-end, self-circle, etc.). Default: False - --dnase Run DNase Hi-C mode. All options related to restriction fragments are not considered. Default: False - --min_cis_dist Minimum intra-chromosomal distance to consider. Default: None + --dnase [bool] Run DNase Hi-C mode. All options related to restriction fragments are not considered. Default: False + --min_cis_dist [int] Minimum intra-chromosomal distance to consider. Default: None Contact maps - --bin_size Bin size for contact maps (comma separated). Default: '1000000,500000' - --ice_max_iter Maximum number of iteration for ICE normalization. Default: 100 - --ice_filter_low_count_perc Percentage of low counts columns/rows to filter before ICE normalization. Default: 0.02 - --ice_filter_high_count_perc Percentage of high counts columns/rows to filter before ICE normalization. Default: 0 - --ice_eps Convergence criteria for ICE normalization. Default: 0.1 + --bin_size [int] Bin size for contact maps (comma separated). Default: '1000000,500000' + --ice_max_iter [int] Maximum number of iteration for ICE normalization. Default: 100 + --ice_filter_low_count_perc [float] Percentage of low counts columns/rows to filter before ICE normalization. Default: 0.02 + --ice_filter_high_count_perc [float] Percentage of high counts columns/rows to filter before ICE normalization. Default: 0 + --ice_eps [float] Convergence criteria for ICE normalization. Default: 0.1 Workflow - --skipMaps Skip generation of contact maps. Useful for capture-C. Default: False - --skipIce Skip ICE normalization. Default: False - --skipCool Skip generation of cool files. Default: False - --skipMultiQC Skip MultiQC. Default: False + --skip_maps [bool] Skip generation of contact maps. Useful for capture-C. Default: False + --skip_ice [bool] Skip ICE normalization. Default: False + --skip_cool [bool] Skip generation of cool files. Default: False + --skip_multiqc [bool] Skip MultiQC. Default: False Other - --splitFastq Size of read chuncks to use to speed up the workflow. Default: None - --outdir The output directory where the results will be saved. Default: './results' - --email Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits. Default: None - -name Name for the pipeline run. If not specified, Nextflow will automatically generate a random mnemonic. Default: None + --split_fastq [bool] Size of read chuncks to use to speed up the workflow. Default: None + --outdir [file] The output directory where the results will be saved. Default: './results' + --email [email] Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits. Default: None + --email_on_fail [email] Same as --email, except only send mail if the workflow is not successful + --max_multiqc_email_size [str] Theshold size for MultiQC report to be attached in notification email. If file generated by pipeline exceeds the threshold, it will not be attached (Default: 25MB) + -name [str] Name for the pipeline run. If not specified, Nextflow will automatically generate a random mnemonic. Default: None AWSBatch - --awsqueue The AWSBatch JobQueue that needs to be set when running on AWSBatch - --awsregion The AWS Region for your AWS Batch job to run on + --awsqueue [str] The AWSBatch JobQueue that needs to be set when running on AWSBatch + --awsregion [str] The AWS Region for your AWS Batch job to run on """.stripIndent() } @@ -152,7 +154,7 @@ if (params.readPaths){ .separate( raw_reads, raw_reads_2 ) { a -> [tuple(a[0], a[1][0]), tuple(a[0], a[1][1])] } } -if ( params.splitFastq ){ +if ( params.split_fastq ){ raw_reads_full = raw_reads.concat( raw_reads_2 ) raw_reads = raw_reads_full.splitFastq( by: params.splitFastq , file: true) }else{ @@ -191,7 +193,6 @@ else { } // Chromosome size - if ( params.chromosome_size ){ Channel.fromPath( params.chromosome_size , checkIfExists: true) .into {chromosome_size; chromosome_size_cool} @@ -236,7 +237,7 @@ def summary = [:] if(workflow.revision) summary['Pipeline Release'] = workflow.revision summary['Run Name'] = custom_runName ?: workflow.runName summary['Reads'] = params.reads -summary['splitFastq'] = params.splitFastq +summary['splitFastq'] = params.split_fastq summary['Fasta Ref'] = params.fasta summary['Restriction Motif']= params.restriction_site summary['Ligation Motif'] = params.ligation_site @@ -249,7 +250,6 @@ summary['Min Insert Size'] = params.min_insert_size summary['Max Insert Size'] = params.max_insert_size summary['Min CIS dist'] = params.min_cis_dist summary['Maps resolution'] = params.bin_size - summary['Max Memory'] = params.max_memory summary['Max CPUs'] = params.max_cpus summary['Max Time'] = params.max_time @@ -333,8 +333,9 @@ process get_software_versions { if(!params.bwt2_index && params.fasta){ process makeBowtie2Index { tag "$bwt2_base" - publishDir path: { params.saveReference ? "${params.outdir}/reference_genome" : params.outdir }, - saveAs: { params.saveReference ? it : null }, mode: 'copy' + label 'process_highmem' + publishDir path: { params.save_reference ? "${params.outdir}/reference_genome" : params.outdir }, + saveAs: { params.save_reference ? it : null }, mode: 'copy' input: file fasta from fasta_for_index @@ -356,8 +357,9 @@ if(!params.bwt2_index && params.fasta){ if(!params.chromosome_size && params.fasta){ process makeChromSize { tag "$fasta" - publishDir path: { params.saveReference ? "${params.outdir}/reference_genome" : params.outdir }, - saveAs: { params.saveReference ? it : null }, mode: 'copy' + label 'process_low'' + publishDir path: { params.save_reference ? "${params.outdir}/reference_genome" : params.outdir }, + saveAs: { params.save_reference ? it : null }, mode: 'copy' input: file fasta from fasta_for_chromsize @@ -375,9 +377,10 @@ if(!params.chromosome_size && params.fasta){ if(!params.restriction_fragments && params.fasta && !params.dnase){ process getRestrictionFragments { - tag "$fasta - ${params.restriction_site}" - publishDir path: { params.saveReference ? "${params.outdir}/reference_genome" : params.outdir }, - saveAs: { params.saveReference ? it : null }, mode: 'copy' + tag "$fasta ${params.restriction_site}" + label 'process_low' + publishDir path: { params.save_reference ? "${params.outdir}/reference_genome" : params.outdir }, + saveAs: { params.save_reference ? it : null }, mode: 'copy' input: file fasta from fasta_for_resfrag @@ -402,8 +405,9 @@ if(!params.restriction_fragments && params.fasta && !params.dnase){ process bowtie2_end_to_end { tag "$prefix" - publishDir path: { params.saveAlignedIntermediates ? "${params.outdir}/mapping" : params.outdir }, - saveAs: { params.saveAlignedIntermediates ? it : null }, mode: 'copy' + label 'process_medium' + publishDir path: { params.save_aligned_intermediates ? "${params.outdir}/mapping" : params.outdir }, + saveAs: { params.save_aligned_intermediates ? it : null }, mode: 'copy' input: set val(sample), file(reads) from raw_reads @@ -440,8 +444,9 @@ process bowtie2_end_to_end { process trim_reads { tag "$prefix" - publishDir path: { params.saveAlignedIntermediates ? "${params.outdir}/mapping" : params.outdir }, - saveAs: { params.saveAlignedIntermediates ? it : null }, mode: 'copy' + label 'process_low' + publishDir path: { params.save_aligned_intermediates ? "${params.outdir}/mapping" : params.outdir }, + saveAs: { params.save_aligned_intermediates ? it : null }, mode: 'copy' when: !params.dnase @@ -462,8 +467,9 @@ process trim_reads { process bowtie2_on_trimmed_reads { tag "$prefix" - publishDir path: { params.saveAlignedIntermediates ? "${params.outdir}/mapping" : params.outdir }, - saveAs: { params.saveAlignedIntermediates ? it : null }, mode: 'copy' + label 'process_medium' + publishDir path: { params.save_aligned_intermediates ? "${params.outdir}/mapping" : params.outdir }, + saveAs: { params.save_aligned_intermediates ? it : null }, mode: 'copy' when: !params.dnase @@ -489,8 +495,9 @@ process bowtie2_on_trimmed_reads { if (!params.dnase){ process merge_mapping_steps{ tag "$sample = $bam1 + $bam2" - publishDir path: { params.saveAlignedIntermediates ? "${params.outdir}/mapping" : params.outdir }, - saveAs: { params.saveAlignedIntermediates ? it : null }, mode: 'copy' + label 'process_medium' + publishDir path: { params.save_aligned_intermediates ? "${params.outdir}/mapping" : params.outdir }, + saveAs: { params.save_aligned_intermediates ? it : null }, mode: 'copy' input: set val(prefix), file(bam1), file(bam2) from end_to_end_bam.join( trimmed_bam ) @@ -529,8 +536,9 @@ if (!params.dnase){ }else{ process dnase_mapping_stats{ tag "$sample = $bam1" - publishDir path: { params.saveAlignedIntermediates ? "${params.outdir}/mapping" : params.outdir }, - saveAs: { params.saveAlignedIntermediates ? it : null }, mode: 'copy' + label 'process_medium' + publishDir path: { params.save_aligned_intermediates ? "${params.outdir}/mapping" : params.outdir }, + saveAs: { params.save_aligned_intermediates ? it : null }, mode: 'copy' input: set val(prefix), file(bam1) from end_to_end_bam @@ -556,10 +564,9 @@ if (!params.dnase){ } } -println(bwt2_merged_bam) - process combine_mapped_files{ tag "$sample = $r1_prefix + $r2_prefix" + label 'process_low' publishDir "${params.outdir}/mapping", mode: 'copy', saveAs: {filename -> filename.indexOf(".pairstat") > 0 ? "stats/$filename" : "$filename"} @@ -594,6 +601,7 @@ process combine_mapped_files{ if (!params.dnase){ process get_valid_interaction{ tag "$sample" + label 'process_low' publishDir "${params.outdir}/hic_results/data", mode: 'copy', saveAs: {filename -> filename.indexOf("*stat") > 0 ? "stats/$filename" : "$filename"} @@ -611,7 +619,7 @@ if (!params.dnase){ set val(sample), file("*RSstat") into all_rsstat script: - if (params.splitFastq){ + if (params.split_fastq){ sample = sample.toString() - ~/(\.[0-9]+)$/ } @@ -621,7 +629,7 @@ if (!params.dnase){ if ("$params.max_insert_size".isInteger()) opts="${opts} -l ${params.max_insert_size}" if ("$params.min_restriction_fragment_size".isInteger()) opts="${opts} -t ${params.min_restriction_fragment_size}" if ("$params.max_restriction_fragment_size".isInteger()) opts="${opts} -m ${params.max_restriction_fragment_size}" - if (params.saveInteractionBAM) opts="${opts} --sam" + if (params.save_interaction_bam) opts="${opts} --sam" """ mapped_2hic_fragments.py -f ${frag_file} -r ${pe_bam} --all ${opts} """ @@ -630,6 +638,7 @@ if (!params.dnase){ else{ process get_valid_interaction_dnase{ tag "$sample" + label 'process_low' publishDir "${params.outdir}/hic_results/data", mode: 'copy', saveAs: {filename -> filename.indexOf("*stat") > 0 ? "stats/$filename" : "$filename"} @@ -642,7 +651,7 @@ else{ set val(sample), file("*RSstat") into all_rsstat script: - if (params.splitFastq){ + if (params.split_fastq){ sample = sample.toString() - ~/(\.[0-9]+)$/ } @@ -661,6 +670,7 @@ else{ process remove_duplicates { tag "$sample" + label 'process_highmem' publishDir "${params.outdir}/hic_results/data", mode: 'copy', saveAs: {filename -> filename.indexOf("*stat") > 0 ? "stats/$sample/$filename" : "$filename"} @@ -707,6 +717,7 @@ process remove_duplicates { process merge_sample { tag "$ext" + label 'process_low' publishDir "${params.outdir}/hic_results/stats/${sample}", mode: 'copy' input: @@ -726,13 +737,13 @@ process merge_sample { """ } - process build_contact_maps{ tag "$sample - $mres" + label 'process_highmem' publishDir "${params.outdir}/hic_results/matrix/raw", mode: 'copy' when: - !params.skipMaps + !params.skip_maps input: set val(sample), file(vpairs), val(mres) from all_valid_pairs.combine(map_res) @@ -754,10 +765,11 @@ process build_contact_maps{ process run_ice{ tag "$rmaps" + label 'process_highmem' publishDir "${params.outdir}/hic_results/matrix/iced", mode: 'copy' when: - !params.skipMaps && !params.skipIce + !params.skip_maps && !params.skip_ice input: file(rmaps) from raw_maps @@ -782,10 +794,11 @@ process run_ice{ */ process generate_cool{ tag "$sample" + label 'process_medium' publishDir "${params.outdir}/export/cool", mode: 'copy' when: - !params.skipCool + !params.skip_cool input: set val(sample), file(vpairs) from all_valid_pairs_4cool @@ -805,10 +818,11 @@ process generate_cool{ * STEP 6 - MultiQC */ process multiqc { + label 'process_low' publishDir "${params.outdir}/MultiQC", mode: 'copy' when: - !params.skipMultiQC + !params.skip_multiQC input: file multiqc_config from ch_multiqc_config From 73c6b105d2ce2205c6a0e17ca1f2222260d8fb52 Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 12 May 2020 11:14:23 +0200 Subject: [PATCH 14/36] [MODIF] adjust for test profile --- bin/ice | 124 ----------------------------------------- bin/merge_statfiles.py | 20 +++---- environment.yml | 3 +- main.nf | 28 ++++++++-- nextflow.config | 16 ++++-- 5 files changed, 46 insertions(+), 145 deletions(-) delete mode 100755 bin/ice diff --git a/bin/ice b/bin/ice deleted file mode 100755 index 10f5f22..0000000 --- a/bin/ice +++ /dev/null @@ -1,124 +0,0 @@ -#! /usr/bin/env python - -import sys -import argparse -import numpy as np -from scipy import sparse - -import iced -from iced.io import loadtxt, savetxt - - -parser = argparse.ArgumentParser("ICE normalization") -parser.add_argument('filename', - metavar='File to load', - type=str, - help='Path to file of contact counts to load') -parser.add_argument("--results_filename", - "-r", - type=str, - default=None, - help="results_filename") -parser.add_argument("--filtering_perc", "-f", - type=float, - default=None, - help="Percentage of reads to filter out") -parser.add_argument("--filter_low_counts_perc", - type=float, - default=0.02, - help="Percentage of reads to filter out") -parser.add_argument("--filter_high_counts_perc", - type=float, - default=0, - help="Percentage of reads to filter out") -parser.add_argument("--remove-all-zeros-loci", default=False, - action="store_true", - help="If provided, all non-interacting loci will be " - "removed prior to the filtering strategy chosen.") -parser.add_argument("--max_iter", "-m", default=100, type=int, - help="Maximum number of iterations") -parser.add_argument("--eps", "-e", default=0.1, type=float, - help="Precision") -parser.add_argument("--dense", "-d", default=False, action="store_true") -parser.add_argument("--output-bias", "-b", default=False, help="Output the bias vector") -parser.add_argument("--verbose", "-v", default=False) - - -args = parser.parse_args() -filename = args.filename - -# Deprecating filtering_perc option -filter_low_counts = None -if "--filtering_perc" in sys.argv: - DeprecationWarning( - "Option '--filtering_perc' is deprecated. Please use " - "'--filter_low_counts_perc' instead.'") - # And print it again because deprecation warnings are not displayed for - # recent versions of python - print "--filtering_perc is deprecated. Please use filter_low_counts_perc" - print "instead. This option will be removed in ice 0.3" - filter_low_counts = args.filtering_perc -if "--filter_low_counts_perc" in sys.argv and "--filtering_perc" in sys.argv: - raise Warning("This two options are incompatible") -if "--filtering_perc" is None and "--filter_low_counts_perc" not in sys.argv: - filter_low_counts_perc = 0.02 -elif args.filter_low_counts_perc is not None: - filter_low_counts_perc = args.filter_low_counts_perc - -if args.verbose: - print("Using iced version %s" % iced.__version__) - print "Loading files..." - -# Loads file as i, j, counts -i, j, data = loadtxt(filename).T - -# Detecting whether the file is 0 or 1 based. -if min(i.min(), j.min()) == 0: - index_base = 0 - N = max(i.max(), j.max()) + 1 - counts = sparse.coo_matrix((data, (i, j)), shape=(N, N), dtype=float) -else: - index_base = 1 - N = max(i.max(), j.max()) - counts = sparse.coo_matrix((data, (i - 1, j - 1)), shape=(N, N), dtype=float) - -if args.dense: - counts = np.array(counts.todense()) -else: - counts = sparse.csr_matrix(counts) - -if args.verbose: - print "Normalizing..." - -if filter_low_counts_perc != 0: - counts = iced.filter.filter_low_counts(counts, - percentage=filter_low_counts_perc, - remove_all_zeros_loci=args.remove_all_zeros_loci, - copy=False, sparsity=False, verbose=args.verbose) -if args.filter_high_counts_perc != 0: - counts = iced.filter.filter_high_counts( - counts, - percentage=args.filter_high_counts_perc, - copy=False) - -counts, bias = iced.normalization.ICE_normalization( - counts, max_iter=args.max_iter, copy=False, - verbose=args.verbose, eps=args.eps, output_bias=True) - -if args.results_filename is None: - results_filename = ".".join( - filename.split(".")[:-1]) + "_normalized." + filename.split(".")[-1] -else: - results_filename = args.results_filename - -counts = sparse.coo_matrix(counts) - -if args.verbose: - print "Writing results..." - -savetxt( - results_filename, counts.col + index_base, counts.row + index_base, counts.data) - - -if args.output_bias: - np.savetxt(results_filename + ".biases", bias) diff --git a/bin/merge_statfiles.py b/bin/merge_statfiles.py index ab3d078..469cacd 100755 --- a/bin/merge_statfiles.py +++ b/bin/merge_statfiles.py @@ -1,8 +1,8 @@ #!/usr/bin/env python -## HiC-Pro -## Copyright (c) 2015 Institut Curie -## Author(s): Nicolas Servant, Eric Viara +## nf-core-hic +## Copyright (c) 2020 Institut Curie +## Author(s): Nicolas Servant ## Contact: nicolas.servant@curie.fr ## This software is distributed without any guarantee under the terms of the BSD-3 licence. ## See the LICENCE file for details @@ -36,13 +36,13 @@ def num(s): if li > 0: if args.verbose: - print "## merge_statfiles.py" - print "## Merging "+ str(li)+" files" + print("## merge_statfiles.py") + print("## Merging "+ str(li)+" files") ## Reading first file to get the template template = OrderedDict() if args.verbose: - print "## Use "+infiles[0]+" as template" + print("## Use "+infiles[0]+" as template") with open(infiles[0]) as f: for line in f: if not line.startswith("#"): @@ -51,17 +51,17 @@ def num(s): template[str(lsp[0])] = data if len(template) == 0: - print "Cannot find template files !" + print("Cannot find template files !") sys.exit(1) ## Int are counts / Float are percentage - for fidx in xrange(1, li): + for fidx in list(range(1, li)): with open(infiles[fidx]) as f: for line in f: if not line.startswith("#"): lsp = line.strip().split("\t") if lsp[0] in template: - for i in xrange(1, len(lsp)): + for i in list(range(1, len(lsp))): if isinstance(num(lsp[i]), int): template[lsp[0]][i-1] += num(lsp[i]) else: @@ -77,6 +77,6 @@ def num(s): sys.stdout.write("\n") else: - print "No files to merge - stop" + print("No files to merge - stop") sys.exit(1) diff --git a/environment.yml b/environment.yml index 9d0d609..2680ede 100644 --- a/environment.yml +++ b/environment.yml @@ -9,9 +9,10 @@ dependencies: - conda-forge::python=3.7.6 - conda-forge::scipy=1.4.1 - conda-forge::numpy=1.18.1 - - bioconda::iced=0.5.4 + - bioconda::iced=0.5.6 - bioconda::bx-python=0.8.8 - bioconda::pysam=0.15.4 + - conda-forge::pymdown-extensions=7.1 - bioconda::cooler=0.8.6 - bioconda::bowtie2=2.3.5 - bioconda::samtools=1.9 diff --git a/main.nf b/main.nf index 85b4154..7b6b374 100644 --- a/main.nf +++ b/main.nf @@ -245,7 +245,7 @@ summary['DNase Mode'] = params.dnase summary['Remove Dup'] = params.rm_dup summary['Min MAPQ'] = params.min_mapq summary['Min Fragment Size']= params.min_restriction_fragment_size -summary['Max Fragment Size']= params.max_restriction_framgnet_size +summary['Max Fragment Size']= params.max_restriction_fragment_size summary['Min Insert Size'] = params.min_insert_size summary['Max Insert Size'] = params.max_insert_size summary['Min CIS dist'] = params.min_cis_dist @@ -302,6 +302,7 @@ Channel.from(summary.collect{ [it.key, it.value] }) /* * Parse software version numbers */ + process get_software_versions { publishDir "${params.outdir}/pipeline_info", mode: 'copy', saveAs: {filename -> @@ -325,6 +326,25 @@ process get_software_versions { """ } +def create_workflow_summary(summary) { + + def yaml_file = workDir.resolve('workflow_summary_mqc.yaml') + yaml_file.text = """ + id: 'nf-core-chipseq-summary' + description: " - this information is collected when the pipeline is started." + section_name: 'nf-core/chipseq Workflow Summary' + section_href: 'https://github.com/nf-core/chipseq' + plot_type: 'html' + data: | +
+${summary.collect { k,v -> "
$k
${v ?: 'N/A'}
" }.join("\n")} +
+ """.stripIndent() + + return yaml_file +} + + /**************************************************** * PRE-PROCESSING @@ -357,7 +377,7 @@ if(!params.bwt2_index && params.fasta){ if(!params.chromosome_size && params.fasta){ process makeChromSize { tag "$fasta" - label 'process_low'' + label 'process_low' publishDir path: { params.save_reference ? "${params.outdir}/reference_genome" : params.outdir }, saveAs: { params.save_reference ? it : null }, mode: 'copy' @@ -822,7 +842,7 @@ process multiqc { publishDir "${params.outdir}/MultiQC", mode: 'copy' when: - !params.skip_multiQC + !params.skip_multiqc input: file multiqc_config from ch_multiqc_config @@ -856,7 +876,7 @@ process output_documentation { script: """ - markdown_to_html.r $output_docs results_description.html + markdown_to_html.py $output_docs -o results_description.html """ } diff --git a/nextflow.config b/nextflow.config index ce5c794..b02a4f5 100644 --- a/nextflow.config +++ b/nextflow.config @@ -18,10 +18,14 @@ params { readPaths = false chromosome_size = false restriction_fragments = false - skipMaps = false - skipIce = false - skipCool = false - skipMultiQC = false + skip_maps = false + skip_ice = false + skip_cool = false + skip_multiqc = false + save_reference = false + save_interaction_bam = false + save_aligned_intermediates = false + dnase = false // Boilerplate options @@ -45,8 +49,8 @@ params { config_profile_url = false // Defaults only, expecting to be overwritten - max_memory = 128.GB - max_cpus = 16 + max_memory = 24.GB + max_cpus = 8 max_time = 240.h } From c5ae57db851ca6b549fcd9875637eacfe63713ff Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 12 May 2020 11:37:14 +0200 Subject: [PATCH 15/36] [MODIF] test profile --- conf/test.config | 11 ++++++++++- nextflow.config | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/conf/test.config b/conf/test.config index 0086d3b..e628667 100644 --- a/conf/test.config +++ b/conf/test.config @@ -26,8 +26,17 @@ config_profile_name = 'Hi-C test data from Schalbetter et al. (2017)' fasta = 'https://github.com/nf-core/test-datasets/raw/hic/reference/W303_SGD_2015_JRIU00000000.fsa' restriction_site = 'A^AGCTT' ligation_site = 'AAGCTAGCTT' - min_mapq = 0 + + min_mapq = 2 + rm_dup = true + rm_singleton = true + rm_multi = true + min_restriction_fragment_size = 100 + max_restriction_fragment_size = 100000 + min_insert_size = 100 + max_insert_size = 600 + // Options skipCool = true } diff --git a/nextflow.config b/nextflow.config index b02a4f5..4ad6c94 100644 --- a/nextflow.config +++ b/nextflow.config @@ -27,6 +27,14 @@ params { save_aligned_intermediates = false dnase = false + rm_dup = false + rm_singleton = false + rm_multi = false + min_restriction_fragment_size = false + max_restriction_fragment_size = false + min_insert_size = false + max_insert_size = false + min_cis_dist = false // Boilerplate options name = false From b26a4ffb9e9d03404480a1cb8d10ac321d814213 Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 12 May 2020 12:03:56 +0200 Subject: [PATCH 16/36] [BUG] Fix in rm_dup --- CHANGELOG.md | 4 ++++ main.nf | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c1941a..8f01b70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * Update conda environment file * Update python scripts for python3 +### `Fixed` + +* Fix a bug in rm_dup in file sorting + ### `Deprecated` * --skipMaps, --skipIce, --skipCool, --skipMultiQC are deprecated and replaced by --skip_maps, --skip_ice, --skip_cool, --skip_multiqc diff --git a/main.nf b/main.nf index 7b6b374..872d6e6 100644 --- a/main.nf +++ b/main.nf @@ -650,8 +650,10 @@ if (!params.dnase){ if ("$params.min_restriction_fragment_size".isInteger()) opts="${opts} -t ${params.min_restriction_fragment_size}" if ("$params.max_restriction_fragment_size".isInteger()) opts="${opts} -m ${params.max_restriction_fragment_size}" if (params.save_interaction_bam) opts="${opts} --sam" + prefix = pe_bam.toString() - ~/.bam/ """ mapped_2hic_fragments.py -f ${frag_file} -r ${pe_bam} --all ${opts} + sort -T /tmp/ -k2,2V -k3,3n -k5,5V -k6,6n -o ${prefix}.validPairs ${prefix}.validPairs """ } } @@ -677,8 +679,10 @@ else{ def opts = "" if ("$params.min_cis_dist".isInteger()) opts="${opts} -d ${params.min_cis_dist}" + prefix = pe_bam.toString() - ~/.bam/ """ mapped_2hic_dnase.py -r ${pe_bam} ${opts} + sort -T /tmp/ -k2,2V -k3,3n -k5,5V -k6,6n -o ${prefix}.validPairs ${prefix}.validPairs """ } } From 5be2e2f686d716ccff9f4add5026ca880f194bd2 Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 12 May 2020 12:12:29 +0200 Subject: [PATCH 17/36] [LINT] fix lint md --- CHANGELOG.md | 1 - README.md | 3 --- docs/usage.md | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f01b70..a85e024 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,4 +65,3 @@ if not provided. * Normalization of the contact maps using the ICE algorithm * Generation of cooler file for visualization on [higlass](https://higlass.io/) * Quality report based on HiC-Pro MultiQC module - diff --git a/README.md b/README.md index 62f2709..c8e13a9 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,6 @@ For further information or help, don't hesitate to get in touch on [Slack](https://nfcore.slack.com/channels/hic). You can join with [this invite](https://nf-co.re/join/slack). - ## Credits nf-core/hic was originally written by Nicolas Servant. @@ -102,5 +101,3 @@ You can cite the `nf-core` publication as follows: > > _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x). > ReadCube: [Full Access Link](https://rdcu.be/b1GjZ) - - diff --git a/docs/usage.md b/docs/usage.md index 8c05abc..66d1945 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -74,7 +74,7 @@ * [`-resume`](#-resume-single-dash) * [`-c`](#-c-single-dash) * [`--custom_config_version`](#--custom_config_version) - * [`--custom_config_base`](#--custom_config_base) + * [`--custom_config_base`](#--custom_config_base) * [`--max_memory`](#--max_memory) * [`--max_time`](#--max_time) * [`--max_cpus`](#--max_cpus) From fa7afebdf07ed1ca0b04ce7da8b426501e7bdadd Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 12 May 2020 12:23:10 +0200 Subject: [PATCH 18/36] [MODIF] update CHANGELOG --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a85e024..4df6a1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## v1.2.0dev +## v1.2.0dev - 2020-05-12 ### `Added` @@ -22,7 +22,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * --skipMaps, --skipIce, --skipCool, --skipMultiQC are deprecated and replaced by --skip_maps, --skip_ice, --skip_cool, --skip_multiqc * --saveReference, --saveAlignedIntermediates, --saveInteractionBAM are replaced by --save_reference, --save_aligned_intermediates, --save_interaction_bam -## v1.1.1 +## v1.1.1 - 2020-04-02 ### `Fixed` From ddeabc9f38a35e7193e469bdc29e653028ef8fb8 Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 19 May 2020 15:16:37 +0200 Subject: [PATCH 19/36] [MODIF] update conda env for testing --- environment.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index 2680ede..fa48dca 100644 --- a/environment.yml +++ b/environment.yml @@ -1,12 +1,13 @@ # You can use this file to create a conda environment for this pipeline: # conda env create -f environment.yml -name: nf-core-hic-1.2.0dev +name: nf-core-hic-1.2.1dev channels: - conda-forge - bioconda - defaults dependencies: - conda-forge::python=3.7.6 + - conda-forge::pip=20.0.1 - conda-forge::scipy=1.4.1 - conda-forge::numpy=1.18.1 - bioconda::iced=0.5.6 @@ -17,3 +18,10 @@ dependencies: - bioconda::bowtie2=2.3.5 - bioconda::samtools=1.9 - bioconda::multiqc=1.8 + + - bioconda::hicexplorer=3.4.3 + - bioconda::bioconductor-hitc=1.32.0 + - conda-forge::r-optparse=1.6.6 + - pip: + - cooltools + - fanc \ No newline at end of file From aaa379642618f63cfb66fb4b9ab90e3985be115f Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 19 May 2020 16:52:37 +0200 Subject: [PATCH 20/36] [MODIF] update environment --- environment.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/environment.yml b/environment.yml index fa48dca..7bbaff2 100644 --- a/environment.yml +++ b/environment.yml @@ -1,6 +1,6 @@ # You can use this file to create a conda environment for this pipeline: # conda env create -f environment.yml -name: nf-core-hic-1.2.1dev +name: nf-core-hic-1.3.0dev channels: - conda-forge - bioconda @@ -19,9 +19,11 @@ dependencies: - bioconda::samtools=1.9 - bioconda::multiqc=1.8 +## Dev tools - bioconda::hicexplorer=3.4.3 - bioconda::bioconductor-hitc=1.32.0 - conda-forge::r-optparse=1.6.6 + - bioconda::ucsc-bedgraphtobigwig=377 - pip: - - cooltools - - fanc \ No newline at end of file + - cooltools==0.3.2 + - fanc==0.8.30 \ No newline at end of file From fe13fafac8a37e30a3e4a5f5a58533b7d887f0a3 Mon Sep 17 00:00:00 2001 From: Nicolas Servant Date: Tue, 19 May 2020 16:53:27 +0200 Subject: [PATCH 21/36] Update CHANGELOG.md Co-authored-by: Phil Ewels --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4df6a1a..5cc0f96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### `Fixed` -* Fix bug for reads extension _1/_2 ([#30](https://github.com/nf-core/hic/issues/30)) +* Fix bug for reads extension `_1`/`_2` ([#30](https://github.com/nf-core/hic/issues/30)) ## v1.0 - [2019-05-06] From ab9fa064c06bf8abcf69026ade7b5357a0519ec3 Mon Sep 17 00:00:00 2001 From: Nicolas Servant Date: Tue, 19 May 2020 16:53:41 +0200 Subject: [PATCH 22/36] Update CHANGELOG.md Co-authored-by: Phil Ewels --- CHANGELOG.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cc0f96..835ea6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,8 +19,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### `Deprecated` -* --skipMaps, --skipIce, --skipCool, --skipMultiQC are deprecated and replaced by --skip_maps, --skip_ice, --skip_cool, --skip_multiqc -* --saveReference, --saveAlignedIntermediates, --saveInteractionBAM are replaced by --save_reference, --save_aligned_intermediates, --save_interaction_bam +* Command line options converted to `camel_case`: + * `--skipMaps` > `--skip_maps` + * `--skipIce` > `--skip_ice` + * `--skipCool` > `--skip_cool` + * `--skipMultiQC` > `--skip_multiqc` + * `--saveReference` > `--save_reference` + * `--saveAlignedIntermediates` > `--save_aligned_intermediates` + * `--saveInteractionBAM` > `--save_interaction_bam` ## v1.1.1 - 2020-04-02 From 72ca75a095cf84c5a6c3d50881011dc9f9010902 Mon Sep 17 00:00:00 2001 From: Nicolas Servant Date: Tue, 19 May 2020 16:54:11 +0200 Subject: [PATCH 23/36] Update conf/test.config Co-authored-by: Phil Ewels --- conf/test.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test.config b/conf/test.config index e628667..39a2bba 100644 --- a/conf/test.config +++ b/conf/test.config @@ -38,5 +38,5 @@ config_profile_name = 'Hi-C test data from Schalbetter et al. (2017)' max_insert_size = 600 // Options - skipCool = true + skip_cool = true } From 406b02a0b0f5a304a3e292d8f926819b8d040670 Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 19 May 2020 17:09:52 +0200 Subject: [PATCH 24/36] [MODIF] Update changelog --- CHANGELOG.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 835ea6a..34cdbc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,29 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * Bump v1.2.0dev * Merge template nf-core 1.9 * Move some options to camel_case -* Update conda environment file * Update python scripts for python3 +* Update conda environment file + * python base `2.7.15` > `3.7.6` + * pip `19.1` > `20.0.1` + * scipy `1.2.1` > `1.4.1` + * numpy `1.16.3` > `1.18.1` + * bx-python `0.8.2` > `0.8.8` + * pysam `0.15.2` > `0.15.4` + * cooler `0.8.5` > `0.8.6` + * multiqc `1.7` > `1.8` + * iced `0.5.1` > `0.5.6` + * *_New_* pymdown-extensions `7.1` + * *_New_* hicexplorer `3.4.3` + * *_New_* bioconductor-hitc `1.32.0` + * *_New_* r-optparse `1.6.6` + * *_New_* ucsc-bedgraphtobigwig `377` + * *_New_* cooltools `0.3.2` + * *_New_* fanc `0.8.30` + * *_Removed_* r-markdown ### `Fixed` -* Fix a bug in rm_dup in file sorting +* Sort output of `get_valid_interaction` process as the input files of `remove_duplicates` are expected to be sorted (sort -m) ### `Deprecated` From 64e5f6643167cba4c8f36b5699ec48916e911367 Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 19 May 2020 17:10:44 +0200 Subject: [PATCH 25/36] [MODIF] update base config --- conf/base.config | 5 ----- 1 file changed, 5 deletions(-) diff --git a/conf/base.config b/conf/base.config index d655a76..157dd95 100644 --- a/conf/base.config +++ b/conf/base.config @@ -19,11 +19,6 @@ process { maxRetries = 1 maxErrors = '-1' - // NOTE - Only one of the labels below are used in the fastqc process in the main script. - // If possible, it would be nice to keep the same label naming convention when - // adding in your processes. - // nf-core: Customise requirements for specific processes. - // See https://www.nextflow.io/docs/latest/config.html#config-process-selectors withLabel:process_low { cpus = { check_max( 1 * task.attempt, 'cpus' ) } memory = { check_max( 4.GB * task.attempt, 'memory' ) } From 7907335094632fe85e848eddcccd2d2e22b06d01 Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 19 May 2020 17:20:02 +0200 Subject: [PATCH 26/36] [MODIF] update mqc config --- main.nf | 1 + 1 file changed, 1 insertion(+) diff --git a/main.nf b/main.nf index 872d6e6..a57fe1e 100644 --- a/main.nf +++ b/main.nf @@ -850,6 +850,7 @@ process multiqc { input: file multiqc_config from ch_multiqc_config + file (mqc_custom_config) from ch_multiqc_custom_config.collect().ifEmpty([]) file ('input_*/*') from all_mstats.concat(all_mergestat).collect() file ('software_versions/*') from software_versions_yaml file workflow_summary from create_workflow_summary(summary) From f10905e3fa8a2661d9bbc396c0ebcd4460308b45 Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 19 May 2020 20:11:51 +0200 Subject: [PATCH 27/36] [MODIF] fix changes in mqc config file --- main.nf | 4 ---- nextflow.config | 1 - 2 files changed, 5 deletions(-) diff --git a/main.nf b/main.nf index a57fe1e..7eb4315 100644 --- a/main.nf +++ b/main.nf @@ -223,10 +223,6 @@ else { // Resolutions for contact maps map_res = Channel.from( params.bin_size.tokenize(',') ) -// Stage config files -ch_multiqc_config = Channel.fromPath(params.multiqc_config) -ch_output_docs = Channel.fromPath("$baseDir/docs/output.md") - /********************************************************** * SET UP LOGS */ diff --git a/nextflow.config b/nextflow.config index 4ad6c94..868ed5b 100644 --- a/nextflow.config +++ b/nextflow.config @@ -38,7 +38,6 @@ params { // Boilerplate options name = false - multiqc_config = "$baseDir/assets/multiqc_config.yaml" email = false email_on_fail = false max_multiqc_email_size = 25.MB From dd47adc0f80abacccdac7db76b6be265cea717dc Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 19 May 2020 20:27:12 +0200 Subject: [PATCH 28/36] [BUG] in mqc config --- nextflow.config | 1 + 1 file changed, 1 insertion(+) diff --git a/nextflow.config b/nextflow.config index 868ed5b..7ad9a22 100644 --- a/nextflow.config +++ b/nextflow.config @@ -37,6 +37,7 @@ params { min_cis_dist = false // Boilerplate options + multiqc_config = false name = false email = false email_on_fail = false From b3459665265ff00e54418a4572cfe44d54bc4c10 Mon Sep 17 00:00:00 2001 From: nservant Date: Wed, 20 May 2020 11:04:36 +0200 Subject: [PATCH 29/36] [MODIF] fix md lint --- CHANGELOG.md | 51 +++++++++++++++++++++++++------------------------ README.md | 24 +++++++++++++++++------ environment.yml | 2 +- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34cdbc8..6480cc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,38 +12,39 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * Move some options to camel_case * Update python scripts for python3 * Update conda environment file - * python base `2.7.15` > `3.7.6` - * pip `19.1` > `20.0.1` - * scipy `1.2.1` > `1.4.1` - * numpy `1.16.3` > `1.18.1` - * bx-python `0.8.2` > `0.8.8` - * pysam `0.15.2` > `0.15.4` - * cooler `0.8.5` > `0.8.6` - * multiqc `1.7` > `1.8` - * iced `0.5.1` > `0.5.6` - * *_New_* pymdown-extensions `7.1` - * *_New_* hicexplorer `3.4.3` - * *_New_* bioconductor-hitc `1.32.0` - * *_New_* r-optparse `1.6.6` - * *_New_* ucsc-bedgraphtobigwig `377` - * *_New_* cooltools `0.3.2` - * *_New_* fanc `0.8.30` - * *_Removed_* r-markdown + * python base `2.7.15` > `3.7.6` + * pip `19.1` > `20.0.1` + * scipy `1.2.1` > `1.4.1` + * numpy `1.16.3` > `1.18.1` + * bx-python `0.8.2` > `0.8.8` + * pysam `0.15.2` > `0.15.4` + * cooler `0.8.5` > `0.8.6` + * multiqc `1.7` > `1.8` + * iced `0.5.1` > `0.5.6` + * *_New_* pymdown-extensions `7.1` + * *_New_* hicexplorer `3.4.3` + * *_New_* bioconductor-hitc `1.32.0` + * *_New_* r-optparse `1.6.6` + * *_New_* ucsc-bedgraphtobigwig `377` + * *_New_* cooltools `0.3.2` + * *_New_* fanc `0.8.30` + * *_Removed_* r-markdown ### `Fixed` -* Sort output of `get_valid_interaction` process as the input files of `remove_duplicates` are expected to be sorted (sort -m) +* Sort output of `get_valid_interaction` process as the input files of `remove_duplicates` +are expected to be sorted (sort -m) ### `Deprecated` * Command line options converted to `camel_case`: - * `--skipMaps` > `--skip_maps` - * `--skipIce` > `--skip_ice` - * `--skipCool` > `--skip_cool` - * `--skipMultiQC` > `--skip_multiqc` - * `--saveReference` > `--save_reference` - * `--saveAlignedIntermediates` > `--save_aligned_intermediates` - * `--saveInteractionBAM` > `--save_interaction_bam` + * `--skipMaps` > `--skip_maps` + * `--skipIce` > `--skip_ice` + * `--skipCool` > `--skip_cool` + * `--skipMultiQC` > `--skip_multiqc` + * `--saveReference` > `--save_reference` + * `--saveAlignedIntermediates` > `--save_aligned_intermediates` + * `--saveInteractionBAM` > `--save_interaction_bam` ## v1.1.1 - 2020-04-02 diff --git a/README.md b/README.md index c8e13a9..be3889d 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,10 @@ sites (bowtie2) i. Install [`nextflow`](https://nf-co.re/usage/installation) -ii. Install either [`Docker`](https://docs.docker.com/engine/installation/) or [`Singularity`](https://www.sylabs.io/guides/3.0/user-guide/) for full pipeline reproducibility (please only use [`Conda`](https://conda.io/miniconda.html) as a last resort; see [docs](https://nf-co.re/usage/configuration#basic-configuration-profiles)) +ii. Install either [`Docker`](https://docs.docker.com/engine/installation/) +or [`Singularity`](https://www.sylabs.io/guides/3.0/user-guide/) +for full pipeline reproducibility (please only use [`Conda`](https://conda.io/miniconda.html) +as a last resort; see [docs](https://nf-co.re/usage/configuration#basic-configuration-profiles)) iii. Download the pipeline and test it on a minimal dataset with a single command @@ -51,7 +54,11 @@ iii. Download the pipeline and test it on a minimal dataset with a single comman nextflow run nf-core/hic -profile test, ``` -> Please check [nf-core/configs](https://github.com/nf-core/configs#documentation) to see if a custom config file to run nf-core pipelines already exists for your Institute. If so, you can simply use `-profile ` in your command. This will enable either `docker` or `singularity` and set the appropriate execution settings for your local compute environment. +> Please check [nf-core/configs](https://github.com/nf-core/configs#documentation) +to see if a custom config file to run nf-core pipelines already exists for your Institute. +If so, you can simply use `-profile ` in your command. +This will enable either `docker` or `singularity` and set the appropriate execution +settings for your local compute environment. iv. Start running your own analysis! @@ -63,7 +70,8 @@ See [usage docs](docs/usage.md) for all of the available options when running th ## Documentation -The nf-core/hic pipeline comes with documentation about the pipeline, found in the `docs/` directory: +The nf-core/hic pipeline comes with documentation about the pipeline, +found in the `docs/` directory: 1. [Installation](https://nf-co.re/usage/installation) 2. Pipeline configuration @@ -86,7 +94,9 @@ nf-core/hic was originally written by Nicolas Servant. If you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md). -For further information or help, don't hesitate to get in touch on [Slack](https://nfcore.slack.com/channels/hic) (you can join with [this invite](https://nf-co.re/join/slack)). +For further information or help, don't hesitate to get in touch on +[Slack](https://nfcore.slack.com/channels/hic) (you can join with +[this invite](https://nf-co.re/join/slack)). ## Citation @@ -97,7 +107,9 @@ You can cite the `nf-core` publication as follows: > **The nf-core framework for community-curated bioinformatics pipelines.** > -> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen. +> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, +Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen. > -> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x). +> _Nat Biotechnol._ 2020 Feb 13. +doi:[10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x). > ReadCube: [Full Access Link](https://rdcu.be/b1GjZ) diff --git a/environment.yml b/environment.yml index 7bbaff2..f9c9548 100644 --- a/environment.yml +++ b/environment.yml @@ -1,6 +1,6 @@ # You can use this file to create a conda environment for this pipeline: # conda env create -f environment.yml -name: nf-core-hic-1.3.0dev +name: nf-core-hic-1.2.0dev channels: - conda-forge - bioconda From c0ede978fbd5678fa11fb99b23c4be14747051ec Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 26 May 2020 17:15:10 +0200 Subject: [PATCH 30/36] [MODIF] Add pip in conda --- environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index f9c9548..7bbaff2 100644 --- a/environment.yml +++ b/environment.yml @@ -1,6 +1,6 @@ # You can use this file to create a conda environment for this pipeline: # conda env create -f environment.yml -name: nf-core-hic-1.2.0dev +name: nf-core-hic-1.3.0dev channels: - conda-forge - bioconda From e0c416f2ae2aaa351ec93d320315b4dca9d92d1c Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 26 May 2020 18:11:53 +0200 Subject: [PATCH 31/36] [MODIF] fix env --- environment.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/environment.yml b/environment.yml index 7bbaff2..97fb679 100644 --- a/environment.yml +++ b/environment.yml @@ -7,7 +7,7 @@ channels: - defaults dependencies: - conda-forge::python=3.7.6 - - conda-forge::pip=20.0.1 + - pip=20.0.1 - conda-forge::scipy=1.4.1 - conda-forge::numpy=1.18.1 - bioconda::iced=0.5.6 @@ -23,7 +23,7 @@ dependencies: - bioconda::hicexplorer=3.4.3 - bioconda::bioconductor-hitc=1.32.0 - conda-forge::r-optparse=1.6.6 - - bioconda::ucsc-bedgraphtobigwig=377 + - bioconda::ucsc-bedgraphtobigwig=357 - pip: - cooltools==0.3.2 - fanc==0.8.30 \ No newline at end of file From b5da93a00a01cf95b363f5ff2843f187d627f26a Mon Sep 17 00:00:00 2001 From: nservant Date: Tue, 26 May 2020 18:14:41 +0200 Subject: [PATCH 32/36] [MODIF] fix env --- environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index 97fb679..c4b2ec5 100644 --- a/environment.yml +++ b/environment.yml @@ -1,6 +1,6 @@ # You can use this file to create a conda environment for this pipeline: # conda env create -f environment.yml -name: nf-core-hic-1.3.0dev +name: nf-core-hic-1.2.0dev channels: - conda-forge - bioconda From 99fc19d116679e10bd8816fe3ef6ea219d5c165c Mon Sep 17 00:00:00 2001 From: nservant Date: Wed, 27 May 2020 11:41:18 +0200 Subject: [PATCH 33/36] [MODIF] update env --- environment.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/environment.yml b/environment.yml index c4b2ec5..fd6119a 100644 --- a/environment.yml +++ b/environment.yml @@ -24,6 +24,7 @@ dependencies: - bioconda::bioconductor-hitc=1.32.0 - conda-forge::r-optparse=1.6.6 - bioconda::ucsc-bedgraphtobigwig=357 + - conda-forge::cython=0.29.19 - pip: - cooltools==0.3.2 - fanc==0.8.30 \ No newline at end of file From 483501edd21da89bc69daa86341b8a33359d6b7a Mon Sep 17 00:00:00 2001 From: nservant Date: Thu, 28 May 2020 09:38:40 +0200 Subject: [PATCH 34/36] update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6480cc4..5543ec9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * *_New_* bioconductor-hitc `1.32.0` * *_New_* r-optparse `1.6.6` * *_New_* ucsc-bedgraphtobigwig `377` + * *_New_* cython `0.29.19` * *_New_* cooltools `0.3.2` * *_New_* fanc `0.8.30` * *_Removed_* r-markdown From 6cc80fc384bc6cca8ded082e29bb186cd6e34f44 Mon Sep 17 00:00:00 2001 From: nservant Date: Thu, 11 Jun 2020 10:31:58 +0200 Subject: [PATCH 35/36] [MODIF] update doc for Arima --- CHANGELOG.md | 1 + docs/usage.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5543ec9..c8645cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### `Fixed` +* Fix error in doc for Arima kit usage * Sort output of `get_valid_interaction` process as the input files of `remove_duplicates` are expected to be sorted (sort -m) diff --git a/docs/usage.md b/docs/usage.md index 66d1945..cef7bf3 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -398,7 +398,7 @@ Here are a few examples: * DpnII: ^GATC * BglII: A^GATCT * HindIII: A^AGCTT -* ARIMA kit: ^GATC,^GANT +* ARIMA kit: ^GATC,G^ANTC Note that multiples restriction motifs can be provided (comma-separated) and that 'N' base are supported. @@ -419,7 +419,7 @@ Default: 'AAGCTAGCTT' --ligation_site '[Ligation motif]' ``` -Exemple of the ARIMA kit: GATCGATC,GATCGANT,GANTGATC,GANTGANT +Exemple of the ARIMA kit: GATCGATC,GANTGATC,GANTANTC,GATCANTC #### `--min_restriction_fragment_size` From 8ab27056f67139a8b7b54e671e347417971bf5a6 Mon Sep 17 00:00:00 2001 From: nservant Date: Thu, 18 Jun 2020 16:28:30 +0200 Subject: [PATCH 36/36] bump v1.2.0 --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 4 ++-- Dockerfile | 4 ++-- environment.yml | 2 +- nextflow.config | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 34410af..a7f734d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: - name: Pull docker image run: | docker pull nfcore/hic:dev - docker tag nfcore/hic:dev nfcore/hic:dev + docker tag nfcore/hic:dev nfcore/hic:1.2.0 - name: Run pipeline with test data run: | # nf-core: You can customise CI pipeline run tests as required diff --git a/CHANGELOG.md b/CHANGELOG.md index c8645cd..6852128 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,11 +3,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## v1.2.0dev - 2020-05-12 +## v1.2.0 - 2020-06-18 ### `Added` -* Bump v1.2.0dev +* Bump v1.2.0 * Merge template nf-core 1.9 * Move some options to camel_case * Update python scripts for python3 diff --git a/Dockerfile b/Dockerfile index cbb686f..5aecaa6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,8 +7,8 @@ RUN apt-get update && apt-get install -y gcc g++ && apt-get clean -y COPY environment.yml / RUN conda env create -f /environment.yml && conda clean -a -ENV PATH /opt/conda/envs/nf-core-hic-1.2.0dev/bin:$PATH +ENV PATH /opt/conda/envs/nf-core-hic-1.2.0/bin:$PATH # Dump the details of the installed packages to a file for posterity -RUN conda env export --name nf-core-hic-1.2.0dev > nf-core-hic-1.2.0dev.yml +RUN conda env export --name nf-core-hic-1.2.0 > nf-core-hic-1.2.0.yml diff --git a/environment.yml b/environment.yml index fd6119a..b9e6c02 100644 --- a/environment.yml +++ b/environment.yml @@ -1,6 +1,6 @@ # You can use this file to create a conda environment for this pipeline: # conda env create -f environment.yml -name: nf-core-hic-1.2.0dev +name: nf-core-hic-1.2.0 channels: - conda-forge - bioconda diff --git a/nextflow.config b/nextflow.config index 7ad9a22..f7a5af7 100644 --- a/nextflow.config +++ b/nextflow.config @@ -64,7 +64,7 @@ params { // Container slug. Stable releases should specify release tag! // Developmental code should specify :dev -process.container = 'nfcore/hic:dev' +process.container = 'nfcore/hic:1.2.0' // Load base.config by default for all pipelines includeConfig 'conf/base.config' @@ -135,7 +135,7 @@ manifest { description = 'Analysis of Chromosome Conformation Capture data (Hi-C)' mainScript = 'main.nf' nextflowVersion = '>=19.10.0' - version = '1.2.0dev' + version = '1.2.0' } // Function to ensure that resource requirements don't go beyond