From 9e409e3865f635986f4408d1f5ddd43def92b96e Mon Sep 17 00:00:00 2001 From: Thoumyre Stanislas Date: Tue, 7 Jan 2025 11:42:35 +0000 Subject: [PATCH 1/2] add module visualization --- .../connectivity/visualize/environment.yml | 4 + .../nf-neuro/connectivity/visualize/main.nf | 55 +++++++++++ .../nf-neuro/connectivity/visualize/meta.yml | 57 +++++++++++ .../connectivity/visualize/tests/main.nf.test | 50 ++++++++++ .../visualize/tests/main.nf.test.snap | 99 +++++++++++++++++++ .../connectivity/visualize/tests/tags.yml | 2 + 6 files changed, 267 insertions(+) create mode 100644 modules/nf-neuro/connectivity/visualize/environment.yml create mode 100644 modules/nf-neuro/connectivity/visualize/main.nf create mode 100644 modules/nf-neuro/connectivity/visualize/meta.yml create mode 100644 modules/nf-neuro/connectivity/visualize/tests/main.nf.test create mode 100644 modules/nf-neuro/connectivity/visualize/tests/main.nf.test.snap create mode 100644 modules/nf-neuro/connectivity/visualize/tests/tags.yml diff --git a/modules/nf-neuro/connectivity/visualize/environment.yml b/modules/nf-neuro/connectivity/visualize/environment.yml new file mode 100644 index 0000000..103ef9d --- /dev/null +++ b/modules/nf-neuro/connectivity/visualize/environment.yml @@ -0,0 +1,4 @@ +--- +channels: [] +dependencies: [] +name: connectivity_visualize diff --git a/modules/nf-neuro/connectivity/visualize/main.nf b/modules/nf-neuro/connectivity/visualize/main.nf new file mode 100644 index 0000000..b2a6612 --- /dev/null +++ b/modules/nf-neuro/connectivity/visualize/main.nf @@ -0,0 +1,55 @@ +process CONNECTIVITY_VISUALIZE { + tag "$meta.id" + label 'process_single' + + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'scil.usherbrooke.ca/containers/scilus_2.0.2.sif': + 'scilus/scilus:2.0.2' }" + + input: + tuple val(meta), path(matrix), path (atlas_labels), path(labels_list) + + output: + tuple val(meta), path("*.png"), emit: figure + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + + String matrix_list = matrix.join(", ").replace(',', '') + def args = "" + if (atlas_labels) args += [" --lookup_table $atlas_labels "] + if (labels_list) args += [" --labels_list $labels_list "] + + """ + for matrix in $matrix_list; do + scil_viz_connectivity.py \$matrix \${matrix/.npy/_matrix.png} \ + --name_axis --display_legend --histogram \${matrix/.npy/_histogram.png} \ + --nb_bins 50 --exclude_zeros --axis_text_size 5 5 \ + $args + done + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + scilpy: \$(pip list | grep scilpy | tr -s ' ' | cut -d' ' -f2) + END_VERSIONS + """ + + stub: + matrix_list = matrix.join(", ").replace(',', '') + """ + for metric in $matrix_list; do + base_name=\$(basename "\${metric}" .npy) + touch "\${base_name}.png" + done + + scil_viz_connectivity.py -h + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + scilpy: \$(pip list | grep scilpy | tr -s ' ' | cut -d' ' -f2) + END_VERSIONS + """ +} diff --git a/modules/nf-neuro/connectivity/visualize/meta.yml b/modules/nf-neuro/connectivity/visualize/meta.yml new file mode 100644 index 0000000..c0b8dd9 --- /dev/null +++ b/modules/nf-neuro/connectivity/visualize/meta.yml @@ -0,0 +1,57 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "connectivity_visualize" +description: display a connectivity matrix and adjust the desired visualization. +keywords: + - nifti + - connectivity + - visualize + - scilpy +tools: + - "scilpy": + description: "The Sherbrooke Connectivity Imaging Lab (SCIL) Python dMRI processing toolbox." + homepage: "https://github.com/scilus/scilpy.git" + +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + + - matrix: + type: file + description: Connectivity matrix. + pattern: "*.npy" + + - atlas_labels: + type: file + description: Lookup table with the label number as keys and the name as values + pattern: "*.json" + + - labels_list: + type: file + description: List saved by the decomposition script, must contain labels rather than coordinates. + pattern: "*.txt" + +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + + - figure: + type: file + description: Output filename for the connectivity matrix figure. + pattern: "*.png" + + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + +authors: + - "@ThoumyreStanislas" +maintainers: + - "@ThoumyreStanislas" diff --git a/modules/nf-neuro/connectivity/visualize/tests/main.nf.test b/modules/nf-neuro/connectivity/visualize/tests/main.nf.test new file mode 100644 index 0000000..1e5ce6c --- /dev/null +++ b/modules/nf-neuro/connectivity/visualize/tests/main.nf.test @@ -0,0 +1,50 @@ +// TODO nf-core: Once you have added the required tests, please run the following command to build this file: +// nf-core modules test connectivity/visualize +nextflow_process { + + name "Test Process CONNECTIVITY_VISUALIZE" + script "../main.nf" + process "CONNECTIVITY_VISUALIZE" + + tag "modules" + tag "modules_nfcore" + tag "connectivity" + tag "connectivity/visualize" + + tag "subworkflows/load_test_data" + + setup { + run("LOAD_TEST_DATA", alias: "LOAD_DATA") { + script "../../../../../subworkflows/nf-neuro/load_test_data/main.nf" + process { + """ + input[0] = Channel.from( ["connectivity.zip" ] ) + input[1] = "test.load-test-data" + """ + } + } + } + + test("connectivity - visualisation ") { + when { + process { + """ + input[0] = LOAD_DATA.out.test_data_directory.map{ + test_data_directory -> [ + [ id:'test', single_end:false ], // meta map + file("\${test_data_directory}/*.npy", checkIfExists: true), + [], + [] + ] + } + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-neuro/connectivity/visualize/tests/main.nf.test.snap b/modules/nf-neuro/connectivity/visualize/tests/main.nf.test.snap new file mode 100644 index 0000000..e67405d --- /dev/null +++ b/modules/nf-neuro/connectivity/visualize/tests/main.nf.test.snap @@ -0,0 +1,99 @@ +{ + "connectivity - visualisation ": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "afd_max_histogram.png:md5,43912780c2ac709b631fc39d95d464e8", + "afd_max_matrix.png:md5,89adc0462e5f6ee412110994e6e6b3eb", + "len_histogram.png:md5,117651740e19ee3c536c9a4bea6babfb", + "len_matrix.png:md5,e2098003d452ce2ba9db2c265d8516e9", + "mask_histogram.png:md5,073e208a8a327baa5bbf721e66e337d4", + "mask_matrix.png:md5,ec19ecce53d485ca983bf17bc87b56c7", + "pval_histogram.png:md5,892ebc7b367db2ac1bd970f638043904", + "pval_matrix.png:md5,2b8e9a9f8833110d7a2f9d612ae6f2be", + "sc_add_10_histogram.png:md5,265a9399387c856977eae1ea3f83516a", + "sc_add_10_matrix.png:md5,07e322fd583f9b8235c50363d7aba9e0", + "sc_histogram.png:md5,7baccf0dc5a650bea2aecd19d3867653", + "sc_lower_threshold_histogram.png:md5,cd4368e81ef4f9f128a444a7897d0c1e", + "sc_lower_threshold_matrix.png:md5,748d5a2a15159896775ebb7aa71a3fd5", + "sc_masked_histogram.png:md5,2a0163a153ee2b3174138ba4505ec6fb", + "sc_masked_matrix.png:md5,1b52240fc505e2e002c65b9e4f0ce777", + "sc_matrix.png:md5,db388963daf62fae2ef1d8be58c9cad8", + "sc_norm_histogram.png:md5,bfc9fa64063f6a8797f3bb49d2bfcbfd", + "sc_norm_matrix.png:md5,67ef585c7559edb6e7c88ca50304db4f", + "sc_norm_vol_histogram.png:md5,1eb857ea304f82fe73bc3a6416ade1d1", + "sc_norm_vol_matrix.png:md5,572daf7d844699f96cc1519458491f3b", + "sc_normalize_histogram.png:md5,dbc8741adf4dd3a597199c36a9ed197d", + "sc_normalize_matrix.png:md5,2bc762a0e4861d726bbec1372b124763", + "sc_reo_fake_histogram.png:md5,1f2efba6ff6a949f6bdc9b07e3d0952b", + "sc_reo_fake_matrix.png:md5,2d8e4abada02b7d096e38888a2ea2a09", + "sc_thr_histogram.png:md5,cd4368e81ef4f9f128a444a7897d0c1e", + "sc_thr_matrix.png:md5,748d5a2a15159896775ebb7aa71a3fd5", + "sim_histogram.png:md5,e82b14b3fbb8184e53265a05fe247fd0", + "sim_matrix.png:md5,e42c85fbd2211738bb38882305122c9a", + "vol_histogram.png:md5,5b60e61f931294416a22ad3a7d8848ca", + "vol_matrix.png:md5,85ddd42c1562adaf38aee0cc32334039" + ] + ] + ], + "1": [ + "versions.yml:md5,3114f700c3813ee15388713fe8a539f1" + ], + "figure": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "afd_max_histogram.png:md5,43912780c2ac709b631fc39d95d464e8", + "afd_max_matrix.png:md5,89adc0462e5f6ee412110994e6e6b3eb", + "len_histogram.png:md5,117651740e19ee3c536c9a4bea6babfb", + "len_matrix.png:md5,e2098003d452ce2ba9db2c265d8516e9", + "mask_histogram.png:md5,073e208a8a327baa5bbf721e66e337d4", + "mask_matrix.png:md5,ec19ecce53d485ca983bf17bc87b56c7", + "pval_histogram.png:md5,892ebc7b367db2ac1bd970f638043904", + "pval_matrix.png:md5,2b8e9a9f8833110d7a2f9d612ae6f2be", + "sc_add_10_histogram.png:md5,265a9399387c856977eae1ea3f83516a", + "sc_add_10_matrix.png:md5,07e322fd583f9b8235c50363d7aba9e0", + "sc_histogram.png:md5,7baccf0dc5a650bea2aecd19d3867653", + "sc_lower_threshold_histogram.png:md5,cd4368e81ef4f9f128a444a7897d0c1e", + "sc_lower_threshold_matrix.png:md5,748d5a2a15159896775ebb7aa71a3fd5", + "sc_masked_histogram.png:md5,2a0163a153ee2b3174138ba4505ec6fb", + "sc_masked_matrix.png:md5,1b52240fc505e2e002c65b9e4f0ce777", + "sc_matrix.png:md5,db388963daf62fae2ef1d8be58c9cad8", + "sc_norm_histogram.png:md5,bfc9fa64063f6a8797f3bb49d2bfcbfd", + "sc_norm_matrix.png:md5,67ef585c7559edb6e7c88ca50304db4f", + "sc_norm_vol_histogram.png:md5,1eb857ea304f82fe73bc3a6416ade1d1", + "sc_norm_vol_matrix.png:md5,572daf7d844699f96cc1519458491f3b", + "sc_normalize_histogram.png:md5,dbc8741adf4dd3a597199c36a9ed197d", + "sc_normalize_matrix.png:md5,2bc762a0e4861d726bbec1372b124763", + "sc_reo_fake_histogram.png:md5,1f2efba6ff6a949f6bdc9b07e3d0952b", + "sc_reo_fake_matrix.png:md5,2d8e4abada02b7d096e38888a2ea2a09", + "sc_thr_histogram.png:md5,cd4368e81ef4f9f128a444a7897d0c1e", + "sc_thr_matrix.png:md5,748d5a2a15159896775ebb7aa71a3fd5", + "sim_histogram.png:md5,e82b14b3fbb8184e53265a05fe247fd0", + "sim_matrix.png:md5,e42c85fbd2211738bb38882305122c9a", + "vol_histogram.png:md5,5b60e61f931294416a22ad3a7d8848ca", + "vol_matrix.png:md5,85ddd42c1562adaf38aee0cc32334039" + ] + ] + ], + "versions": [ + "versions.yml:md5,3114f700c3813ee15388713fe8a539f1" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.10.3" + }, + "timestamp": "2025-01-07T11:38:42.542320238" + } +} \ No newline at end of file diff --git a/modules/nf-neuro/connectivity/visualize/tests/tags.yml b/modules/nf-neuro/connectivity/visualize/tests/tags.yml new file mode 100644 index 0000000..3738b71 --- /dev/null +++ b/modules/nf-neuro/connectivity/visualize/tests/tags.yml @@ -0,0 +1,2 @@ +connectivity/visualize: + - "modules/nf-neuro/connectivity/visualize/**" From 1ad734ec15ca7c36d67160b68f17b5f944691487 Mon Sep 17 00:00:00 2001 From: Thoumyre Stanislas Date: Thu, 16 Jan 2025 11:09:43 +0000 Subject: [PATCH 2/2] fix anthony's comment --- .../nf-neuro/connectivity/visualize/main.nf | 21 +++++++++------ .../nf-neuro/connectivity/visualize/meta.yml | 7 +++-- .../connectivity/visualize/tests/main.nf.test | 27 +++++++++++++++++-- .../visualize/tests/main.nf.test.snap | 14 +++++++++- .../visualize/tests/nextflow.config | 10 +++++++ 5 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 modules/nf-neuro/connectivity/visualize/tests/nextflow.config diff --git a/modules/nf-neuro/connectivity/visualize/main.nf b/modules/nf-neuro/connectivity/visualize/main.nf index b2a6612..8c129a0 100644 --- a/modules/nf-neuro/connectivity/visualize/main.nf +++ b/modules/nf-neuro/connectivity/visualize/main.nf @@ -7,7 +7,7 @@ process CONNECTIVITY_VISUALIZE { 'scilus/scilus:2.0.2' }" input: - tuple val(meta), path(matrix), path (atlas_labels), path(labels_list) + tuple val(meta), path(matrices), path (atlas_labels), path(labels_list) output: tuple val(meta), path("*.png"), emit: figure @@ -18,16 +18,21 @@ process CONNECTIVITY_VISUALIZE { script: - String matrix_list = matrix.join(", ").replace(',', '') + String matrices_list = matrices.join(", ").replace(',', '') + def name_axis = task.ext.name_axis ? "--name_axis " : "" + def display_legend = task.ext.display_legend ? "--display_legend " : "" + def exclude_zeros = task.ext.exclude_zeros ? "--exclude_zeros " : "" + def nb_bins = task.ext.nb_bins ? "--nb_bins " + task.ext.nb_bins : "--nb_bins 50" + def axis_text_size = task.ext.axis_text_size ? "--axis_text_size $task.ext.axis_text_size $task.ext.axis_text_size" : "--axis_text_size 5 5" def args = "" if (atlas_labels) args += [" --lookup_table $atlas_labels "] - if (labels_list) args += [" --labels_list $labels_list "] + if (labels_list) args += [" --name_axis "] """ - for matrix in $matrix_list; do + for matrix in $matrices_list; do scil_viz_connectivity.py \$matrix \${matrix/.npy/_matrix.png} \ - --name_axis --display_legend --histogram \${matrix/.npy/_histogram.png} \ - --nb_bins 50 --exclude_zeros --axis_text_size 5 5 \ + $name_axis $display_legend --histogram \${matrix/.npy/_histogram.png} \ + $nb_bins $exclude_zeros $axis_text_size \ $args done @@ -38,9 +43,9 @@ process CONNECTIVITY_VISUALIZE { """ stub: - matrix_list = matrix.join(", ").replace(',', '') + String matrices_list = matrices.join(", ").replace(',', '') """ - for metric in $matrix_list; do + for metric in $matrices_list; do base_name=\$(basename "\${metric}" .npy) touch "\${base_name}.png" done diff --git a/modules/nf-neuro/connectivity/visualize/meta.yml b/modules/nf-neuro/connectivity/visualize/meta.yml index c0b8dd9..86ca805 100644 --- a/modules/nf-neuro/connectivity/visualize/meta.yml +++ b/modules/nf-neuro/connectivity/visualize/meta.yml @@ -1,9 +1,8 @@ --- -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json name: "connectivity_visualize" description: display a connectivity matrix and adjust the desired visualization. keywords: - - nifti + - numpy - connectivity - visualize - scilpy @@ -19,9 +18,9 @@ input: Groovy Map containing sample information e.g. `[ id:'sample1', single_end:false ]` - - matrix: + - matrices: type: file - description: Connectivity matrix. + description: List of connectivity matrices. the set of matrices is concatenated into a single matrix, but can also contain a single matrix. pattern: "*.npy" - atlas_labels: diff --git a/modules/nf-neuro/connectivity/visualize/tests/main.nf.test b/modules/nf-neuro/connectivity/visualize/tests/main.nf.test index 1e5ce6c..9e2f510 100644 --- a/modules/nf-neuro/connectivity/visualize/tests/main.nf.test +++ b/modules/nf-neuro/connectivity/visualize/tests/main.nf.test @@ -1,5 +1,3 @@ -// TODO nf-core: Once you have added the required tests, please run the following command to build this file: -// nf-core modules test connectivity/visualize nextflow_process { name "Test Process CONNECTIVITY_VISUALIZE" @@ -26,6 +24,7 @@ nextflow_process { } test("connectivity - visualisation ") { + config "./nextflow.config" when { process { """ @@ -47,4 +46,28 @@ nextflow_process { ) } } + test("connectivity - visualisation - stub-run") { + options "-stub-run" + config "./nextflow.config" + when { + process { + """ + input[0] = LOAD_DATA.out.test_data_directory.map{ + test_data_directory -> [ + [ id:'test', single_end:false ], // meta map + file("\${test_data_directory}/*.npy", checkIfExists: true), + [], + [] + ] + } + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.versions).match() } + ) + } + } } diff --git a/modules/nf-neuro/connectivity/visualize/tests/main.nf.test.snap b/modules/nf-neuro/connectivity/visualize/tests/main.nf.test.snap index e67405d..514ca1b 100644 --- a/modules/nf-neuro/connectivity/visualize/tests/main.nf.test.snap +++ b/modules/nf-neuro/connectivity/visualize/tests/main.nf.test.snap @@ -94,6 +94,18 @@ "nf-test": "0.9.0", "nextflow": "24.10.3" }, - "timestamp": "2025-01-07T11:38:42.542320238" + "timestamp": "2025-01-16T10:54:29.917241635" + }, + "connectivity - visualisation - stub-run": { + "content": [ + [ + "versions.yml:md5,3114f700c3813ee15388713fe8a539f1" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.10.3" + }, + "timestamp": "2025-01-16T10:55:34.856253711" } } \ No newline at end of file diff --git a/modules/nf-neuro/connectivity/visualize/tests/nextflow.config b/modules/nf-neuro/connectivity/visualize/tests/nextflow.config new file mode 100644 index 0000000..48348d5 --- /dev/null +++ b/modules/nf-neuro/connectivity/visualize/tests/nextflow.config @@ -0,0 +1,10 @@ +process { + withName: "CONNECTIVITY_VISUALIZE" { + publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } + ext.name_axis = true + ext.display_legend = true + ext.exclude_zeros = true + ext.ext.nb_bins = 50 + ext.axis_text_size = 5 + } +}