From ce166d3039700fc2eb7192f0e93b95b6f1c68b88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= <mirp.julia@gmail.com>
Date: Tue, 7 Feb 2023 12:44:27 +0100
Subject: [PATCH] Igv js (#2846)

* add igv/js module

* add documentation in meta.yml

* create test.yml according to new version of the library

* fix browser description and pattern
---
 modules/nf-core/igv/js/main.nf               | 66 +++++++++++++++++++
 modules/nf-core/igv/js/meta.yml              | 67 ++++++++++++++++++++
 tests/config/pytest_modules.yml              |  4 ++
 tests/modules/nf-core/igv/js/main.nf         | 16 +++++
 tests/modules/nf-core/igv/js/nextflow.config | 14 ++++
 tests/modules/nf-core/igv/js/test.yml        | 13 ++++
 6 files changed, 180 insertions(+)
 create mode 100644 modules/nf-core/igv/js/main.nf
 create mode 100644 modules/nf-core/igv/js/meta.yml
 create mode 100644 tests/modules/nf-core/igv/js/main.nf
 create mode 100644 tests/modules/nf-core/igv/js/nextflow.config
 create mode 100644 tests/modules/nf-core/igv/js/test.yml

diff --git a/modules/nf-core/igv/js/main.nf b/modules/nf-core/igv/js/main.nf
new file mode 100644
index 00000000000..12e050f431c
--- /dev/null
+++ b/modules/nf-core/igv/js/main.nf
@@ -0,0 +1,66 @@
+
+process IGV_JS {
+    tag "$meta.id"
+    label 'process_single'
+
+    conda "conda-forge::sed=4.7"
+    container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
+        'https://depot.galaxyproject.org/singularity/ubuntu:20.04' :
+        'ubuntu:20.04' }"
+
+    input:
+    tuple val(meta), path(alignment), path(index)
+
+    output:
+    tuple val(meta), path("*_genome-browser.html") , emit: browser
+    tuple val(meta), path(alignment)               , emit: align_files
+    tuple val(meta), path(index)                   , emit: index_files
+    path "versions.yml"                            , emit: versions
+
+    when:
+    task.ext.when == null || task.ext.when
+
+    script:
+    def browser_args = task.ext.args ?: ''
+    def track_args = task.ext.args2 ?: ''
+    def prefix = task.ext.prefix ?: "${meta.id}"
+    """
+    cat  <<IGV > ${prefix}_genome-browser.html
+    <html>
+        <head>
+            <script src="https://cdn.jsdelivr.net/npm/igv@2.13.9/dist/igv.min.js"></script> <!-- https://github.com/igvteam/igv.js/ -->
+        </head>
+        <body>
+
+        <div id="igv-div"></div>
+        <script>
+            var igvDiv = document.getElementById("igv-div");
+            var options =
+            {
+                $browser_args,
+                tracks: [
+                    {
+                        "name": "$prefix",
+                        "url": "$alignment",
+                        "indexURL": "$index",
+                        $track_args
+                    }
+                ]
+            };
+            igv.removeAllBrowsers();
+            igv.createBrowser(igvDiv, options)
+                .then(function(browser){
+                    igv.browser = browser;
+                })
+        </script>
+
+        </body>
+    </html>
+    IGV
+
+    cat <<-END_VERSIONS > versions.yml
+    "${task.process}":
+        cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//')
+    END_VERSIONS
+    """
+}
diff --git a/modules/nf-core/igv/js/meta.yml b/modules/nf-core/igv/js/meta.yml
new file mode 100644
index 00000000000..1b6c4510cd2
--- /dev/null
+++ b/modules/nf-core/igv/js/meta.yml
@@ -0,0 +1,67 @@
+name: "igv_js"
+description: igv.js is an embeddable interactive genome visualization component
+keywords:
+  - igv
+  - igv.js
+  - js
+  - genome browser
+tools:
+  - "igv":
+      description: |
+        Create an embeddable interactive genome browser component.
+        Output files are expected to be present in the same directory as teh genome browser html file.
+        To visualise it, files have to be served. Check the documentation at:
+          https://github.com/igvteam/igv-webapp for an example and
+          https://github.com/igvteam/igv.js/wiki/Data-Server-Requirements for server requirements
+      homepage: https://github.com/igvteam/igv.js
+      documentation: https://github.com/igvteam/igv.js/wiki
+      tool_dev_url: https://github.com/igvteam/igv.js
+      doi: https://doi.org/10.1093/bioinformatics/btac830
+      licence: "['MIT']"
+
+input:
+  - meta:
+      type: map
+      description: |
+        Groovy Map containing sample information
+        e.g. [ id:'test', single_end:false ]
+
+  - alignment:
+    type: file
+    description: Sorted BAM/CRAM file
+    pattern: "*.{bam,cram}"
+
+  - index:
+    type: file
+    description: Index of sorted BAM/CRAM file
+    pattern: "*.{bai,crai}"
+
+output:
+  - meta:
+      type: map
+      description: |
+        Groovy Map containing sample information
+        e.g. [ id:'test', single_end:false ]
+
+  - browser:
+    type: file
+    description: Genome browser HTML file
+    pattern: "*.{html}"
+
+  - align_files:
+    type: file
+    description: Copy of the input sorted BAM/CRAM file
+    pattern: "*.{bam,cram}"
+
+  - index_files:
+    type: file
+    description: Copy of the input index of sorted BAM/CRAM file
+    pattern: "*.{bai,crai}"
+
+  - versions:
+      type: file
+      description: File containing software versions
+      pattern: "versions.yml"
+
+authors:
+  - "@mirpedrol"
diff --git a/tests/config/pytest_modules.yml b/tests/config/pytest_modules.yml
index 568b2ab1dff..8f2411edc8d 100644
--- a/tests/config/pytest_modules.yml
+++ b/tests/config/pytest_modules.yml
@@ -1625,6 +1625,10 @@ idr:
   - modules/nf-core/idr/**
   - tests/modules/nf-core/idr/**
 
+igv/js:
+  - modules/nf-core/igv/js/**
+  - tests/modules/nf-core/igv/js/**
+
 imputeme/vcftoprs:
   - modules/nf-core/imputeme/vcftoprs/**
   - tests/modules/nf-core/imputeme/vcftoprs/**
diff --git a/tests/modules/nf-core/igv/js/main.nf b/tests/modules/nf-core/igv/js/main.nf
new file mode 100644
index 00000000000..00f0831c7d5
--- /dev/null
+++ b/tests/modules/nf-core/igv/js/main.nf
@@ -0,0 +1,16 @@
+#!/usr/bin/env nextflow
+
+nextflow.enable.dsl = 2
+
+include { IGV_JS } from '../../../../../modules/nf-core/igv/js/main.nf'
+
+workflow test_igv_js {
+
+    input = [
+        [ id:'test', single_end:false ], // meta map
+        file(params.test_data['homo_sapiens']['illumina']['test_paired_end_sorted_bam'], checkIfExists: true),
+        file(params.test_data['homo_sapiens']['illumina']['test_paired_end_sorted_bam_bai'], checkIfExists: true)
+    ]
+
+    IGV_JS ( input )
+}
diff --git a/tests/modules/nf-core/igv/js/nextflow.config b/tests/modules/nf-core/igv/js/nextflow.config
new file mode 100644
index 00000000000..c6892336f02
--- /dev/null
+++ b/tests/modules/nf-core/igv/js/nextflow.config
@@ -0,0 +1,14 @@
+process {
+
+    publishDir = [
+        mode: "copy",
+        path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
+    ]
+    withName: 'IGV_JS' {
+        ext.args = """genome: "hg38",
+                locus: "chr22:4,514-4,554""""
+        ext.args2 = """"format": "bam",
+                        "type": "alignment""""
+    }
+
+}
diff --git a/tests/modules/nf-core/igv/js/test.yml b/tests/modules/nf-core/igv/js/test.yml
new file mode 100644
index 00000000000..e8024a63e3e
--- /dev/null
+++ b/tests/modules/nf-core/igv/js/test.yml
@@ -0,0 +1,13 @@
+- name: igv js test_igv_js
+  command: nextflow run ./tests/modules/nf-core/igv/js -entry test_igv_js -c ./tests/config/nextflow.config -c ./tests/modules/nf-core/igv/js/nextflow.config
+  tags:
+    - igv
+    - igv/js
+  files:
+    - path: output/igv/test.paired_end.sorted.bam
+      md5sum: 76396678f283516b159a1e9b538fc64c
+    - path: output/igv/test.paired_end.sorted.bam.bai
+      md5sum: 9ac6ecb9435822c44b37765f111e9013
+    - path: output/igv/test_genome-browser.html
+      md5sum: 99f4962da2703eceaba71fd68f9be7e6
+    - path: output/igv/versions.yml