From 96e709174ba352cdc283fbb3628783115967c8d0 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Feb 2025 13:58:07 +0100 Subject: [PATCH 001/227] template repo --- CITATIONS.md | 2 -- docs/output.md | 1 - modules.json | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/CITATIONS.md b/CITATIONS.md index 14cc889..3a62896 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -10,8 +10,6 @@ ## Pipeline tools - - ## Software packaging/containerisation tools - [Anaconda](https://anaconda.com) diff --git a/docs/output.md b/docs/output.md index ceef91a..8aa16f1 100644 --- a/docs/output.md +++ b/docs/output.md @@ -12,7 +12,6 @@ The directories listed below will be created in the results directory after the The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes data using the following steps: - - [Pipeline information](#pipeline-information) - Report metrics generated during the workflow execution ### Pipeline information diff --git a/modules.json b/modules.json index 629fdb6..052719c 100644 --- a/modules.json +++ b/modules.json @@ -4,8 +4,7 @@ "repos": { "https://github.com/nf-core/modules.git": { "modules": { - "nf-core": { - } + "nf-core": {} }, "subworkflows": { "nf-core": { From cf675831a69e2f66c8166cbe6d8e3cf4a470e3a9 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Feb 2025 14:27:11 +0100 Subject: [PATCH 002/227] update schema --- assets/schema_input.json | 25 ++--- main.nf | 57 +++++------ samplesheet.csv | 2 + .../local/utils_nfcore_sopa_pipeline/main.nf | 99 +++++++++---------- tower.yml | 3 - 5 files changed, 85 insertions(+), 101 deletions(-) create mode 100644 samplesheet.csv delete mode 100644 tower.yml diff --git a/assets/schema_input.json b/assets/schema_input.json index 275fcd9..38ee505 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -11,23 +11,18 @@ "type": "string", "pattern": "^\\S+$", "errorMessage": "Sample name must be provided and cannot contain spaces", - "meta": ["id"] + "meta": [ + "id" + ] }, - "fastq_1": { + "dataset_id": { "type": "string", - "format": "file-path", - "exists": true, - "pattern": "^\\S+\\.f(ast)?q\\.gz$", - "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" - }, - "fastq_2": { - "type": "string", - "format": "file-path", - "exists": true, - "pattern": "^\\S+\\.f(ast)?q\\.gz$", - "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + "pattern": "^\\S+$", + "errorMessage": "Dataset IDs cannot contain spaces" } }, - "required": ["sample", "fastq_1"] + "required": [ + "sample" + ] } -} +} \ No newline at end of file diff --git a/main.nf b/main.nf index 1884d6f..566232f 100644 --- a/main.nf +++ b/main.nf @@ -15,32 +15,9 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { SOPA } from './workflows/sopa' +include { SOPA } from './workflows/sopa' include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_sopa_pipeline' -include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_sopa_pipeline' -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - NAMED WORKFLOWS FOR PIPELINE -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -// -// WORKFLOW: Run main analysis pipeline depending on type of input -// -workflow NFCORE_SOPA { - - take: - samplesheet // channel: samplesheet read in from --input - - main: - - // - // WORKFLOW: Run pipeline - // - SOPA ( - samplesheet - ) -} +include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_sopa_pipeline' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -48,30 +25,28 @@ workflow NFCORE_SOPA { */ workflow { - - main: // // SUBWORKFLOW: Run initialisation tasks // - PIPELINE_INITIALISATION ( + PIPELINE_INITIALISATION( params.version, params.validate_params, params.monochrome_logs, args, params.outdir, - params.input + params.input, ) // // WORKFLOW: Run main workflow // - NFCORE_SOPA ( + NFCORE_SOPA( PIPELINE_INITIALISATION.out.samplesheet ) // // SUBWORKFLOW: Run completion tasks // - PIPELINE_COMPLETION ( + PIPELINE_COMPLETION( params.email, params.email_on_fail, params.plaintext_email, @@ -80,9 +55,25 @@ workflow { params.hook_url, ) } - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - THE END + NAMED WORKFLOWS FOR PIPELINE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +// +// WORKFLOW: Run main analysis pipeline depending on type of input +// +workflow NFCORE_SOPA { + take: + samplesheet // channel: samplesheet read in from --input + + main: + + // + // WORKFLOW: Run pipeline + // + SOPA( + samplesheet + ) +} diff --git a/samplesheet.csv b/samplesheet.csv new file mode 100644 index 0000000..d3a4604 --- /dev/null +++ b/samplesheet.csv @@ -0,0 +1,2 @@ +sample,dataset_id +.,test \ No newline at end of file diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index d5e65f2..cf84f63 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -8,14 +8,14 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' -include { paramsSummaryMap } from 'plugin/nf-schema' -include { samplesheetToList } from 'plugin/nf-schema' -include { completionEmail } from '../../nf-core/utils_nfcore_pipeline' -include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' -include { imNotification } from '../../nf-core/utils_nfcore_pipeline' -include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' -include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { completionEmail } from '../../nf-core/utils_nfcore_pipeline' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +include { imNotification } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -24,14 +24,13 @@ include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipelin */ workflow PIPELINE_INITIALISATION { - take: - version // boolean: Display version and exit - validate_params // boolean: Boolean whether to validate parameters against the schema at runtime - monochrome_logs // boolean: Do not use coloured log outputs + version // boolean: Display version and exit + validate_params // boolean: Boolean whether to validate parameters against the schema at runtime + monochrome_logs // boolean: Do not use coloured log outputs nextflow_cli_args // array: List of positional nextflow CLI args - outdir // string: The output directory where the results will be saved - input // string: Path to input samplesheet + outdir // string: The output directory where the results will be saved + input // string: Path to input samplesheet main: @@ -40,26 +39,26 @@ workflow PIPELINE_INITIALISATION { // // Print version and exit if required and dump pipeline parameters to JSON file // - UTILS_NEXTFLOW_PIPELINE ( + UTILS_NEXTFLOW_PIPELINE( version, true, outdir, - workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1 + workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1, ) // // Validate parameters and generate parameter summary to stdout // - UTILS_NFSCHEMA_PLUGIN ( + UTILS_NFSCHEMA_PLUGIN( workflow, validate_params, - null + null, ) // // Check config provided to the pipeline // - UTILS_NFCORE_PIPELINE ( + UTILS_NFCORE_PIPELINE( nextflow_cli_args ) @@ -69,27 +68,26 @@ workflow PIPELINE_INITIALISATION { Channel .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) - .map { - meta, fastq_1, fastq_2 -> - if (!fastq_2) { - return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] - } else { - return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] - } + .map { meta, dataset_id -> + if (!dataset_id) { + return [meta.id, meta + [single_end: true], []] + } + else { + return [meta.id, meta + [single_end: false], [dataset_id]] + } } .groupTuple() .map { samplesheet -> validateInputSamplesheet(samplesheet) } - .map { - meta, fastqs -> - return [ meta, fastqs.flatten() ] + .map { meta, dataset_id -> + return [meta, dataset_id.flatten()] } - .set { ch_samplesheet } + .set { -> ch_samplesheet } emit: samplesheet = ch_samplesheet - versions = ch_versions + versions = ch_versions } /* @@ -99,14 +97,13 @@ workflow PIPELINE_INITIALISATION { */ workflow PIPELINE_COMPLETION { - take: - email // string: email address - email_on_fail // string: email address sent on pipeline failure + email // string: email address + email_on_fail // string: email address sent on pipeline failure plaintext_email // boolean: Send plain-text email instead of HTML - outdir // path: Path to output directory where results will be published + outdir // path: Path to output directory where results will be published monochrome_logs // boolean: Disable ANSI colour codes in log output - hook_url // string: hook URL for notifications + hook_url // string: hook URL for notifications main: summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") @@ -114,7 +111,7 @@ workflow PIPELINE_COMPLETION { // // Completion email and summary // - workflow.onComplete { + workflow.onComplete { -> if (email || email_on_fail) { completionEmail( summary_params, @@ -123,7 +120,7 @@ workflow PIPELINE_COMPLETION { plaintext_email, outdir, monochrome_logs, - [] + [], ) } @@ -133,8 +130,8 @@ workflow PIPELINE_COMPLETION { } } - workflow.onError { - log.error "Pipeline failed. Please refer to troubleshooting docs: https://nf-co.re/docs/usage/troubleshooting" + workflow.onError { -> + log.error("Pipeline failed. Please refer to troubleshooting docs: https://nf-co.re/docs/usage/troubleshooting") } } @@ -148,15 +145,15 @@ workflow PIPELINE_COMPLETION { // Validate channels from input samplesheet // def validateInputSamplesheet(input) { - def (metas, fastqs) = input[1..2] + def (metas, dataset_id) = input[1..2] // Check that multiple runs of the same sample are of the same datatype i.e. single-end / paired-end - def endedness_ok = metas.collect{ meta -> meta.single_end }.unique().size == 1 + def endedness_ok = metas.collect { meta -> meta.single_end }.unique().size == 1 if (!endedness_ok) { error("Please check input samplesheet -> Multiple runs of a sample must be of the same datatype i.e. single-end or paired-end: ${metas[0].id}") } - return [ metas[0], fastqs ] + return [metas[0], dataset_id] } // // Generate methods description for MultiQC @@ -166,9 +163,9 @@ def toolCitationText() { // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "Tool (Foo et al. 2023)" : "", // Uncomment function in methodsDescriptionText to render in MultiQC report def citation_text = [ - "Tools used in the workflow included:", - "." - ].join(' ').trim() + "Tools used in the workflow included:", + ".", + ].join(' ').trim() return citation_text } @@ -178,7 +175,7 @@ def toolBibliographyText() { // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "
  • Author (2023) Pub name, Journal, DOI
  • " : "", // Uncomment function in methodsDescriptionText to render in MultiQC report def reference_text = [ - ].join(' ').trim() + ].join(' ').trim() return reference_text } @@ -200,7 +197,10 @@ def methodsDescriptionText(mqc_methods_yaml) { temp_doi_ref += "(doi: ${doi_ref.replace("https://doi.org/", "").replace(" ", "")}), " } meta["doi_text"] = temp_doi_ref.substring(0, temp_doi_ref.length() - 2) - } else meta["doi_text"] = "" + } + else { + meta["doi_text"] = "" + } meta["nodoi_text"] = meta.manifest_map.doi ? "" : "
  • If available, make sure to update the text to include the Zenodo DOI of version of the pipeline used.
  • " // Tool references @@ -214,9 +214,8 @@ def methodsDescriptionText(mqc_methods_yaml) { def methods_text = mqc_methods_yaml.text - def engine = new groovy.text.SimpleTemplateEngine() + def engine = new groovy.text.SimpleTemplateEngine() def description_html = engine.createTemplate(methods_text).make(meta) return description_html.toString() } - diff --git a/tower.yml b/tower.yml deleted file mode 100644 index c61323c..0000000 --- a/tower.yml +++ /dev/null @@ -1,3 +0,0 @@ -reports: - samplesheet.csv: - display: "Auto-created samplesheet with collated metadata and FASTQ paths" From 2299ee52917b5d63c26eda4b7c141f4c0baaf499 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Feb 2025 15:00:58 +0100 Subject: [PATCH 003/227] try running toy dataset --- toy/baysor.yaml | 53 ++++++ toy/cellpose.yaml | 33 ++++ samplesheet.csv => toy/samplesheet.csv | 0 workflows/sopa.nf | 217 +++++++++++++++++++++++-- 4 files changed, 291 insertions(+), 12 deletions(-) create mode 100644 toy/baysor.yaml create mode 100644 toy/cellpose.yaml rename samplesheet.csv => toy/samplesheet.csv (100%) diff --git a/toy/baysor.yaml b/toy/baysor.yaml new file mode 100644 index 0000000..fd5783a --- /dev/null +++ b/toy/baysor.yaml @@ -0,0 +1,53 @@ +# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml +read: + technology: xenium + +patchify: + patch_width_microns: 1000 + patch_overlap_microns: 20 + +segmentation: + tissue: + level: 2 + + baysor: + min_area: 20 + + config: + data: + force_2d: true # if false, uses 3D mode + min_molecules_per_cell: 10 + x: "x" + y: "y" + z: "z" + gene: "feature_name" + min_molecules_per_gene: 0 + min_molecules_per_segment: 3 + confidence_nn_id: 6 + + segmentation: + scale: 6.25 # typical cell radius in microns + scale_std: "25%" # cell radius standard deviation + prior_segmentation_confidence: 0 + estimate_scale_from_centers: false + n_clusters: 4 + iters: 500 + n_cells_init: 0 + nuclei_genes: "" + cyto_genes: "" + +aggregate: + average_intensities: true + min_transcripts: 10 # [optional] cells whose transcript count is below that this threshold are filtered + +# Comment this out if you want to use tangram --> + +# annotation: +# method: tangram +# args: +# sc_reference_path: "..." +# cell_type_key: ct + +explorer: + gene_column: "feature_name" + ram_threshold_gb: 4 diff --git a/toy/cellpose.yaml b/toy/cellpose.yaml new file mode 100644 index 0000000..ef592f4 --- /dev/null +++ b/toy/cellpose.yaml @@ -0,0 +1,33 @@ +# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml +read: + technology: toy_dataset + +patchify: + patch_width_pixel: 500 + patch_overlap_pixel: 20 + +segmentation: + + cellpose: + diameter: 35 + channels: [ "DAPI" ] + flow_threshold: 2 + cellprob_threshold: -6 + min_area: 2500 + +aggregate: + average_intensities: true + gene_column: genes + +annotation: + method: fluorescence + args: + marker_cell_dict: + CK: Tumoral cell + CD3: T cell + CD20: B cell + +explorer: + gene_column: "genes" + ram_threshold_gb: 4 + pixel_size: 1 diff --git a/samplesheet.csv b/toy/samplesheet.csv similarity index 100% rename from samplesheet.csv rename to toy/samplesheet.csv diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 1adbfff..49ce6c5 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -3,7 +3,7 @@ IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { paramsSummaryMap } from 'plugin/nf-schema' +include { paramsSummaryMap } from 'plugin/nf-schema' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_sopa_pipeline' @@ -14,32 +14,225 @@ include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_sopa */ workflow SOPA { - take: ch_samplesheet // channel: samplesheet read in from --input + main: ch_versions = Channel.empty() + def config = readConfigFile("toy/cellpose.yaml") + + def exp_dir = "test.zarr".replaceAll(/\.zarr$/, '.explorer') + + toSpatialData("test.zarr", exp_dir) + + sdata_path = toSpatialData.out.sdata_path + explorer_directory = toSpatialData.out.explorer_directory + + tissue_seg = config.segmentation.tissue ? tissueSegmentation(sdata_path, mapToCliArgs(config.segmentation.tissue)) : Channel.of([]) + + makeImagePatches(tissue_seg, sdata_path, mapToCliArgs(config.patchify)) + + cellpose_args = mapToCliArgs(config.segmentation.cellpose) + + makeImagePatches.out.patches_file_image + .map { file -> file.text.trim().toInteger() } + .map { n -> (0.. tuple(sdata_path.value, cellpose_args, index) } + .set { -> cellpose_ch } + + patchSegmentationCellpose(cellpose_ch) + .collect() + .set { -> resolve_trigger } + + aggregate_trigger = resolveCellpose(resolve_trigger, sdata_path) + + is_aggregated = aggregate(aggregate_trigger, sdata_path) + + report(is_aggregated, sdata_path, explorer_directory) + explorer(is_aggregated, sdata_path, explorer_directory, mapToCliArgs(config.explorer)) + + // // Collate and save software versions // softwareVersionsToYAML(ch_versions) .collectFile( storeDir: "${params.outdir}/pipeline_info", - name: 'nf_core_' + 'sopa_software_' + 'versions.yml', + name: 'nf_core_' + 'sopa_software_' + 'versions.yml', sort: true, - newLine: true - ).set { ch_collated_versions } - + newLine: true, + ) + .set { -> ch_collated_versions } emit: - versions = ch_versions // channel: [ path(versions.yml) ] + versions = ch_versions // channel: [ path(versions.yml) ] +} + +process toSpatialData { + publishDir 'results', mode: 'copy' + + input: + val sdata_path + val explorer_directory + + output: + path sdata_path, emit: sdata_path + path explorer_directory, emit: explorer_directory + + script: + """ + sopa convert . --sdata-path ${sdata_path} --technology toy_dataset + + mkdir -p ${explorer_directory} + touch ${explorer_directory}/.nextflow + """ } -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - THE END -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ +process tissueSegmentation { + publishDir 'results', mode: 'copy' + + input: + path sdata_path + val cli_arguments + + output: + path "${sdata_path}/shapes/region_of_interest" + + script: + """ + sopa segmentation tissue ${sdata_path} ${cli_arguments} + """ +} + +process makeImagePatches { + publishDir 'results', mode: 'copy' + + input: + val trigger + path sdata_path + val cli_arguments + + output: + path "${sdata_path}/shapes/image_patches" + path "${sdata_path}/.sopa_cache/patches_file_image", emit: patches_file_image + + script: + """ + sopa patchify image ${sdata_path} ${cli_arguments} + """ +} + +process patchSegmentationCellpose { + publishDir 'results', mode: 'copy' + + input: + tuple path(sdata_path), val(cli_arguments), val(index) + + output: + path "${sdata_path}/.sopa_cache/cellpose_boundaries/${index}.parquet" + + script: + """ + sopa segmentation cellpose ${sdata_path} --patch-index ${index} ${cli_arguments} + """ +} + +process resolveCellpose { + publishDir 'results', mode: 'copy' + + input: + val trigger + path sdata_path + + output: + path "${sdata_path}/shapes/cellpose_boundaries" + + script: + """ + sopa resolve cellpose ${sdata_path} + """ +} + +process aggregate { + publishDir 'results', mode: 'copy' + + input: + val trigger + path sdata_path + + output: + path "${sdata_path}/tables/table" + + script: + """ + sopa aggregate ${sdata_path} + """ +} + +process explorer { + publishDir 'results', mode: 'copy' + + input: + val trigger + path sdata_path + path explorer_experiment + val cli_arguments + + output: + path "${explorer_experiment}/experiment.xenium" + + script: + """ + sopa explorer write ${sdata_path} --output-path ${explorer_experiment} ${cli_arguments} + """ +} + +process report { + publishDir 'results', mode: 'copy' + + input: + val trigger + path sdata_path + path explorer_directory + + output: + path "${explorer_directory}/analysis_summary.html" + + script: + """ + sopa report ${sdata_path} ${explorer_directory}/analysis_summary.html + """ +} + +def stringifyItem(String key, value) { + key = key.replace('_', '-') + + def option = "--${key}" + + if (value instanceof Boolean) { + return value ? option : "--no-${key}" + } + if (value instanceof List) { + return value.collect { v -> "${option} ${stringifyValueForCli(v)}" }.join(" ") + } + return "${option} ${stringifyValueForCli(value)}" +} + +def stringifyValueForCli(value) { + if (value instanceof String || value instanceof Map) { + return "'${value}'" + } + return value.toString() +} + +def mapToCliArgs(Map params) { + return params.collect { key, value -> stringifyItem(key, value) }.join(" ") +} + +def readConfigFile(String config) { + return new groovy.yaml.YamlSlurper().parse(config as File) +} From 528435dbacba10e7cc84805857ee9571073d2b79 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Feb 2025 18:01:09 +0100 Subject: [PATCH 004/227] wip --- assets/schema_input.json | 4 ++- data | 0 .../local/utils_nfcore_sopa_pipeline/main.nf | 24 ++++--------- toy/samplesheet.csv | 4 +-- workflows/sopa.nf | 34 ++++++------------- 5 files changed, 23 insertions(+), 43 deletions(-) create mode 100644 data diff --git a/assets/schema_input.json b/assets/schema_input.json index 38ee505..260409d 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -10,7 +10,9 @@ "sample": { "type": "string", "pattern": "^\\S+$", - "errorMessage": "Sample name must be provided and cannot contain spaces", + "format": "file-path", + "exists": true, + "errorMessage": "Sample data path must exist", "meta": [ "id" ] diff --git a/data b/data new file mode 100644 index 0000000..e69de29 diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index cf84f63..b63c1d4 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -70,19 +70,17 @@ workflow PIPELINE_INITIALISATION { .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) .map { meta, dataset_id -> if (!dataset_id) { - return [meta.id, meta + [single_end: true], []] - } - else { - return [meta.id, meta + [single_end: false], [dataset_id]] + dataset_id = file(meta.id).baseName } + + def sdata_dir = "${dataset_id}.zarr" + def explorer_dir = "${dataset_id}.explorer" + + return [meta.id, meta, dataset_id, sdata_dir, explorer_dir] } - .groupTuple() .map { samplesheet -> validateInputSamplesheet(samplesheet) } - .map { meta, dataset_id -> - return [meta, dataset_id.flatten()] - } .set { -> ch_samplesheet } emit: @@ -145,15 +143,7 @@ workflow PIPELINE_COMPLETION { // Validate channels from input samplesheet // def validateInputSamplesheet(input) { - def (metas, dataset_id) = input[1..2] - - // Check that multiple runs of the same sample are of the same datatype i.e. single-end / paired-end - def endedness_ok = metas.collect { meta -> meta.single_end }.unique().size == 1 - if (!endedness_ok) { - error("Please check input samplesheet -> Multiple runs of a sample must be of the same datatype i.e. single-end or paired-end: ${metas[0].id}") - } - - return [metas[0], dataset_id] + return input } // // Generate methods description for MultiQC diff --git a/toy/samplesheet.csv b/toy/samplesheet.csv index d3a4604..3d7202e 100644 --- a/toy/samplesheet.csv +++ b/toy/samplesheet.csv @@ -1,2 +1,2 @@ -sample,dataset_id -.,test \ No newline at end of file +sample +data diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 49ce6c5..bd632d6 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -23,36 +23,29 @@ workflow SOPA { def config = readConfigFile("toy/cellpose.yaml") - def exp_dir = "test.zarr".replaceAll(/\.zarr$/, '.explorer') + sdata_dirs = ch_samplesheet.map { row -> row[3] } - toSpatialData("test.zarr", exp_dir) + sdata_path = toSpatialData(sdata_dirs) - sdata_path = toSpatialData.out.sdata_path - explorer_directory = toSpatialData.out.explorer_directory - - tissue_seg = config.segmentation.tissue ? tissueSegmentation(sdata_path, mapToCliArgs(config.segmentation.tissue)) : Channel.of([]) + tissue_seg = config.segmentation.tissue ? tissueSegmentation(sdata_path, mapToCliArgs(config.segmentation.tissue)) : "" makeImagePatches(tissue_seg, sdata_path, mapToCliArgs(config.patchify)) cellpose_args = mapToCliArgs(config.segmentation.cellpose) - makeImagePatches.out.patches_file_image - .map { file -> file.text.trim().toInteger() } - .map { n -> (0.. tuple(sdata_path.value, cellpose_args, index) } + sdata_path + .merge(makeImagePatches.out.patches_file_image) + .flatMap { zarr, index_file -> (0.. tuple(zarr, cellpose_args, index) } } .set { -> cellpose_ch } - patchSegmentationCellpose(cellpose_ch) - .collect() - .set { -> resolve_trigger } + patchSegmentationCellpose(cellpose_ch).set { -> resolve_trigger } - aggregate_trigger = resolveCellpose(resolve_trigger, sdata_path) + // aggregate_trigger = resolveCellpose(resolve_trigger, sdata_path) - is_aggregated = aggregate(aggregate_trigger, sdata_path) + // is_aggregated = aggregate(aggregate_trigger, sdata_path) - report(is_aggregated, sdata_path, explorer_directory) - explorer(is_aggregated, sdata_path, explorer_directory, mapToCliArgs(config.explorer)) + // report(is_aggregated, sdata_path, explorer_directory) + // explorer(is_aggregated, sdata_path, explorer_directory, mapToCliArgs(config.explorer)) // @@ -77,18 +70,13 @@ process toSpatialData { input: val sdata_path - val explorer_directory output: path sdata_path, emit: sdata_path - path explorer_directory, emit: explorer_directory script: """ sopa convert . --sdata-path ${sdata_path} --technology toy_dataset - - mkdir -p ${explorer_directory} - touch ${explorer_directory}/.nextflow """ } From 8d2cb5eb263f7967d1ff6d7f1660c127ea2e207b Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 3 Mar 2025 16:28:33 +0100 Subject: [PATCH 005/227] cellpose is running --- modules/local/utils.nf | 28 ++++++++++++++++++++++ workflows/sopa.nf | 54 ++++++++++-------------------------------- 2 files changed, 41 insertions(+), 41 deletions(-) create mode 100644 modules/local/utils.nf diff --git a/modules/local/utils.nf b/modules/local/utils.nf new file mode 100644 index 0000000..37d9ae6 --- /dev/null +++ b/modules/local/utils.nf @@ -0,0 +1,28 @@ +def stringifyItem(String key, value) { + key = key.replace('_', '-') + + def option = "--${key}" + + if (value instanceof Boolean) { + return value ? option : "--no-${key}" + } + if (value instanceof List) { + return value.collect { v -> "${option} ${stringifyValueForCli(v)}" }.join(" ") + } + return "${option} ${stringifyValueForCli(value)}" +} + +def stringifyValueForCli(value) { + if (value instanceof String || value instanceof Map) { + return "'${value}'" + } + return value.toString() +} + +def mapToCliArgs(Map params) { + return params.collect { key, value -> stringifyItem(key, value) }.join(" ") +} + +def readConfigFile(String config) { + return new groovy.yaml.YamlSlurper().parse(config as File) +} diff --git a/workflows/sopa.nf b/workflows/sopa.nf index bd632d6..a9e2023 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -6,7 +6,8 @@ include { paramsSummaryMap } from 'plugin/nf-schema' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_sopa_pipeline' - +include { readConfigFile } from '../modules/local/utils' +include { mapToCliArgs } from '../modules/local/utils' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -35,17 +36,18 @@ workflow SOPA { sdata_path .merge(makeImagePatches.out.patches_file_image) - .flatMap { zarr, index_file -> (0.. tuple(zarr, cellpose_args, index) } } - .set { -> cellpose_ch } + .map { zarr, patches_file_image -> tuple(zarr, patches_file_image.text.trim().toInteger()) } + .flatMap { zarr, n_patches -> (0.. tuple(zarr, cellpose_args, index, n_patches) } } + .set { cellpose_ch } - patchSegmentationCellpose(cellpose_ch).set { -> resolve_trigger } + ch_segmented = patchSegmentationCellpose(cellpose_ch).map { dataset_id, zarr, parquet, n_patches -> [groupKey(dataset_id, n_patches), zarr, parquet] }.groupTuple().map { it -> it[1][0] }.view() - // aggregate_trigger = resolveCellpose(resolve_trigger, sdata_path) + ch_resolved = resolveCellpose(ch_segmented) - // is_aggregated = aggregate(aggregate_trigger, sdata_path) + ch_aggregated = aggregate(ch_resolved, sdata_path) - // report(is_aggregated, sdata_path, explorer_directory) - // explorer(is_aggregated, sdata_path, explorer_directory, mapToCliArgs(config.explorer)) + // report(ch_aggregated, sdata_path, explorer_directory) + // explorer(ch_aggregated, sdata_path, explorer_directory, mapToCliArgs(config.explorer)) // @@ -58,7 +60,7 @@ workflow SOPA { sort: true, newLine: true, ) - .set { -> ch_collated_versions } + .set { ch_collated_versions } emit: versions = ch_versions // channel: [ path(versions.yml) ] @@ -118,10 +120,10 @@ process patchSegmentationCellpose { publishDir 'results', mode: 'copy' input: - tuple path(sdata_path), val(cli_arguments), val(index) + tuple path(sdata_path), val(cli_arguments), val(index), val(n_patches) output: - path "${sdata_path}/.sopa_cache/cellpose_boundaries/${index}.parquet" + tuple val(sdata_path), path(sdata_path), path("${sdata_path}/.sopa_cache/cellpose_boundaries/${index}.parquet"), val(n_patches) script: """ @@ -133,7 +135,6 @@ process resolveCellpose { publishDir 'results', mode: 'copy' input: - val trigger path sdata_path output: @@ -195,32 +196,3 @@ process report { sopa report ${sdata_path} ${explorer_directory}/analysis_summary.html """ } - -def stringifyItem(String key, value) { - key = key.replace('_', '-') - - def option = "--${key}" - - if (value instanceof Boolean) { - return value ? option : "--no-${key}" - } - if (value instanceof List) { - return value.collect { v -> "${option} ${stringifyValueForCli(v)}" }.join(" ") - } - return "${option} ${stringifyValueForCli(value)}" -} - -def stringifyValueForCli(value) { - if (value instanceof String || value instanceof Map) { - return "'${value}'" - } - return value.toString() -} - -def mapToCliArgs(Map params) { - return params.collect { key, value -> stringifyItem(key, value) }.join(" ") -} - -def readConfigFile(String config) { - return new groovy.yaml.YamlSlurper().parse(config as File) -} From 754e2ec87e8c8936776e98709728f3d7b75ee367 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 3 Mar 2025 16:33:07 +0100 Subject: [PATCH 006/227] minor cleanup / test --- data2 | 0 toy/samplesheet.csv | 1 + workflows/sopa.nf | 2 +- 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 data2 diff --git a/data2 b/data2 new file mode 100644 index 0000000..e69de29 diff --git a/toy/samplesheet.csv b/toy/samplesheet.csv index 3d7202e..0aaeb0b 100644 --- a/toy/samplesheet.csv +++ b/toy/samplesheet.csv @@ -1,2 +1,3 @@ sample data +data2 diff --git a/workflows/sopa.nf b/workflows/sopa.nf index a9e2023..bfc132b 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -40,7 +40,7 @@ workflow SOPA { .flatMap { zarr, n_patches -> (0.. tuple(zarr, cellpose_args, index, n_patches) } } .set { cellpose_ch } - ch_segmented = patchSegmentationCellpose(cellpose_ch).map { dataset_id, zarr, parquet, n_patches -> [groupKey(dataset_id, n_patches), zarr, parquet] }.groupTuple().map { it -> it[1][0] }.view() + ch_segmented = patchSegmentationCellpose(cellpose_ch).map { dataset_id, zarr, parquet, n_patches -> [groupKey(dataset_id, n_patches), zarr, parquet] }.groupTuple().map { it -> it[1][0] } ch_resolved = resolveCellpose(ch_segmented) From 68fa9df7f4fbb4eb1ad83bb0cd72cfc355454c53 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 3 Mar 2025 18:22:47 +0100 Subject: [PATCH 007/227] start using meta --- .../local/utils_nfcore_sopa_pipeline/main.nf | 11 +++----- workflows/sopa.nf | 28 ++++++++++--------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index b63c1d4..e19dcc9 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -73,15 +73,12 @@ workflow PIPELINE_INITIALISATION { dataset_id = file(meta.id).baseName } - def sdata_dir = "${dataset_id}.zarr" - def explorer_dir = "${dataset_id}.explorer" - - return [meta.id, meta, dataset_id, sdata_dir, explorer_dir] + return [id: meta.id, dataset_id: dataset_id, sdata_dir: "${dataset_id}.zarr", explorer_dir: "${dataset_id}.explorer"] } .map { samplesheet -> validateInputSamplesheet(samplesheet) } - .set { -> ch_samplesheet } + .set { ch_samplesheet } emit: samplesheet = ch_samplesheet @@ -109,7 +106,7 @@ workflow PIPELINE_COMPLETION { // // Completion email and summary // - workflow.onComplete { -> + workflow.onComplete { if (email || email_on_fail) { completionEmail( summary_params, @@ -128,7 +125,7 @@ workflow PIPELINE_COMPLETION { } } - workflow.onError { -> + workflow.onError { log.error("Pipeline failed. Please refer to troubleshooting docs: https://nf-co.re/docs/usage/troubleshooting") } } diff --git a/workflows/sopa.nf b/workflows/sopa.nf index bfc132b..7a93f5e 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -24,7 +24,7 @@ workflow SOPA { def config = readConfigFile("toy/cellpose.yaml") - sdata_dirs = ch_samplesheet.map { row -> row[3] } + sdata_dirs = ch_samplesheet.map { meta -> meta.sdata_dir } sdata_path = toSpatialData(sdata_dirs) @@ -46,8 +46,14 @@ workflow SOPA { ch_aggregated = aggregate(ch_resolved, sdata_path) - // report(ch_aggregated, sdata_path, explorer_directory) - // explorer(ch_aggregated, sdata_path, explorer_directory, mapToCliArgs(config.explorer)) + ch_dataset_id_explorer = ch_samplesheet.map { row -> [row[3], row[4]] } + + ch_explorer = ch_dataset_id_explorer.join(ch_aggregated).view() + + ch_samplesheet.map { meta -> meta.explorer_dir }.view() + + report(ch_explorer) + explorer(ch_explorer, mapToCliArgs(config.explorer)) // @@ -78,7 +84,7 @@ process toSpatialData { script: """ - sopa convert . --sdata-path ${sdata_path} --technology toy_dataset + sopa convert . --sdata-path ${sdata_path} --technology toy_dataset --kwargs '{"length": 200}' """ } @@ -154,7 +160,7 @@ process aggregate { path sdata_path output: - path "${sdata_path}/tables/table" + tuple val(sdata_path), path(sdata_path), path("${sdata_path}/tables/table") script: """ @@ -166,17 +172,15 @@ process explorer { publishDir 'results', mode: 'copy' input: - val trigger - path sdata_path - path explorer_experiment + tuple val(__), path(sdata_path), path(explorer_directory) val cli_arguments output: - path "${explorer_experiment}/experiment.xenium" + path "${explorer_directory}/experiment.xenium" script: """ - sopa explorer write ${sdata_path} --output-path ${explorer_experiment} ${cli_arguments} + sopa explorer write ${sdata_path} --output-path ${explorer_directory} ${cli_arguments} """ } @@ -184,9 +188,7 @@ process report { publishDir 'results', mode: 'copy' input: - val trigger - path sdata_path - path explorer_directory + tuple val(__), path(sdata_path), path(explorer_directory) output: path "${explorer_directory}/analysis_summary.html" From 8fbf215571e69cdc0fe2d44172ebcc1be5e3cfed Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 4 Mar 2025 11:24:53 +0100 Subject: [PATCH 008/227] working v0 --- .../local/utils_nfcore_sopa_pipeline/main.nf | 2 +- toy/cellpose.yaml | 4 +- toy/samplesheet.csv | 1 - workflows/sopa.nf | 86 ++++++++++--------- 4 files changed, 48 insertions(+), 45 deletions(-) diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index e19dcc9..2fdf694 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -73,7 +73,7 @@ workflow PIPELINE_INITIALISATION { dataset_id = file(meta.id).baseName } - return [id: meta.id, dataset_id: dataset_id, sdata_dir: "${dataset_id}.zarr", explorer_dir: "${dataset_id}.explorer"] + return [id: meta.id, sdata_dir: "${dataset_id}.zarr", explorer_dir: "${dataset_id}.explorer"] } .map { samplesheet -> validateInputSamplesheet(samplesheet) diff --git a/toy/cellpose.yaml b/toy/cellpose.yaml index ef592f4..b53fce6 100644 --- a/toy/cellpose.yaml +++ b/toy/cellpose.yaml @@ -3,8 +3,8 @@ read: technology: toy_dataset patchify: - patch_width_pixel: 500 - patch_overlap_pixel: 20 + patch_width_pixel: 1200 + patch_overlap_pixel: 50 segmentation: diff --git a/toy/samplesheet.csv b/toy/samplesheet.csv index 0aaeb0b..3d7202e 100644 --- a/toy/samplesheet.csv +++ b/toy/samplesheet.csv @@ -1,3 +1,2 @@ sample data -data2 diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 7a93f5e..c56dfaa 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -24,36 +24,32 @@ workflow SOPA { def config = readConfigFile("toy/cellpose.yaml") - sdata_dirs = ch_samplesheet.map { meta -> meta.sdata_dir } + ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }) - sdata_path = toSpatialData(sdata_dirs) + if (config.segmentation.tissue) { + (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, mapToCliArgs(config.segmentation.tissue)) + } + else { + ch_tissue_seg = ch_spatialdata + } - tissue_seg = config.segmentation.tissue ? tissueSegmentation(sdata_path, mapToCliArgs(config.segmentation.tissue)) : "" - - makeImagePatches(tissue_seg, sdata_path, mapToCliArgs(config.patchify)) + (ch_patches, _out) = makeImagePatches(ch_tissue_seg, mapToCliArgs(config.patchify)) cellpose_args = mapToCliArgs(config.segmentation.cellpose) - sdata_path - .merge(makeImagePatches.out.patches_file_image) - .map { zarr, patches_file_image -> tuple(zarr, patches_file_image.text.trim().toInteger()) } - .flatMap { zarr, n_patches -> (0.. tuple(zarr, cellpose_args, index, n_patches) } } - .set { cellpose_ch } - - ch_segmented = patchSegmentationCellpose(cellpose_ch).map { dataset_id, zarr, parquet, n_patches -> [groupKey(dataset_id, n_patches), zarr, parquet] }.groupTuple().map { it -> it[1][0] } - - ch_resolved = resolveCellpose(ch_segmented) + ch_patches + .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } + .flatMap { meta, sdata_path, n_patches -> (0.. [meta, sdata_path, cellpose_args, index, n_patches] } } + .set { ch_cellpose } - ch_aggregated = aggregate(ch_resolved, sdata_path) + ch_segmented = patchSegmentationCellpose(ch_cellpose).map { meta, sdata_path, _out2, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - ch_dataset_id_explorer = ch_samplesheet.map { row -> [row[3], row[4]] } + (ch_resolved, _out) = resolveCellpose(ch_segmented) - ch_explorer = ch_dataset_id_explorer.join(ch_aggregated).view() + (ch_aggregated, _out) = aggregate(ch_resolved) - ch_samplesheet.map { meta -> meta.explorer_dir }.view() - - report(ch_explorer) - explorer(ch_explorer, mapToCliArgs(config.explorer)) + report(ch_aggregated) + explorer(ch_aggregated, mapToCliArgs(config.explorer)) // @@ -77,14 +73,14 @@ process toSpatialData { publishDir 'results', mode: 'copy' input: - val sdata_path + tuple val(meta), val(sdata_dir) output: - path sdata_path, emit: sdata_path + tuple val(meta), path(sdata_dir) script: """ - sopa convert . --sdata-path ${sdata_path} --technology toy_dataset --kwargs '{"length": 200}' + sopa convert . --sdata-path ${meta.sdata_dir} --technology toy_dataset --kwargs '{"length": 200}' """ } @@ -92,10 +88,11 @@ process tissueSegmentation { publishDir 'results', mode: 'copy' input: - path sdata_path + tuple val(meta), path(sdata_path) val cli_arguments output: + tuple val(meta), path(sdata_path) path "${sdata_path}/shapes/region_of_interest" script: @@ -108,13 +105,12 @@ process makeImagePatches { publishDir 'results', mode: 'copy' input: - val trigger - path sdata_path + tuple val(meta), path(sdata_path) val cli_arguments output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/patches_file_image") path "${sdata_path}/shapes/image_patches" - path "${sdata_path}/.sopa_cache/patches_file_image", emit: patches_file_image script: """ @@ -126,10 +122,10 @@ process patchSegmentationCellpose { publishDir 'results', mode: 'copy' input: - tuple path(sdata_path), val(cli_arguments), val(index), val(n_patches) + tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) output: - tuple val(sdata_path), path(sdata_path), path("${sdata_path}/.sopa_cache/cellpose_boundaries/${index}.parquet"), val(n_patches) + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/cellpose_boundaries/${index}.parquet"), val(n_patches) script: """ @@ -141,9 +137,10 @@ process resolveCellpose { publishDir 'results', mode: 'copy' input: - path sdata_path + tuple val(meta), path(sdata_path) output: + tuple val(meta), path(sdata_path) path "${sdata_path}/shapes/cellpose_boundaries" script: @@ -156,11 +153,11 @@ process aggregate { publishDir 'results', mode: 'copy' input: - val trigger - path sdata_path + tuple val(meta), path(sdata_path) output: - tuple val(sdata_path), path(sdata_path), path("${sdata_path}/tables/table") + tuple val(meta), path(sdata_path) + path "${sdata_path}/tables/table" script: """ @@ -172,15 +169,20 @@ process explorer { publishDir 'results', mode: 'copy' input: - tuple val(__), path(sdata_path), path(explorer_directory) + tuple val(meta), path(sdata_path) val cli_arguments output: - path "${explorer_directory}/experiment.xenium" + path "${meta.explorer_dir}/experiment.xenium" + path "${meta.explorer_dir}/morphology.ome.tif" + path "${meta.explorer_dir}/cell_feature_matrix.zarr.zip" + path "${meta.explorer_dir}/cells.zarr.zip" + path "${meta.explorer_dir}/transcripts.zarr.zip" + path "${meta.explorer_dir}/adata.h5ad" script: """ - sopa explorer write ${sdata_path} --output-path ${explorer_directory} ${cli_arguments} + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} """ } @@ -188,13 +190,15 @@ process report { publishDir 'results', mode: 'copy' input: - tuple val(__), path(sdata_path), path(explorer_directory) + tuple val(meta), path(sdata_path) output: - path "${explorer_directory}/analysis_summary.html" + path "${meta.explorer_dir}/analysis_summary.html" script: - """ - sopa report ${sdata_path} ${explorer_directory}/analysis_summary.html + """ + mkdir -p ${meta.explorer_dir} + + sopa report ${sdata_path} ${meta.explorer_dir}/analysis_summary.html """ } From 64280a41b50634e88e28d85ee693e4418a0c2628 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 7 Mar 2025 09:58:35 +0100 Subject: [PATCH 009/227] move cellpose to a subworkflow --- subworkflows/local/cellpose/main.nf | 54 +++++++++++++++++++++++++++++ workflows/sopa.nf | 43 ++--------------------- 2 files changed, 56 insertions(+), 41 deletions(-) create mode 100644 subworkflows/local/cellpose/main.nf diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf new file mode 100644 index 0000000..2ccd680 --- /dev/null +++ b/subworkflows/local/cellpose/main.nf @@ -0,0 +1,54 @@ +include { mapToCliArgs } from '../../../modules/local/utils' + +workflow cellpose { + take: + ch_patches + config + + main: + cellpose_args = mapToCliArgs(config.segmentation.cellpose) + + ch_patches + .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } + .flatMap { meta, sdata_path, n_patches -> (0.. [meta, sdata_path, cellpose_args, index, n_patches] } } + .set { ch_cellpose } + + ch_segmented = patchSegmentation(ch_cellpose).map { meta, sdata_path, _out2, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } + + (ch_resolved, _out) = resolve(ch_segmented) + + emit: + ch_resolved +} + + +process patchSegmentation { + publishDir 'results', mode: 'copy' + + input: + tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/cellpose_boundaries/${index}.parquet"), val(n_patches) + + script: + """ + sopa segmentation cellpose ${sdata_path} --patch-index ${index} ${cli_arguments} + """ +} + +process resolve { + publishDir 'results', mode: 'copy' + + input: + tuple val(meta), path(sdata_path) + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/shapes/cellpose_boundaries" + + script: + """ + sopa resolve cellpose ${sdata_path} + """ +} diff --git a/workflows/sopa.nf b/workflows/sopa.nf index c56dfaa..d1be2c8 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -6,6 +6,7 @@ include { paramsSummaryMap } from 'plugin/nf-schema' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_sopa_pipeline' +include { cellpose } from '../subworkflows/local/cellpose' include { readConfigFile } from '../modules/local/utils' include { mapToCliArgs } from '../modules/local/utils' /* @@ -35,16 +36,7 @@ workflow SOPA { (ch_patches, _out) = makeImagePatches(ch_tissue_seg, mapToCliArgs(config.patchify)) - cellpose_args = mapToCliArgs(config.segmentation.cellpose) - - ch_patches - .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } - .flatMap { meta, sdata_path, n_patches -> (0.. [meta, sdata_path, cellpose_args, index, n_patches] } } - .set { ch_cellpose } - - ch_segmented = patchSegmentationCellpose(ch_cellpose).map { meta, sdata_path, _out2, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - - (ch_resolved, _out) = resolveCellpose(ch_segmented) + ch_resolved = cellpose(ch_patches, config) (ch_aggregated, _out) = aggregate(ch_resolved) @@ -118,37 +110,6 @@ process makeImagePatches { """ } -process patchSegmentationCellpose { - publishDir 'results', mode: 'copy' - - input: - tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) - - output: - tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/cellpose_boundaries/${index}.parquet"), val(n_patches) - - script: - """ - sopa segmentation cellpose ${sdata_path} --patch-index ${index} ${cli_arguments} - """ -} - -process resolveCellpose { - publishDir 'results', mode: 'copy' - - input: - tuple val(meta), path(sdata_path) - - output: - tuple val(meta), path(sdata_path) - path "${sdata_path}/shapes/cellpose_boundaries" - - script: - """ - sopa resolve cellpose ${sdata_path} - """ -} - process aggregate { publishDir 'results', mode: 'copy' From 6a1bcb8fdbebfeda545416df06dfb869cc62fd1d Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 7 Mar 2025 14:07:34 +0100 Subject: [PATCH 010/227] add baysor --- modules/local/utils.nf | 24 ++++++++-- nextflow.config | 1 - subworkflows/local/baysor/main.nf | 69 +++++++++++++++++++++++++++++ subworkflows/local/cellpose/main.nf | 2 +- toy/baysor.yaml | 7 +-- workflows/sopa.nf | 45 ++++++++++++++----- 6 files changed, 128 insertions(+), 20 deletions(-) create mode 100644 subworkflows/local/baysor/main.nf diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 37d9ae6..de3d585 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -9,20 +9,38 @@ def stringifyItem(String key, value) { if (value instanceof List) { return value.collect { v -> "${option} ${stringifyValueForCli(v)}" }.join(" ") } + if (value instanceof Map) { + return "${option} \"" + stringifyValueForCli(value) + "\"" + } return "${option} ${stringifyValueForCli(value)}" } def stringifyValueForCli(value) { - if (value instanceof String || value instanceof Map) { + if (value instanceof Map) { + return "{" + value.collect { k, v -> "'${k}': ${stringifyValueForCli(v)}" }.join(", ") + "}" + } + if (value instanceof List) { + return "[" + value.collect { stringifyValueForCli(it) }.join(", ") + "]" + } + if (value instanceof String) { return "'${value}'" } + if (value instanceof Boolean) { + return value ? "True" : "False" + } return value.toString() } -def mapToCliArgs(Map params) { - return params.collect { key, value -> stringifyItem(key, value) }.join(" ") +def mapToCliArgs(Map params, String contains = null, List keys = null) { + return params + .findAll { key, _value -> + (contains == null || key.contains(contains)) && (keys == null || key in keys) + } + .collect { key, value -> stringifyItem(key, value) } + .join(" ") } + def readConfigFile(String config) { return new groovy.yaml.YamlSlurper().parse(config as File) } diff --git a/nextflow.config b/nextflow.config index d9a0bd5..2c01cfc 100644 --- a/nextflow.config +++ b/nextflow.config @@ -178,7 +178,6 @@ env { PYTHONNOUSERSITE = 1 R_PROFILE_USER = "/.Rprofile" R_ENVIRON_USER = "/.Renviron" - JULIA_DEPOT_PATH = "/usr/local/share/julia" } // Set bash options diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf new file mode 100644 index 0000000..a7e950e --- /dev/null +++ b/subworkflows/local/baysor/main.nf @@ -0,0 +1,69 @@ +include { mapToCliArgs } from '../../../modules/local/utils' + +workflow baysor { + take: + ch_patches + config + + main: + baysor_args = mapToCliArgs(config.segmentation.baysor, null, ["config"]) + + ch_patches + .map { meta, sdata_path, patches_file_transcripts -> [meta, sdata_path, patches_file_transcripts.splitText()] } + .flatMap { meta, sdata_path, patches_indices -> patches_indices.collect { index -> [meta, sdata_path, baysor_args, index.trim().toInteger(), patches_indices.size] } } + .set { ch_baysor } + + ch_segmented = patchSegmentation(ch_baysor).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } + + (ch_resolved, _out) = resolve(ch_segmented, resolveArgs(config)) + + emit: + ch_resolved +} + + +process patchSegmentation { + publishDir 'results', mode: 'copy' + + input: + tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/transcript_patches/${index}/segmentation_counts.loom"), val(n_patches) + + script: + """ + if command -v module &> /dev/null; then + module purge + fi + + sopa segmentation baysor ${sdata_path} --patch-index ${index} ${cli_arguments} + """ +} + +process resolve { + publishDir 'results', mode: 'copy' + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/shapes/baysor_boundaries" + + script: + """ + sopa resolve baysor ${sdata_path} ${cli_arguments} + + rm -r ${sdata_path}/.sopa_cache/transcript_patches # cleanup large baysor files + """ +} + +def resolveArgs(Map config) { + def gene_column = config["segmentation"]["baysor"]["config"]["data"]["gene"] + + def min_area = config["segmentation"]["baysor"]["min_area"] ?: 0 + + return "--gene-column ${gene_column} --min-area ${min_area}" +} diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index 2ccd680..29d5c0b 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -13,7 +13,7 @@ workflow cellpose { .flatMap { meta, sdata_path, n_patches -> (0.. [meta, sdata_path, cellpose_args, index, n_patches] } } .set { ch_cellpose } - ch_segmented = patchSegmentation(ch_cellpose).map { meta, sdata_path, _out2, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } + ch_segmented = patchSegmentation(ch_cellpose).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } (ch_resolved, _out) = resolve(ch_segmented) diff --git a/toy/baysor.yaml b/toy/baysor.yaml index fd5783a..6cfa569 100644 --- a/toy/baysor.yaml +++ b/toy/baysor.yaml @@ -7,9 +7,6 @@ patchify: patch_overlap_microns: 20 segmentation: - tissue: - level: 2 - baysor: min_area: 20 @@ -20,7 +17,7 @@ segmentation: x: "x" y: "y" z: "z" - gene: "feature_name" + gene: "genes" min_molecules_per_gene: 0 min_molecules_per_segment: 3 confidence_nn_id: 6 @@ -49,5 +46,5 @@ aggregate: # cell_type_key: ct explorer: - gene_column: "feature_name" + gene_column: "genes" ram_threshold_gb: 4 diff --git a/workflows/sopa.nf b/workflows/sopa.nf index d1be2c8..89f594f 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -7,6 +7,7 @@ include { paramsSummaryMap } from 'plugin/nf-schema' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_sopa_pipeline' include { cellpose } from '../subworkflows/local/cellpose' +include { baysor } from '../subworkflows/local/baysor' include { readConfigFile } from '../modules/local/utils' include { mapToCliArgs } from '../modules/local/utils' /* @@ -23,7 +24,7 @@ workflow SOPA { ch_versions = Channel.empty() - def config = readConfigFile("toy/cellpose.yaml") + def config = readConfigFile("toy/baysor.yaml") ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }) @@ -34,9 +35,11 @@ workflow SOPA { ch_tissue_seg = ch_spatialdata } - (ch_patches, _out) = makeImagePatches(ch_tissue_seg, mapToCliArgs(config.patchify)) + // (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, mapToCliArgs(config.patchify, "pixel")) + // ch_resolved = cellpose(ch_image_patches, config) - ch_resolved = cellpose(ch_patches, config) + (ch_transcripts_patches, _out) = makeTranscriptPatches(ch_tissue_seg, mapToCliArgs(config.patchify, "micron")) + ch_resolved = baysor(ch_transcripts_patches, config) (ch_aggregated, _out) = aggregate(ch_resolved) @@ -60,6 +63,17 @@ workflow SOPA { versions = ch_versions // channel: [ path(versions.yml) ] } +process baysorVersion { + publishDir 'results', mode: 'copy' + + output: + path "baysor_version.txt" + + script: + """ + baysor --version > baysor_version.txt + """ +} process toSpatialData { publishDir 'results', mode: 'copy' @@ -72,7 +86,7 @@ process toSpatialData { script: """ - sopa convert . --sdata-path ${meta.sdata_dir} --technology toy_dataset --kwargs '{"length": 200}' + sopa convert . --sdata-path ${meta.sdata_dir} --technology toy_dataset --kwargs '{"length": 2000}' """ } @@ -110,6 +124,22 @@ process makeImagePatches { """ } +process makeTranscriptPatches { + publishDir 'results', mode: 'copy' + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/patches_file_transcripts") + + script: + """ + sopa patchify transcripts ${sdata_path} ${cli_arguments} + """ +} + process aggregate { publishDir 'results', mode: 'copy' @@ -134,12 +164,7 @@ process explorer { val cli_arguments output: - path "${meta.explorer_dir}/experiment.xenium" - path "${meta.explorer_dir}/morphology.ome.tif" - path "${meta.explorer_dir}/cell_feature_matrix.zarr.zip" - path "${meta.explorer_dir}/cells.zarr.zip" - path "${meta.explorer_dir}/transcripts.zarr.zip" - path "${meta.explorer_dir}/adata.h5ad" + path meta.explorer_dir script: """ From 43c79546e9a44a35caaa33ec909f0a6c1829e63d Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 7 Mar 2025 14:44:51 +0100 Subject: [PATCH 011/227] make logic between cellpose and baysor --- modules/local/utils.nf | 14 ++++++-- subworkflows/local/baysor/main.nf | 5 ++- toy/baysor.yaml | 29 ++++++++------- toy/baysor_overlaps.yaml | 53 +++++++++++++++++++++++++++ toy/baysor_vizgen.yaml | 57 +++++++++++++++++++++++++++++ toy/cellpose.yaml | 5 +-- toy/cellpose_baysor.yaml | 60 +++++++++++++++++++++++++++++++ toy/cellpose_comseg.yaml | 52 +++++++++++++++++++++++++++ toy/comseg.yaml | 46 ++++++++++++++++++++++++ toy/tissue_cellpose.yaml | 37 +++++++++++++++++++ workflows/sopa.nf | 59 +++++++++++++++++++----------- 11 files changed, 377 insertions(+), 40 deletions(-) create mode 100644 toy/baysor_overlaps.yaml create mode 100644 toy/baysor_vizgen.yaml create mode 100644 toy/cellpose_baysor.yaml create mode 100644 toy/cellpose_comseg.yaml create mode 100644 toy/comseg.yaml create mode 100644 toy/tissue_cellpose.yaml diff --git a/modules/local/utils.nf b/modules/local/utils.nf index de3d585..7b31fef 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -40,7 +40,17 @@ def mapToCliArgs(Map params, String contains = null, List keys = null) { .join(" ") } +def readConfigFile(String config_file) { + def config = new groovy.yaml.YamlSlurper().parse(config_file as File) -def readConfigFile(String config) { - return new groovy.yaml.YamlSlurper().parse(config as File) + if (config.segmentation.baysor) { + if (config.segmentation.cellpose) { + config.segmentation.baysor.prior_shapes_key = "cellpose_boundaries" + } + else if (config.segmentation.baysor.cell_key) { + println("Config argument 'cell_key' is deprecated. Use 'prior_shapes_key' instead.") + config.segmentation.baysor.prior_shapes_key = config.segmentation.baysor.cell_key + } + } + return config } diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index a7e950e..10be229 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -61,9 +61,8 @@ process resolve { } def resolveArgs(Map config) { - def gene_column = config["segmentation"]["baysor"]["config"]["data"]["gene"] - - def min_area = config["segmentation"]["baysor"]["min_area"] ?: 0 + def gene_column = config.segmentation.baysor.config.data.gene + def min_area = config.segmentation.baysor.min_area ?: 0 return "--gene-column ${gene_column} --min-area ${min_area}" } diff --git a/toy/baysor.yaml b/toy/baysor.yaml index 6cfa569..36c3727 100644 --- a/toy/baysor.yaml +++ b/toy/baysor.yaml @@ -1,18 +1,20 @@ # For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml read: - technology: xenium + technology: toy_dataset patchify: - patch_width_microns: 1000 + patch_width_pixel: 1200 + patch_overlap_pixel: 50 + patch_width_microns: 400 patch_overlap_microns: 20 segmentation: baysor: - min_area: 20 + min_area: 10 config: data: - force_2d: true # if false, uses 3D mode + force_2d: true min_molecules_per_cell: 10 x: "x" y: "y" @@ -23,7 +25,7 @@ segmentation: confidence_nn_id: 6 segmentation: - scale: 6.25 # typical cell radius in microns + scale: 3 # typical cell radius in microns scale_std: "25%" # cell radius standard deviation prior_segmentation_confidence: 0 estimate_scale_from_centers: false @@ -35,16 +37,17 @@ segmentation: aggregate: average_intensities: true - min_transcripts: 10 # [optional] cells whose transcript count is below that this threshold are filtered + min_transcripts: 5 # [optional] cells whose transcript count is below that this threshold are filtered -# Comment this out if you want to use tangram --> - -# annotation: -# method: tangram -# args: -# sc_reference_path: "..." -# cell_type_key: ct +annotation: + method: fluorescence + args: + marker_cell_dict: + CK: Tumoral cell + CD3: T cell + CD20: B cell explorer: gene_column: "genes" ram_threshold_gb: 4 + pixel_size: 0.1 diff --git a/toy/baysor_overlaps.yaml b/toy/baysor_overlaps.yaml new file mode 100644 index 0000000..1fc7049 --- /dev/null +++ b/toy/baysor_overlaps.yaml @@ -0,0 +1,53 @@ +# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml +read: + technology: toy_dataset + +patchify: + patch_width_pixel: 1200 + patch_overlap_pixel: 50 + patch_width_microns: 150 + patch_overlap_microns: 10 + +segmentation: + baysor: + min_area: 10 + + config: + data: + force_2d: true + min_molecules_per_cell: 10 + x: "x" + y: "y" + z: "z" + gene: "genes" + min_molecules_per_gene: 0 + min_molecules_per_segment: 3 + confidence_nn_id: 6 + + segmentation: + scale: 3 # typical cell radius in microns + scale_std: "25%" # cell radius standard deviation + prior_segmentation_confidence: 0 + estimate_scale_from_centers: false + n_clusters: 4 + iters: 500 + n_cells_init: 0 + nuclei_genes: "" + cyto_genes: "" + +aggregate: + average_intensities: true + min_transcripts: 5 # [optional] cells whose transcript count is below that this threshold are filtered + +annotation: + method: fluorescence + args: + marker_cell_dict: + CK: Tumoral cell + CD3: T cell + CD20: B cell + +explorer: + gene_column: "genes" + ram_threshold_gb: 4 + pixel_size: 0.1 diff --git a/toy/baysor_vizgen.yaml b/toy/baysor_vizgen.yaml new file mode 100644 index 0000000..819e727 --- /dev/null +++ b/toy/baysor_vizgen.yaml @@ -0,0 +1,57 @@ +# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml +read: + technology: toy_dataset + kwargs: + transcript_cell_id_as_merscope: true + +patchify: + patch_width_pixel: 1200 + patch_overlap_pixel: 50 + patch_width_microns: 400 + patch_overlap_microns: 20 + +segmentation: + baysor: + min_area: 10 + prior_shapes_key: "cell_id" + unassigned_value: -1 + + config: + data: + force_2d: true + min_molecules_per_cell: 10 + x: "x" + y: "y" + z: "z" + gene: "genes" + min_molecules_per_gene: 0 + min_molecules_per_segment: 3 + confidence_nn_id: 6 + + segmentation: + scale: 3 # typical cell radius in microns + scale_std: "25%" # cell radius standard deviation + prior_segmentation_confidence: 1 + estimate_scale_from_centers: false + n_clusters: 4 + iters: 500 + n_cells_init: 0 + nuclei_genes: "" + cyto_genes: "" + +aggregate: + average_intensities: true + min_transcripts: 5 # [optional] cells whose transcript count is below that this threshold are filtered + +annotation: + method: fluorescence + args: + marker_cell_dict: + CK: Tumoral cell + CD3: T cell + CD20: B cell + +explorer: + gene_column: "genes" + ram_threshold_gb: 4 + pixel_size: 0.1 diff --git a/toy/cellpose.yaml b/toy/cellpose.yaml index b53fce6..517d582 100644 --- a/toy/cellpose.yaml +++ b/toy/cellpose.yaml @@ -5,12 +5,13 @@ read: patchify: patch_width_pixel: 1200 patch_overlap_pixel: 50 + patch_width_microns: 3000 + patch_overlap_microns: 40 segmentation: - cellpose: diameter: 35 - channels: [ "DAPI" ] + channels: ["DAPI"] flow_threshold: 2 cellprob_threshold: -6 min_area: 2500 diff --git a/toy/cellpose_baysor.yaml b/toy/cellpose_baysor.yaml new file mode 100644 index 0000000..32fb7f8 --- /dev/null +++ b/toy/cellpose_baysor.yaml @@ -0,0 +1,60 @@ +# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml +read: + technology: toy_dataset + +patchify: + patch_width_pixel: 1200 + patch_overlap_pixel: 50 + patch_width_microns: 400 + patch_overlap_microns: 20 + +segmentation: + cellpose: + diameter: 35 + channels: ["DAPI"] + flow_threshold: 2 + cellprob_threshold: -6 + min_area: 2500 + + baysor: + min_area: 10 + + config: + data: + force_2d: true + min_molecules_per_cell: 10 + x: "x" + y: "y" + z: "z" + gene: "genes" + min_molecules_per_gene: 0 + min_molecules_per_segment: 3 + confidence_nn_id: 6 + + segmentation: + scale: 3 # typical cell radius in microns + scale_std: "25%" # cell radius standard deviation + prior_segmentation_confidence: 0 + estimate_scale_from_centers: false + n_clusters: 4 + iters: 500 + n_cells_init: 0 + nuclei_genes: "" + cyto_genes: "" + +aggregate: + average_intensities: true + min_transcripts: 5 # [optional] cells whose transcript count is below that this threshold are filtered + +annotation: + method: fluorescence + args: + marker_cell_dict: + CK: Tumoral cell + CD3: T cell + CD20: B cell + +explorer: + gene_column: "genes" + ram_threshold_gb: 4 + pixel_size: 0.1 diff --git a/toy/cellpose_comseg.yaml b/toy/cellpose_comseg.yaml new file mode 100644 index 0000000..e63c683 --- /dev/null +++ b/toy/cellpose_comseg.yaml @@ -0,0 +1,52 @@ +# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml +read: + technology: toy_dataset + kwargs: + add_nan_gene_name: false + +patchify: + patch_width_pixel: 1200 + patch_overlap_pixel: 50 + patch_width_microns: 3000 + patch_overlap_microns: 40 + +segmentation: + cellpose: + diameter: 35 + channels: ["DAPI"] + flow_threshold: 2 + cellprob_threshold: -6 + min_area: 2500 + + comseg: + min_area: 10 + + config: + dict_scale: + x: 1 + y: 1 + z: 1 + mean_cell_diameter: 15 + max_cell_radius: 25 + allow_disconnected_polygon: false + alpha: 0.5 + min_rna_per_cell: 5 + gene_column: "genes" + norm_vector: false # [optional] requires exeternal R package '"sctransform"' "feather" and "arrow" to be installed, otherwise set to false + +aggregate: + average_intensities: true + gene_column: genes + +annotation: + method: fluorescence + args: + marker_cell_dict: + CK: Tumoral cell + CD3: T cell + CD20: B cell + +explorer: + gene_column: "genes" + ram_threshold_gb: 4 + pixel_size: 1 diff --git a/toy/comseg.yaml b/toy/comseg.yaml new file mode 100644 index 0000000..071a625 --- /dev/null +++ b/toy/comseg.yaml @@ -0,0 +1,46 @@ +# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml +read: + technology: toy_dataset + kwargs: + add_nan_gene_name: false + +patchify: + patch_width_pixel: 1200 + patch_overlap_pixel: 50 + patch_width_microns: 3000 + patch_overlap_microns: 40 + +segmentation: + comseg: + min_area: 10 + prior_shapes_key: cells + + config: + dict_scale: + x: 1 + y: 1 + z: 1 + mean_cell_diameter: 15 + max_cell_radius: 25 + allow_disconnected_polygon: false + alpha: 0.5 + min_rna_per_cell: 5 + gene_column: "genes" + norm_vector: false # [optional] requires exeternal R package '"sctransform"' "feather" and "arrow" to be installed, otherwise set to false + +aggregate: + average_intensities: true + gene_column: genes + +annotation: + method: fluorescence + args: + marker_cell_dict: + CK: Tumoral cell + CD3: T cell + CD20: B cell + +explorer: + gene_column: "genes" + ram_threshold_gb: 4 + pixel_size: 1 diff --git a/toy/tissue_cellpose.yaml b/toy/tissue_cellpose.yaml new file mode 100644 index 0000000..91b7b2c --- /dev/null +++ b/toy/tissue_cellpose.yaml @@ -0,0 +1,37 @@ +# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml +read: + technology: toy_dataset + +patchify: + patch_width_pixel: 1200 + patch_overlap_pixel: 50 + patch_width_microns: 3000 + patch_overlap_microns: 40 + +segmentation: + tissue: + mode: saturation + + cellpose: + diameter: 35 + channels: ["DAPI"] + flow_threshold: 2 + cellprob_threshold: -6 + min_area: 2500 + +aggregate: + average_intensities: true + gene_column: genes + +annotation: + method: fluorescence + args: + marker_cell_dict: + CK: Tumoral cell + CD3: T cell + CD20: B cell + +explorer: + gene_column: "genes" + ram_threshold_gb: 4 + pixel_size: 1 diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 89f594f..5b8b692 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -24,10 +24,12 @@ workflow SOPA { ch_versions = Channel.empty() - def config = readConfigFile("toy/baysor.yaml") + def config = readConfigFile("toy/cellpose_baysor.yaml") ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }) + explorer_raw_inputs(ch_spatialdata, mapToCliArgs(config.explorer)) + if (config.segmentation.tissue) { (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, mapToCliArgs(config.segmentation.tissue)) } @@ -35,13 +37,19 @@ workflow SOPA { ch_tissue_seg = ch_spatialdata } - // (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, mapToCliArgs(config.patchify, "pixel")) - // ch_resolved = cellpose(ch_image_patches, config) + if (config.segmentation.cellpose) { + (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, mapToCliArgs(config.patchify, "pixel")) + ch_resolved = cellpose(ch_image_patches, config) + } + + if (config.segmentation.baysor) { + ch_input_baysor = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg - (ch_transcripts_patches, _out) = makeTranscriptPatches(ch_tissue_seg, mapToCliArgs(config.patchify, "micron")) - ch_resolved = baysor(ch_transcripts_patches, config) + (ch_transcripts_patches, _out) = makeTranscriptPatches(ch_input_baysor, transcriptPatchesArgs(config)) + ch_resolved = baysor(ch_transcripts_patches, config) + } - (ch_aggregated, _out) = aggregate(ch_resolved) + (ch_aggregated, _out) = aggregate(ch_resolved, mapToCliArgs(config.aggregate)) report(ch_aggregated) explorer(ch_aggregated, mapToCliArgs(config.explorer)) @@ -63,18 +71,6 @@ workflow SOPA { versions = ch_versions // channel: [ path(versions.yml) ] } -process baysorVersion { - publishDir 'results', mode: 'copy' - - output: - path "baysor_version.txt" - - script: - """ - baysor --version > baysor_version.txt - """ -} - process toSpatialData { publishDir 'results', mode: 'copy' @@ -145,6 +141,7 @@ process aggregate { input: tuple val(meta), path(sdata_path) + val cli_arguments output: tuple val(meta), path(sdata_path) @@ -152,7 +149,23 @@ process aggregate { script: """ - sopa aggregate ${sdata_path} + sopa aggregate ${sdata_path} ${cli_arguments} + """ +} + +process explorer_raw_inputs { + publishDir 'results', mode: 'copy' + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + path meta.explorer_dir + + script: + """ + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "+it" --no-save-h5ad """ } @@ -168,7 +181,7 @@ process explorer { script: """ - sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "-it" """ } @@ -188,3 +201,9 @@ process report { sopa report ${sdata_path} ${meta.explorer_dir}/analysis_summary.html """ } + +def transcriptPatchesArgs(Map config) { + def prior_args = mapToCliArgs(config.segmentation.baysor, null, ["prior_shapes_key", "unassigned_value"]) + + return mapToCliArgs(config.patchify, "micron") + " " + prior_args +} From 111c9a787212009fcd9f624144d2efa6189bed76 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 7 Mar 2025 15:17:43 +0100 Subject: [PATCH 012/227] can use --config and remove hardcoded publishdir --- conf/modules.config | 5 +-- main.nf | 7 +++- nextflow_schema.json | 28 ++++++++++++-- subworkflows/local/baysor/main.nf | 4 -- subworkflows/local/cellpose/main.nf | 4 -- .../local/utils_nfcore_sopa_pipeline/main.nf | 10 ++--- workflows/sopa.nf | 37 ++----------------- 7 files changed, 40 insertions(+), 55 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index e27fd28..30ab42b 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -13,9 +13,8 @@ process { publishDir = [ - path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + path: { params.outdir }, mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] - } diff --git a/main.nf b/main.nf index 566232f..b54785f 100644 --- a/main.nf +++ b/main.nf @@ -41,7 +41,8 @@ workflow { // WORKFLOW: Run main workflow // NFCORE_SOPA( - PIPELINE_INITIALISATION.out.samplesheet + PIPELINE_INITIALISATION.out.samplesheet, + params.config, ) // // SUBWORKFLOW: Run completion tasks @@ -67,6 +68,7 @@ workflow { workflow NFCORE_SOPA { take: samplesheet // channel: samplesheet read in from --input + config main: @@ -74,6 +76,7 @@ workflow NFCORE_SOPA { // WORKFLOW: Run pipeline // SOPA( - samplesheet + samplesheet, + config, ) } diff --git a/nextflow_schema.json b/nextflow_schema.json index 7eca6e0..ad34240 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -10,7 +10,11 @@ "type": "object", "fa_icon": "fas fa-terminal", "description": "Define where the pipeline should find input data and save output data.", - "required": ["input", "outdir"], + "required": [ + "input", + "outdir", + "config" + ], "properties": { "input": { "type": "string", @@ -23,6 +27,17 @@ "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row. See [usage docs](https://nf-co.re/sopa/usage#samplesheet-input).", "fa_icon": "fas fa-file-csv" }, + "config": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row. See [usage docs](https://nf-co.re/sopa/usage#samplesheet-input).", + "fa_icon": "fas fa-file-csv" + }, "outdir": { "type": "string", "format": "directory-path", @@ -105,7 +120,14 @@ "description": "Method used to save pipeline results to output directory.", "help_text": "The Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.", "fa_icon": "fas fa-copy", - "enum": ["symlink", "rellink", "link", "copy", "copyNoFollow", "move"], + "enum": [ + "symlink", + "rellink", + "link", + "copy", + "copyNoFollow", + "move" + ], "hidden": true }, "email_on_fail": { @@ -169,4 +191,4 @@ "$ref": "#/$defs/generic_options" } ] -} +} \ No newline at end of file diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index 10be229..7d98359 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -23,8 +23,6 @@ workflow baysor { process patchSegmentation { - publishDir 'results', mode: 'copy' - input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -42,8 +40,6 @@ process patchSegmentation { } process resolve { - publishDir 'results', mode: 'copy' - input: tuple val(meta), path(sdata_path) val cli_arguments diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index 29d5c0b..dc623a0 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -23,8 +23,6 @@ workflow cellpose { process patchSegmentation { - publishDir 'results', mode: 'copy' - input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -38,8 +36,6 @@ process patchSegmentation { } process resolve { - publishDir 'results', mode: 'copy' - input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index 2fdf694..5fa33c3 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -49,11 +49,11 @@ workflow PIPELINE_INITIALISATION { // // Validate parameters and generate parameter summary to stdout // - UTILS_NFSCHEMA_PLUGIN( - workflow, - validate_params, - null, - ) + // UTILS_NFSCHEMA_PLUGIN( + // workflow, + // validate_params, + // null, + // ) // // Check config provided to the pipeline diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 5b8b692..d82c203 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -19,17 +19,16 @@ include { mapToCliArgs } from '../modules/local/utils' workflow SOPA { take: ch_samplesheet // channel: samplesheet read in from --input + config_file main: ch_versions = Channel.empty() - def config = readConfigFile("toy/cellpose_baysor.yaml") + def config = readConfigFile(config_file) ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }) - explorer_raw_inputs(ch_spatialdata, mapToCliArgs(config.explorer)) - if (config.segmentation.tissue) { (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, mapToCliArgs(config.segmentation.tissue)) } @@ -72,8 +71,6 @@ workflow SOPA { } process toSpatialData { - publishDir 'results', mode: 'copy' - input: tuple val(meta), val(sdata_dir) @@ -87,8 +84,6 @@ process toSpatialData { } process tissueSegmentation { - publishDir 'results', mode: 'copy' - input: tuple val(meta), path(sdata_path) val cli_arguments @@ -104,8 +99,6 @@ process tissueSegmentation { } process makeImagePatches { - publishDir 'results', mode: 'copy' - input: tuple val(meta), path(sdata_path) val cli_arguments @@ -121,8 +114,6 @@ process makeImagePatches { } process makeTranscriptPatches { - publishDir 'results', mode: 'copy' - input: tuple val(meta), path(sdata_path) val cli_arguments @@ -137,8 +128,6 @@ process makeTranscriptPatches { } process aggregate { - publishDir 'results', mode: 'copy' - input: tuple val(meta), path(sdata_path) val cli_arguments @@ -153,25 +142,7 @@ process aggregate { """ } -process explorer_raw_inputs { - publishDir 'results', mode: 'copy' - - input: - tuple val(meta), path(sdata_path) - val cli_arguments - - output: - path meta.explorer_dir - - script: - """ - sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "+it" --no-save-h5ad - """ -} - process explorer { - publishDir 'results', mode: 'copy' - input: tuple val(meta), path(sdata_path) val cli_arguments @@ -181,13 +152,11 @@ process explorer { script: """ - sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "-it" + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} """ } process report { - publishDir 'results', mode: 'copy' - input: tuple val(meta), path(sdata_path) From fc592eb2f7146f061afe99c7c502d8f8b9389c7e Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 7 Mar 2025 17:07:15 +0100 Subject: [PATCH 013/227] use label process --- conf/test.config | 9 ++++--- conf/test_full.config | 8 +++---- main.nf | 6 ++--- modules/local/utils.nf | 4 ++-- nextflow_schema.json | 2 +- subworkflows/local/baysor/main.nf | 4 ++++ subworkflows/local/cellpose/main.nf | 4 ++++ data => toy/data | 0 data2 => toy/data2 | 0 toy/samplesheet.csv | 2 +- workflows/sopa.nf | 37 +++++++++++++++++++---------- 11 files changed, 47 insertions(+), 29 deletions(-) rename data => toy/data (100%) rename data2 => toy/data2 (100%) diff --git a/conf/test.config b/conf/test.config index e8cffce..3ea4e93 100644 --- a/conf/test.config +++ b/conf/test.config @@ -14,18 +14,17 @@ process { resourceLimits = [ cpus: 4, memory: '15.GB', - time: '1.h' + time: '1.h', ] } params { - config_profile_name = 'Test profile' + config_profile_name = 'Test profile' config_profile_description = 'Minimal test dataset to check pipeline function' // 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 - input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' - - + input = "${baseDir}/toy/samplesheet.csv" + configfile = "${baseDir}/toy/cellpose.yaml" } diff --git a/conf/test_full.config b/conf/test_full.config index 63eed15..8b14459 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -11,14 +11,12 @@ */ params { - config_profile_name = 'Full test profile' + config_profile_name = 'Full test profile' config_profile_description = 'Full test dataset to check pipeline function' // Input data for full size test // TODO nf-core: Specify the paths to your full test data ( on nf-core/test-datasets or directly in repositories, e.g. SRA) // TODO nf-core: Give any required params for the test so that command line flags are not needed - input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_full_illumina_amplicon.csv' - - // Fasta references - fasta = params.pipelines_testdata_base_path + 'viralrecon/genome/NC_045512.2/GCF_009858895.2_ASM985889v3_genomic.200409.fna.gz' + input = "${baseDir}/toy/samplesheet.csv" + configfile = "${baseDir}/toy/cellpose.yaml" } diff --git a/main.nf b/main.nf index b54785f..e09be6e 100644 --- a/main.nf +++ b/main.nf @@ -42,7 +42,7 @@ workflow { // NFCORE_SOPA( PIPELINE_INITIALISATION.out.samplesheet, - params.config, + params.configfile, ) // // SUBWORKFLOW: Run completion tasks @@ -68,7 +68,7 @@ workflow { workflow NFCORE_SOPA { take: samplesheet // channel: samplesheet read in from --input - config + configfile main: @@ -77,6 +77,6 @@ workflow NFCORE_SOPA { // SOPA( samplesheet, - config, + configfile, ) } diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 7b31fef..c2e1483 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -40,8 +40,8 @@ def mapToCliArgs(Map params, String contains = null, List keys = null) { .join(" ") } -def readConfigFile(String config_file) { - def config = new groovy.yaml.YamlSlurper().parse(config_file as File) +def readConfigFile(String configfile) { + def config = new groovy.yaml.YamlSlurper().parse(configfile as File) if (config.segmentation.baysor) { if (config.segmentation.cellpose) { diff --git a/nextflow_schema.json b/nextflow_schema.json index ad34240..9273e7d 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -27,7 +27,7 @@ "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row. See [usage docs](https://nf-co.re/sopa/usage#samplesheet-input).", "fa_icon": "fas fa-file-csv" }, - "config": { + "configfile": { "type": "string", "format": "file-path", "exists": true, diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index 7d98359..7b38846 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -23,6 +23,8 @@ workflow baysor { process patchSegmentation { + label "process_medium" + input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -40,6 +42,8 @@ process patchSegmentation { } process resolve { + label "process_low" + input: tuple val(meta), path(sdata_path) val cli_arguments diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index dc623a0..2951cb8 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -23,6 +23,8 @@ workflow cellpose { process patchSegmentation { + label "process_single" + input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -36,6 +38,8 @@ process patchSegmentation { } process resolve { + label "process_low" + input: tuple val(meta), path(sdata_path) diff --git a/data b/toy/data similarity index 100% rename from data rename to toy/data diff --git a/data2 b/toy/data2 similarity index 100% rename from data2 rename to toy/data2 diff --git a/toy/samplesheet.csv b/toy/samplesheet.csv index 3d7202e..ede083c 100644 --- a/toy/samplesheet.csv +++ b/toy/samplesheet.csv @@ -1,2 +1,2 @@ sample -data +toy/data diff --git a/workflows/sopa.nf b/workflows/sopa.nf index d82c203..ac48b7e 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -19,15 +19,15 @@ include { mapToCliArgs } from '../modules/local/utils' workflow SOPA { take: ch_samplesheet // channel: samplesheet read in from --input - config_file + configfile // sopa configfile from --configfile main: ch_versions = Channel.empty() - def config = readConfigFile(config_file) + def config = readConfigFile(configfile) - ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }) + ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }, mapToCliArgs(config.read)) if (config.segmentation.tissue) { (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, mapToCliArgs(config.segmentation.tissue)) @@ -57,33 +57,36 @@ workflow SOPA { // // Collate and save software versions // - softwareVersionsToYAML(ch_versions) - .collectFile( - storeDir: "${params.outdir}/pipeline_info", - name: 'nf_core_' + 'sopa_software_' + 'versions.yml', - sort: true, - newLine: true, - ) - .set { ch_collated_versions } + softwareVersionsToYAML(ch_versions).collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'nf_core_sopa_software_versions.yml', + sort: true, + newLine: true, + ) emit: versions = ch_versions // channel: [ path(versions.yml) ] } process toSpatialData { + label "process_high" + input: tuple val(meta), val(sdata_dir) + val cli_arguments output: tuple val(meta), path(sdata_dir) script: """ - sopa convert . --sdata-path ${meta.sdata_dir} --technology toy_dataset --kwargs '{"length": 2000}' + sopa convert ${meta.id} --sdata-path ${meta.sdata_dir} ${cli_arguments} """ } process tissueSegmentation { + label "process_low" + input: tuple val(meta), path(sdata_path) val cli_arguments @@ -99,6 +102,8 @@ process tissueSegmentation { } process makeImagePatches { + label "process_single" + input: tuple val(meta), path(sdata_path) val cli_arguments @@ -114,6 +119,8 @@ process makeImagePatches { } process makeTranscriptPatches { + label "process_medium" + input: tuple val(meta), path(sdata_path) val cli_arguments @@ -128,6 +135,8 @@ process makeTranscriptPatches { } process aggregate { + label "process_medium" + input: tuple val(meta), path(sdata_path) val cli_arguments @@ -143,6 +152,8 @@ process aggregate { } process explorer { + label "process_high" + input: tuple val(meta), path(sdata_path) val cli_arguments @@ -157,6 +168,8 @@ process explorer { } process report { + label "process_medium" + input: tuple val(meta), path(sdata_path) From 7e630600f0a0a0c6029b065a9078cd4ee4876eed Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 7 Mar 2025 17:13:30 +0100 Subject: [PATCH 014/227] minor readme update --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9c0c32c..5aba081 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ Now, you can run the pipeline using: nextflow run nf-core/sopa \ -profile \ --input samplesheet.csv \ + --configfile sopa_config_name.yaml \ --outdir ``` From 9d8db7fd0680e13b004b3b23dda7cad6273b130a Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 10 Mar 2025 13:13:57 +0100 Subject: [PATCH 015/227] add conda env files --- .gitignore | 1 + conf/test.config | 2 +- subworkflows/local/baysor/environment.yml | 8 ++++++++ subworkflows/local/baysor/main.nf | 4 ++++ subworkflows/local/cellpose/environment.yml | 8 ++++++++ subworkflows/local/cellpose/main.nf | 4 ++++ workflows/environment.yml | 8 ++++++++ workflows/sopa.nf | 17 +++++++++++++++++ 8 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 subworkflows/local/baysor/environment.yml create mode 100644 subworkflows/local/cellpose/environment.yml create mode 100644 workflows/environment.yml diff --git a/.gitignore b/.gitignore index a42ce01..42eba98 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ testing/ testing* *.pyc null/ +tests \ No newline at end of file diff --git a/conf/test.config b/conf/test.config index 3ea4e93..ea129ca 100644 --- a/conf/test.config +++ b/conf/test.config @@ -26,5 +26,5 @@ params { // 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 input = "${baseDir}/toy/samplesheet.csv" - configfile = "${baseDir}/toy/cellpose.yaml" + configfile = "${baseDir}/toy/baysor.yaml" } diff --git a/subworkflows/local/baysor/environment.yml b/subworkflows/local/baysor/environment.yml new file mode 100644 index 0000000..f3547f2 --- /dev/null +++ b/subworkflows/local/baysor/environment.yml @@ -0,0 +1,8 @@ +channels: +- conda-forge +- bioconda +dependencies: +- python=3.10 +- pip=24.3.1 +- pip: + - sopa[baysor]==2.0.1 diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index 7b38846..bd4ec8b 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -25,6 +25,8 @@ workflow baysor { process patchSegmentation { label "process_medium" + conda "${moduleDir}/environment.yml" + input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -44,6 +46,8 @@ process patchSegmentation { process resolve { label "process_low" + conda "${moduleDir}/environment.yml" + input: tuple val(meta), path(sdata_path) val cli_arguments diff --git a/subworkflows/local/cellpose/environment.yml b/subworkflows/local/cellpose/environment.yml new file mode 100644 index 0000000..b6a5167 --- /dev/null +++ b/subworkflows/local/cellpose/environment.yml @@ -0,0 +1,8 @@ +channels: +- conda-forge +- bioconda +dependencies: +- python=3.10 +- pip=24.3.1 +- pip: + - sopa==2.0.1 diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index 2951cb8..32d3d21 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -25,6 +25,8 @@ workflow cellpose { process patchSegmentation { label "process_single" + conda "${moduleDir}/environment.yml" + input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -40,6 +42,8 @@ process patchSegmentation { process resolve { label "process_low" + conda "${moduleDir}/environment.yml" + input: tuple val(meta), path(sdata_path) diff --git a/workflows/environment.yml b/workflows/environment.yml new file mode 100644 index 0000000..b6a5167 --- /dev/null +++ b/workflows/environment.yml @@ -0,0 +1,8 @@ +channels: +- conda-forge +- bioconda +dependencies: +- python=3.10 +- pip=24.3.1 +- pip: + - sopa==2.0.1 diff --git a/workflows/sopa.nf b/workflows/sopa.nf index ac48b7e..9bec590 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -71,6 +71,11 @@ workflow SOPA { process toSpatialData { label "process_high" + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'TODO' + : 'TODO'}" + input: tuple val(meta), val(sdata_dir) val cli_arguments @@ -87,6 +92,8 @@ process toSpatialData { process tissueSegmentation { label "process_low" + conda "${moduleDir}/environment.yml" + input: tuple val(meta), path(sdata_path) val cli_arguments @@ -104,6 +111,8 @@ process tissueSegmentation { process makeImagePatches { label "process_single" + conda "${moduleDir}/environment.yml" + input: tuple val(meta), path(sdata_path) val cli_arguments @@ -121,6 +130,8 @@ process makeImagePatches { process makeTranscriptPatches { label "process_medium" + conda "${moduleDir}/environment.yml" + input: tuple val(meta), path(sdata_path) val cli_arguments @@ -137,6 +148,8 @@ process makeTranscriptPatches { process aggregate { label "process_medium" + conda "${moduleDir}/environment.yml" + input: tuple val(meta), path(sdata_path) val cli_arguments @@ -154,6 +167,8 @@ process aggregate { process explorer { label "process_high" + conda "${moduleDir}/environment.yml" + input: tuple val(meta), path(sdata_path) val cli_arguments @@ -170,6 +185,8 @@ process explorer { process report { label "process_medium" + conda "${moduleDir}/environment.yml" + input: tuple val(meta), path(sdata_path) From f4cf6347bd31090a7b0406276d4f44060b4bab11 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 10 Mar 2025 13:14:20 +0100 Subject: [PATCH 016/227] fix conda env for cellpose --- subworkflows/local/cellpose/environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/local/cellpose/environment.yml b/subworkflows/local/cellpose/environment.yml index b6a5167..a1ee6d8 100644 --- a/subworkflows/local/cellpose/environment.yml +++ b/subworkflows/local/cellpose/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.10 - pip=24.3.1 - pip: - - sopa==2.0.1 + - sopa[cellpose]==2.0.1 From 7bd5177b4aa61203271115cddbb36f5e19a6c18a Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 10 Mar 2025 14:13:38 +0100 Subject: [PATCH 017/227] fix inputs validation (configfile) --- nextflow_schema.json | 12 +++++------- .../local/utils_nfcore_sopa_pipeline/main.nf | 10 +++++----- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/nextflow_schema.json b/nextflow_schema.json index 9273e7d..cdd67a5 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -13,7 +13,7 @@ "required": [ "input", "outdir", - "config" + "configfile" ], "properties": { "input": { @@ -31,12 +31,10 @@ "type": "string", "format": "file-path", "exists": true, - "schema": "assets/schema_input.json", - "mimetype": "text/csv", - "pattern": "^\\S+\\.csv$", - "description": "Path to comma-separated file containing information about the samples in the experiment.", - "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row. See [usage docs](https://nf-co.re/sopa/usage#samplesheet-input).", - "fa_icon": "fas fa-file-csv" + "pattern": "^\\S+\\.yaml$", + "description": "Path to a Sopa config file describing the technology used and the pipeline parameters.", + "help_text": "Choose one existing config file amont public one: https://github.com/gustaveroussy/sopa/tree/master/workflow/config", + "fa_icon": "fas fa-file" }, "outdir": { "type": "string", diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index 5fa33c3..2fdf694 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -49,11 +49,11 @@ workflow PIPELINE_INITIALISATION { // // Validate parameters and generate parameter summary to stdout // - // UTILS_NFSCHEMA_PLUGIN( - // workflow, - // validate_params, - // null, - // ) + UTILS_NFSCHEMA_PLUGIN( + workflow, + validate_params, + null, + ) // // Check config provided to the pipeline From 330b2de8e1a15ac82a9a2f918b4eca97499d8bac Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 10 Mar 2025 14:32:33 +0100 Subject: [PATCH 018/227] clean versions + right explorer outputs --- subworkflows/local/baysor/environment.yml | 2 +- subworkflows/local/cellpose/environment.yml | 2 +- workflows/environment.yml | 2 +- workflows/sopa.nf | 29 +++++++++++++++++++-- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/subworkflows/local/baysor/environment.yml b/subworkflows/local/baysor/environment.yml index f3547f2..03ebdf2 100644 --- a/subworkflows/local/baysor/environment.yml +++ b/subworkflows/local/baysor/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.10 - pip=24.3.1 - pip: - - sopa[baysor]==2.0.1 + - sopa[baysor]>=2.0.2 diff --git a/subworkflows/local/cellpose/environment.yml b/subworkflows/local/cellpose/environment.yml index a1ee6d8..fa547f9 100644 --- a/subworkflows/local/cellpose/environment.yml +++ b/subworkflows/local/cellpose/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.10 - pip=24.3.1 - pip: - - sopa[cellpose]==2.0.1 + - sopa[cellpose]>=2.0.2 diff --git a/workflows/environment.yml b/workflows/environment.yml index b6a5167..d0aebab 100644 --- a/workflows/environment.yml +++ b/workflows/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.10 - pip=24.3.1 - pip: - - sopa==2.0.1 + - sopa>=2.0.2 diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 9bec590..8467781 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -29,6 +29,8 @@ workflow SOPA { ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }, mapToCliArgs(config.read)) + // explorer_raw(ch_spatialdata, mapToCliArgs(config.explorer)) + if (config.segmentation.tissue) { (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, mapToCliArgs(config.segmentation.tissue)) } @@ -164,6 +166,25 @@ process aggregate { """ } +process explorer_raw { + label "process_high" + + conda "${moduleDir}/environment.yml" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + path "${meta.explorer_dir}/morphology.ome.tif" + path "${meta.explorer_dir}/transcripts.zarr.zip" + + script: + """ + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "+it" --no-save-h5ad + """ +} + process explorer { label "process_high" @@ -174,11 +195,15 @@ process explorer { val cli_arguments output: - path meta.explorer_dir + path "${meta.explorer_dir}/experiment.xenium" + path "${meta.explorer_dir}/analysis.zarr.zip" + path "${meta.explorer_dir}/cell_feature_matrix.zarr.zip" + path "${meta.explorer_dir}/adata.h5ad" + path "${meta.explorer_dir}/cells.zarr.zip" script: """ - sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "-it" """ } From d8166c5e36a927c95b8f7c9c3fad367eadc4590e Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 10 Mar 2025 14:47:03 +0100 Subject: [PATCH 019/227] add jeffquinnmsk/sopa container --- subworkflows/local/baysor/main.nf | 2 ++ subworkflows/local/cellpose/main.nf | 2 ++ workflows/sopa.nf | 11 ++++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index bd4ec8b..2b805a9 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -26,6 +26,7 @@ process patchSegmentation { label "process_medium" conda "${moduleDir}/environment.yml" + container "jeffquinnmsk/sopa" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -47,6 +48,7 @@ process resolve { label "process_low" conda "${moduleDir}/environment.yml" + container "jeffquinnmsk/sopa" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index 32d3d21..aa243ed 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -26,6 +26,7 @@ process patchSegmentation { label "process_single" conda "${moduleDir}/environment.yml" + container "jeffquinnmsk/sopa" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -43,6 +44,7 @@ process resolve { label "process_low" conda "${moduleDir}/environment.yml" + container "jeffquinnmsk/sopa" input: tuple val(meta), path(sdata_path) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 8467781..52c3f3c 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -74,9 +74,7 @@ process toSpatialData { label "process_high" conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'TODO' - : 'TODO'}" + container "jeffquinnmsk/sopa" input: tuple val(meta), val(sdata_dir) @@ -95,6 +93,7 @@ process tissueSegmentation { label "process_low" conda "${moduleDir}/environment.yml" + container "jeffquinnmsk/sopa" input: tuple val(meta), path(sdata_path) @@ -114,6 +113,7 @@ process makeImagePatches { label "process_single" conda "${moduleDir}/environment.yml" + container "jeffquinnmsk/sopa" input: tuple val(meta), path(sdata_path) @@ -133,6 +133,7 @@ process makeTranscriptPatches { label "process_medium" conda "${moduleDir}/environment.yml" + container "jeffquinnmsk/sopa" input: tuple val(meta), path(sdata_path) @@ -151,6 +152,7 @@ process aggregate { label "process_medium" conda "${moduleDir}/environment.yml" + container "jeffquinnmsk/sopa" input: tuple val(meta), path(sdata_path) @@ -170,6 +172,7 @@ process explorer_raw { label "process_high" conda "${moduleDir}/environment.yml" + container "jeffquinnmsk/sopa" input: tuple val(meta), path(sdata_path) @@ -189,6 +192,7 @@ process explorer { label "process_high" conda "${moduleDir}/environment.yml" + container "jeffquinnmsk/sopa" input: tuple val(meta), path(sdata_path) @@ -211,6 +215,7 @@ process report { label "process_medium" conda "${moduleDir}/environment.yml" + container "jeffquinnmsk/sopa" input: tuple val(meta), path(sdata_path) From a4b90752be3170d210b118491756380118862e0b Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 10 Mar 2025 14:53:06 +0100 Subject: [PATCH 020/227] remove image for baysor --- subworkflows/local/baysor/main.nf | 1 - 1 file changed, 1 deletion(-) diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index 2b805a9..e97f565 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -26,7 +26,6 @@ process patchSegmentation { label "process_medium" conda "${moduleDir}/environment.yml" - container "jeffquinnmsk/sopa" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) From e2cab8c40d860b43831366873d506eaac7efb2e6 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 10 Mar 2025 15:52:35 +0100 Subject: [PATCH 021/227] try c51 config --- conf/c51.config | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 conf/c51.config diff --git a/conf/c51.config b/conf/c51.config new file mode 100644 index 0000000..edabe4c --- /dev/null +++ b/conf/c51.config @@ -0,0 +1,79 @@ +params { + max_memory = 256.GB + max_cpus = 32 + max_time = 2.d +} + +process { + executor = 'slurm' + // queue = '' // Your default queue or partition + containerOptions = '--user $(id -u):$(id -g)' + errorStrategy = 'retry' + maxRetries = 5 + + // Lightweight tasks: Fits into the standard partition + withLabel: process_single { + queue = 'standard' + resourceLimits = [ + cpus: 4, + memory: 30.GB, + time: 2.d, + ] + } + + // Low resource tasks: Use nf-standard-mem + withLabel: process_low { + queue = 'nf-standard-mem' + resourceLimits = [ + cpus: 8, + memory: 60.GB, + time: 2.d, + ] + } + + // Medium resource tasks: Use nf-standard-mem or nf-high-mem + withLabel: process_medium { + queue = 'nf-high-mem' + resourceLimits = [ + cpus: 16, + memory: 120.GB, + time: 2.d, + ] + } + + // High resource tasks: Use nf-high-mem + withLabel: process_high { + queue = 'nf-high-mem' + resourceLimits = [ + cpus: 16, + memory: 120.GB, + time: 2.d, + ] + } + + // Long-running tasks: Use high partition for extended time + withLabel: process_long { + queue = 'high' + resourceLimits = [ + cpus: 32, + memory: 250.GB, + time: 2.d, + ] + } + + // Memory-intensive tasks: Use high partition for maximum memory + withLabel: process_high_memory { + queue = 'high' + resourceLimits = [ + cpus: 32, + memory: 250.GB, + time: 2.d, + ] + } +} + +aws { + client { + anonymous = true + } +} From a9c9918b6a1ee9503f043ceaddd775f75eccc834 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 10 Mar 2025 15:56:38 +0100 Subject: [PATCH 022/227] add slurm profile --- conf/{c51.config => slurm.config} | 0 nextflow.config | 1 + 2 files changed, 1 insertion(+) rename conf/{c51.config => slurm.config} (100%) diff --git a/conf/c51.config b/conf/slurm.config similarity index 100% rename from conf/c51.config rename to conf/slurm.config diff --git a/nextflow.config b/nextflow.config index 2c01cfc..0e79ead 100644 --- a/nextflow.config +++ b/nextflow.config @@ -149,6 +149,7 @@ profiles { } } test { includeConfig 'conf/test.config' } + slurm { includeConfig 'conf/slurm.config' } test_full { includeConfig 'conf/test_full.config' } } From 8b1a8419bbd53f2ac1aea6876d182ed2a3ae1bfb Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 10 Mar 2025 15:59:56 +0100 Subject: [PATCH 023/227] try validation path --- assets/schema_input.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/schema_input.json b/assets/schema_input.json index 260409d..e42e5fc 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -10,7 +10,7 @@ "sample": { "type": "string", "pattern": "^\\S+$", - "format": "file-path", + "format": "path", "exists": true, "errorMessage": "Sample data path must exist", "meta": [ From 4dcaa63bc3196f918ad026aa33b1a1325e76896d Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 11 Mar 2025 11:43:24 +0100 Subject: [PATCH 024/227] try symlink --- conf/slurm.config | 6 ------ nextflow_schema.json | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/conf/slurm.config b/conf/slurm.config index edabe4c..6f546af 100644 --- a/conf/slurm.config +++ b/conf/slurm.config @@ -1,9 +1,3 @@ -params { - max_memory = 256.GB - max_cpus = 32 - max_time = 2.d -} - process { executor = 'slurm' // queue = '' // Your default queue or partition diff --git a/nextflow_schema.json b/nextflow_schema.json index cdd67a5..534c77a 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -114,7 +114,7 @@ }, "publish_dir_mode": { "type": "string", - "default": "copy", + "default": "symlink", "description": "Method used to save pipeline results to output directory.", "help_text": "The Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.", "fa_icon": "fas fa-copy", From 0965bc7f9aaffe0be9b8fd2861165da614ff42e2 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 11 Mar 2025 17:10:23 +0100 Subject: [PATCH 025/227] use symlink --- nextflow.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nextflow.config b/nextflow.config index 0e79ead..d456683 100644 --- a/nextflow.config +++ b/nextflow.config @@ -15,7 +15,7 @@ params { // Boilerplate options outdir = null - publish_dir_mode = 'copy' + publish_dir_mode = 'symlink' email = null email_on_fail = null plaintext_email = false From 8aa086d69e6734ece9572249a514e8033059e8a8 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 11 Mar 2025 17:52:48 +0100 Subject: [PATCH 026/227] publish at the end --- conf/modules.config | 6 ------ workflows/sopa.nf | 27 ++++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 30ab42b..8b7dd54 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -11,10 +11,4 @@ */ process { - - publishDir = [ - path: { params.outdir }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, - ] } diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 52c3f3c..f9c19be 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -52,8 +52,10 @@ workflow SOPA { (ch_aggregated, _out) = aggregate(ch_resolved, mapToCliArgs(config.aggregate)) - report(ch_aggregated) explorer(ch_aggregated, mapToCliArgs(config.explorer)) + report(ch_aggregated) + + publish(ch_aggregated.map { it[1] }) // @@ -174,6 +176,8 @@ process explorer_raw { conda "${moduleDir}/environment.yml" container "jeffquinnmsk/sopa" + publishDir "${params.outdir}", mode: params.publish_dir_mode + input: tuple val(meta), path(sdata_path) val cli_arguments @@ -194,6 +198,8 @@ process explorer { conda "${moduleDir}/environment.yml" container "jeffquinnmsk/sopa" + publishDir "${params.outdir}", mode: params.publish_dir_mode + input: tuple val(meta), path(sdata_path) val cli_arguments @@ -217,6 +223,8 @@ process report { conda "${moduleDir}/environment.yml" container "jeffquinnmsk/sopa" + publishDir "${params.outdir}", mode: params.publish_dir_mode + input: tuple val(meta), path(sdata_path) @@ -231,6 +239,23 @@ process report { """ } +process publish { + label "process_single" + + publishDir "${params.outdir}", mode: params.publish_dir_mode + + input: + path sdata_path + + output: + path sdata_path + + script: + """ + echo "Publishing ${sdata_path}" + """ +} + def transcriptPatchesArgs(Map config) { def prior_args = mapToCliArgs(config.segmentation.baysor, null, ["prior_shapes_key", "unassigned_value"]) From 26c2a82a64ac8cbaded8ee2e93e249450d835f6f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 11 Mar 2025 17:57:32 +0100 Subject: [PATCH 027/227] use publish dir mode copy --- nextflow.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nextflow.config b/nextflow.config index d456683..0e79ead 100644 --- a/nextflow.config +++ b/nextflow.config @@ -15,7 +15,7 @@ params { // Boilerplate options outdir = null - publish_dir_mode = 'symlink' + publish_dir_mode = 'copy' email = null email_on_fail = null plaintext_email = false From 99c18dedd80e8275dd72b9415065426ea33b088f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 12 Mar 2025 09:07:47 +0100 Subject: [PATCH 028/227] re-run baysor with process_high --- subworkflows/local/baysor/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index e97f565..3dc77bd 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -23,7 +23,7 @@ workflow baysor { process patchSegmentation { - label "process_medium" + label "process_high" conda "${moduleDir}/environment.yml" From a2863698af95515b53ddc31495d18eae232b8121 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 12 Mar 2025 15:25:40 +0100 Subject: [PATCH 029/227] terminate config --- conf/slurm.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/slurm.config b/conf/slurm.config index 6f546af..36be4e7 100644 --- a/conf/slurm.config +++ b/conf/slurm.config @@ -2,7 +2,7 @@ process { executor = 'slurm' // queue = '' // Your default queue or partition containerOptions = '--user $(id -u):$(id -g)' - errorStrategy = 'retry' + errorStrategy = 'terminate' maxRetries = 5 // Lightweight tasks: Fits into the standard partition From a00cca64d7a8eb9068e38d00dc57a9daf7a7e25c Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 12 Mar 2025 16:33:37 +0100 Subject: [PATCH 030/227] try errorStrategy = 'ignore' --- conf/modules.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conf/modules.config b/conf/modules.config index 8b7dd54..26828a2 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -11,4 +11,7 @@ */ process { + withName: patchSegmentation { + errorStrategy = 'ignore' + } } From dad5e7d286803e0aabad986ab7f4eb3007742d3f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 12 Mar 2025 17:52:41 +0100 Subject: [PATCH 031/227] docker containers + use process_long for baysor --- conf/modules.config | 3 --- subworkflows/local/baysor/main.nf | 12 +++++++---- subworkflows/local/cellpose/main.nf | 8 ++++++-- workflows/sopa.nf | 32 +++++++++++++++++++++-------- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 26828a2..8b7dd54 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -11,7 +11,4 @@ */ process { - withName: patchSegmentation { - errorStrategy = 'ignore' - } } diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index 3dc77bd..d549d33 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -23,9 +23,11 @@ workflow baysor { process patchSegmentation { - label "process_high" + label "process_long" - conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/baysor:latest' + : 'docker.io/jeffquinnmsk/baysor:latest'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -38,7 +40,7 @@ process patchSegmentation { if command -v module &> /dev/null; then module purge fi - + sopa segmentation baysor ${sdata_path} --patch-index ${index} ${cli_arguments} """ } @@ -47,7 +49,9 @@ process resolve { label "process_low" conda "${moduleDir}/environment.yml" - container "jeffquinnmsk/sopa" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index aa243ed..6360f00 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -26,7 +26,9 @@ process patchSegmentation { label "process_single" conda "${moduleDir}/environment.yml" - container "jeffquinnmsk/sopa" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -44,7 +46,9 @@ process resolve { label "process_low" conda "${moduleDir}/environment.yml" - container "jeffquinnmsk/sopa" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" input: tuple val(meta), path(sdata_path) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index f9c19be..25b4437 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -76,7 +76,9 @@ process toSpatialData { label "process_high" conda "${moduleDir}/environment.yml" - container "jeffquinnmsk/sopa" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" input: tuple val(meta), val(sdata_dir) @@ -95,7 +97,9 @@ process tissueSegmentation { label "process_low" conda "${moduleDir}/environment.yml" - container "jeffquinnmsk/sopa" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" input: tuple val(meta), path(sdata_path) @@ -115,7 +119,9 @@ process makeImagePatches { label "process_single" conda "${moduleDir}/environment.yml" - container "jeffquinnmsk/sopa" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" input: tuple val(meta), path(sdata_path) @@ -135,7 +141,9 @@ process makeTranscriptPatches { label "process_medium" conda "${moduleDir}/environment.yml" - container "jeffquinnmsk/sopa" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" input: tuple val(meta), path(sdata_path) @@ -154,7 +162,9 @@ process aggregate { label "process_medium" conda "${moduleDir}/environment.yml" - container "jeffquinnmsk/sopa" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" input: tuple val(meta), path(sdata_path) @@ -174,7 +184,9 @@ process explorer_raw { label "process_high" conda "${moduleDir}/environment.yml" - container "jeffquinnmsk/sopa" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -196,7 +208,9 @@ process explorer { label "process_high" conda "${moduleDir}/environment.yml" - container "jeffquinnmsk/sopa" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -221,7 +235,9 @@ process report { label "process_medium" conda "${moduleDir}/environment.yml" - container "jeffquinnmsk/sopa" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" publishDir "${params.outdir}", mode: params.publish_dir_mode From 5a63bafa72700ecd000d891581e77e57c58fed90 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 12 Mar 2025 17:55:25 +0100 Subject: [PATCH 032/227] add back conda env --- subworkflows/local/baysor/main.nf | 1 + 1 file changed, 1 insertion(+) diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index d549d33..c8ccbfa 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -25,6 +25,7 @@ workflow baysor { process patchSegmentation { label "process_long" + conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container ? 'docker://jeffquinnmsk/baysor:latest' : 'docker.io/jeffquinnmsk/baysor:latest'}" From 00035b9e1136fa73711cd4dbf3237aae718e3cb9 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 13 Mar 2025 11:01:35 +0100 Subject: [PATCH 033/227] add proseg --- subworkflows/local/proseg/environment.yml | 8 +++++ subworkflows/local/proseg/main.nf | 38 +++++++++++++++++++++++ toy/proseg.yaml | 30 ++++++++++++++++++ workflows/sopa.nf | 16 +++++++--- 4 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 subworkflows/local/proseg/environment.yml create mode 100644 subworkflows/local/proseg/main.nf create mode 100644 toy/proseg.yaml diff --git a/subworkflows/local/proseg/environment.yml b/subworkflows/local/proseg/environment.yml new file mode 100644 index 0000000..18c06ff --- /dev/null +++ b/subworkflows/local/proseg/environment.yml @@ -0,0 +1,8 @@ +channels: +- conda-forge +- bioconda +dependencies: +- python=3.10 +- pip=24.3.1 +- pip: + - sopa>=2.0.3 diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf new file mode 100644 index 0000000..57ee06b --- /dev/null +++ b/subworkflows/local/proseg/main.nf @@ -0,0 +1,38 @@ +include { mapToCliArgs } from '../../../modules/local/utils' + +workflow proseg { + take: + ch_patches + config + + main: + proseg_args = mapToCliArgs(config.segmentation.proseg, null, ["command_line_suffix"]) + + (ch_segmented, _out) = patchSegmentation(ch_patches, proseg_args) + + emit: + ch_segmented +} + + +process patchSegmentation { + label "process_long" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://tbencomo/proseg:latest' + : 'docker.io/tbencomo/proseg:latest'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/shapes/proseg_boundaries" + + script: + """ + sopa segmentation proseg ${sdata_path} ${cli_arguments} + """ +} diff --git a/toy/proseg.yaml b/toy/proseg.yaml new file mode 100644 index 0000000..c94e99b --- /dev/null +++ b/toy/proseg.yaml @@ -0,0 +1,30 @@ +# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml +read: + technology: toy_dataset + kwargs: + genes: 500 + +patchify: + patch_width_microns: -1 + patch_overlap_microns: 0 + +segmentation: + proseg: + prior_shapes_key: "cells" + +aggregate: + average_intensities: true + min_transcripts: 5 # [optional] cells whose transcript count is below that this threshold are filtered + +annotation: + method: fluorescence + args: + marker_cell_dict: + CK: Tumoral cell + CD3: T cell + CD20: B cell + +explorer: + gene_column: "genes" + ram_threshold_gb: 4 + pixel_size: 0.1 diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 25b4437..bf69a64 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -8,6 +8,7 @@ include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pi include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_sopa_pipeline' include { cellpose } from '../subworkflows/local/cellpose' include { baysor } from '../subworkflows/local/baysor' +include { proseg } from '../subworkflows/local/proseg' include { readConfigFile } from '../modules/local/utils' include { mapToCliArgs } from '../modules/local/utils' /* @@ -29,7 +30,7 @@ workflow SOPA { ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }, mapToCliArgs(config.read)) - // explorer_raw(ch_spatialdata, mapToCliArgs(config.explorer)) + explorer_raw(ch_spatialdata, mapToCliArgs(config.explorer)) if (config.segmentation.tissue) { (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, mapToCliArgs(config.segmentation.tissue)) @@ -46,10 +47,17 @@ workflow SOPA { if (config.segmentation.baysor) { ch_input_baysor = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg - (ch_transcripts_patches, _out) = makeTranscriptPatches(ch_input_baysor, transcriptPatchesArgs(config)) + ch_transcripts_patches = makeTranscriptPatches(ch_input_baysor, transcriptPatchesArgs(config, "baysor")) ch_resolved = baysor(ch_transcripts_patches, config) } + if (config.segmentation.proseg) { + ch_input_proseg = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg + + ch_proseg_patches = makeTranscriptPatches(ch_input_proseg, transcriptPatchesArgs(config, "proseg")) + ch_resolved = proseg(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, config) + } + (ch_aggregated, _out) = aggregate(ch_resolved, mapToCliArgs(config.aggregate)) explorer(ch_aggregated, mapToCliArgs(config.explorer)) @@ -272,8 +280,8 @@ process publish { """ } -def transcriptPatchesArgs(Map config) { - def prior_args = mapToCliArgs(config.segmentation.baysor, null, ["prior_shapes_key", "unassigned_value"]) +def transcriptPatchesArgs(Map config, String method) { + def prior_args = mapToCliArgs(config.segmentation[method], null, ["prior_shapes_key", "unassigned_value"]) return mapToCliArgs(config.patchify, "micron") + " " + prior_args } From ff7f58065b4dc55de7609b3325a9a8e4d5a830a8 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 13 Mar 2025 11:18:05 +0100 Subject: [PATCH 034/227] use sopa>=2.0.3 --- workflows/environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/environment.yml b/workflows/environment.yml index d0aebab..18c06ff 100644 --- a/workflows/environment.yml +++ b/workflows/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.10 - pip=24.3.1 - pip: - - sopa>=2.0.2 + - sopa>=2.0.3 From 8b62d59c0787ff91950fac30e4d19dec087a21cc Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 13 Mar 2025 14:13:46 +0100 Subject: [PATCH 035/227] rename ArgsCLI --- modules/local/utils.nf | 2 +- subworkflows/local/baysor/main.nf | 4 ++-- subworkflows/local/cellpose/main.nf | 4 ++-- subworkflows/local/proseg/main.nf | 4 ++-- workflows/sopa.nf | 18 +++++++++--------- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/local/utils.nf b/modules/local/utils.nf index c2e1483..6ae6b16 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -31,7 +31,7 @@ def stringifyValueForCli(value) { return value.toString() } -def mapToCliArgs(Map params, String contains = null, List keys = null) { +def ArgsCLI(Map params, String contains = null, List keys = null) { return params .findAll { key, _value -> (contains == null || key.contains(contains)) && (keys == null || key in keys) diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index c8ccbfa..51018da 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -1,4 +1,4 @@ -include { mapToCliArgs } from '../../../modules/local/utils' +include { ArgsCLI } from '../../../modules/local/utils' workflow baysor { take: @@ -6,7 +6,7 @@ workflow baysor { config main: - baysor_args = mapToCliArgs(config.segmentation.baysor, null, ["config"]) + baysor_args = ArgsCLI(config.segmentation.baysor, null, ["config"]) ch_patches .map { meta, sdata_path, patches_file_transcripts -> [meta, sdata_path, patches_file_transcripts.splitText()] } diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index 6360f00..f2f5f7f 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -1,4 +1,4 @@ -include { mapToCliArgs } from '../../../modules/local/utils' +include { ArgsCLI } from '../../../modules/local/utils' workflow cellpose { take: @@ -6,7 +6,7 @@ workflow cellpose { config main: - cellpose_args = mapToCliArgs(config.segmentation.cellpose) + cellpose_args = ArgsCLI(config.segmentation.cellpose) ch_patches .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index 57ee06b..58161c3 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -1,4 +1,4 @@ -include { mapToCliArgs } from '../../../modules/local/utils' +include { ArgsCLI } from '../../../modules/local/utils' workflow proseg { take: @@ -6,7 +6,7 @@ workflow proseg { config main: - proseg_args = mapToCliArgs(config.segmentation.proseg, null, ["command_line_suffix"]) + proseg_args = ArgsCLI(config.segmentation.proseg, null, ["command_line_suffix"]) (ch_segmented, _out) = patchSegmentation(ch_patches, proseg_args) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index bf69a64..c7ce605 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -10,7 +10,7 @@ include { cellpose } from '../subworkflows/local/cellpose' include { baysor } from '../subworkflows/local/baysor' include { proseg } from '../subworkflows/local/proseg' include { readConfigFile } from '../modules/local/utils' -include { mapToCliArgs } from '../modules/local/utils' +include { ArgsCLI } from '../modules/local/utils' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -28,19 +28,19 @@ workflow SOPA { def config = readConfigFile(configfile) - ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }, mapToCliArgs(config.read)) + ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }, ArgsCLI(config.read)) - explorer_raw(ch_spatialdata, mapToCliArgs(config.explorer)) + explorer_raw(ch_spatialdata, ArgsCLI(config.explorer)) if (config.segmentation.tissue) { - (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, mapToCliArgs(config.segmentation.tissue)) + (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, ArgsCLI(config.segmentation.tissue)) } else { ch_tissue_seg = ch_spatialdata } if (config.segmentation.cellpose) { - (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, mapToCliArgs(config.patchify, "pixel")) + (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) ch_resolved = cellpose(ch_image_patches, config) } @@ -58,9 +58,9 @@ workflow SOPA { ch_resolved = proseg(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, config) } - (ch_aggregated, _out) = aggregate(ch_resolved, mapToCliArgs(config.aggregate)) + (ch_aggregated, _out) = aggregate(ch_resolved, ArgsCLI(config.aggregate)) - explorer(ch_aggregated, mapToCliArgs(config.explorer)) + explorer(ch_aggregated, ArgsCLI(config.explorer)) report(ch_aggregated) publish(ch_aggregated.map { it[1] }) @@ -281,7 +281,7 @@ process publish { } def transcriptPatchesArgs(Map config, String method) { - def prior_args = mapToCliArgs(config.segmentation[method], null, ["prior_shapes_key", "unassigned_value"]) + def prior_args = ArgsCLI(config.segmentation[method], null, ["prior_shapes_key", "unassigned_value"]) - return mapToCliArgs(config.patchify, "micron") + " " + prior_args + return ArgsCLI(config.patchify, "micron") + " " + prior_args } From 1aa98e3a4afd7d3cd5cc7fc1ec113a95485c18b4 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 14 Mar 2025 16:36:32 +0100 Subject: [PATCH 036/227] add stardist --- subworkflows/local/stardist/environment.yml | 8 +++ subworkflows/local/stardist/main.nf | 64 +++++++++++++++++++++ workflows/sopa.nf | 6 ++ 3 files changed, 78 insertions(+) create mode 100644 subworkflows/local/stardist/environment.yml create mode 100644 subworkflows/local/stardist/main.nf diff --git a/subworkflows/local/stardist/environment.yml b/subworkflows/local/stardist/environment.yml new file mode 100644 index 0000000..eb5da04 --- /dev/null +++ b/subworkflows/local/stardist/environment.yml @@ -0,0 +1,8 @@ +channels: +- conda-forge +- bioconda +dependencies: +- python=3.10 +- pip=24.3.1 +- pip: + - sopa[stardist]>=2.0.2 diff --git a/subworkflows/local/stardist/main.nf b/subworkflows/local/stardist/main.nf new file mode 100644 index 0000000..b22b026 --- /dev/null +++ b/subworkflows/local/stardist/main.nf @@ -0,0 +1,64 @@ +include { ArgsCLI } from '../../../modules/local/utils' + +workflow stardist { + take: + ch_patches + config + + main: + stardist_args = ArgsCLI(config.segmentation.stardist) + + ch_patches + .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } + .flatMap { meta, sdata_path, n_patches -> (0.. [meta, sdata_path, stardist_args, index, n_patches] } } + .set { ch_stardist } + + ch_segmented = patchSegmentation(ch_stardist).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } + + (ch_resolved, _out) = resolve(ch_segmented) + + emit: + ch_resolved +} + + +process patchSegmentation { + label "process_single" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/stardist_boundaries/${index}.parquet"), val(n_patches) + + script: + """ + sopa segmentation stardist ${sdata_path} --patch-index ${index} ${cli_arguments} + """ +} + +process resolve { + label "process_low" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://jeffquinnmsk/sopa:latest' + : 'docker.io/jeffquinnmsk/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path) + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/shapes/stardist_boundaries" + + script: + """ + sopa resolve stardist ${sdata_path} + """ +} diff --git a/workflows/sopa.nf b/workflows/sopa.nf index c7ce605..6d956cb 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -7,6 +7,7 @@ include { paramsSummaryMap } from 'plugin/nf-schema' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_sopa_pipeline' include { cellpose } from '../subworkflows/local/cellpose' +include { stardist } from '../subworkflows/local/stardist' include { baysor } from '../subworkflows/local/baysor' include { proseg } from '../subworkflows/local/proseg' include { readConfigFile } from '../modules/local/utils' @@ -44,6 +45,11 @@ workflow SOPA { ch_resolved = cellpose(ch_image_patches, config) } + if (config.segmentation.stardist) { + (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) + ch_resolved = stardist(ch_image_patches, config) + } + if (config.segmentation.baysor) { ch_input_baysor = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg From ae388817384cc7bb48dfc449453161c1f96496ca Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 19 Mar 2025 14:35:01 +0100 Subject: [PATCH 037/227] minor slurm config update --- conf/slurm.config | 53 ++++++++++++++++++----------------------------- 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/conf/slurm.config b/conf/slurm.config index 36be4e7..4ff0f4c 100644 --- a/conf/slurm.config +++ b/conf/slurm.config @@ -1,68 +1,55 @@ process { executor = 'slurm' - // queue = '' // Your default queue or partition containerOptions = '--user $(id -u):$(id -g)' - errorStrategy = 'terminate' - maxRetries = 5 + errorStrategy = 'retry' + maxRetries = 2 // Lightweight tasks: Fits into the standard partition withLabel: process_single { queue = 'standard' - resourceLimits = [ - cpus: 4, - memory: 30.GB, - time: 2.d, - ] + cpus = 4 + memory = 30.GB + time = 2.d } // Low resource tasks: Use nf-standard-mem withLabel: process_low { queue = 'nf-standard-mem' - resourceLimits = [ - cpus: 8, - memory: 60.GB, - time: 2.d, - ] + cpus = 8 + memory = 60.GB + time = 2.d } // Medium resource tasks: Use nf-standard-mem or nf-high-mem withLabel: process_medium { queue = 'nf-high-mem' - resourceLimits = [ - cpus: 16, - memory: 120.GB, - time: 2.d, - ] + cpus = 16 + memory = 120.GB + time = 2.d } // High resource tasks: Use nf-high-mem withLabel: process_high { queue = 'nf-high-mem' - resourceLimits = [ - cpus: 16, - memory: 120.GB, - time: 2.d, - ] + cpus = 16 + memory = 120.GB + time = 2.d } // Long-running tasks: Use high partition for extended time withLabel: process_long { queue = 'high' - resourceLimits = [ - cpus: 32, - memory: 250.GB, - time: 2.d, - ] + cpus = 32 + memory = 250.GB + time = 2.d } // Memory-intensive tasks: Use high partition for maximum memory withLabel: process_high_memory { queue = 'high' - resourceLimits = [ - cpus: 32, - memory: 250.GB, - time: 2.d, - ] + cpus = 32 + memory = 250.GB + time = 2.d } } From 2b97d795d8c0d9082bd32f498f717190d325b496 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 19 Mar 2025 14:37:59 +0100 Subject: [PATCH 038/227] update only time --- conf/slurm.config | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/conf/slurm.config b/conf/slurm.config index 4ff0f4c..14318c8 100644 --- a/conf/slurm.config +++ b/conf/slurm.config @@ -7,49 +7,61 @@ process { // Lightweight tasks: Fits into the standard partition withLabel: process_single { queue = 'standard' - cpus = 4 - memory = 30.GB time = 2.d + resourceLimits = [ + cpus: 4, + memory: 30.GB, + ] } // Low resource tasks: Use nf-standard-mem withLabel: process_low { queue = 'nf-standard-mem' - cpus = 8 - memory = 60.GB time = 2.d + resourceLimits = [ + cpus: 8, + memory: 60.GB, + ] } // Medium resource tasks: Use nf-standard-mem or nf-high-mem withLabel: process_medium { queue = 'nf-high-mem' - cpus = 16 - memory = 120.GB time = 2.d + resourceLimits = [ + cpus: 16, + memory: 120.GB, + ] } // High resource tasks: Use nf-high-mem withLabel: process_high { queue = 'nf-high-mem' - cpus = 16 - memory = 120.GB time = 2.d + resourceLimits = [ + cpus: 16, + memory: 120.GB, + ] } // Long-running tasks: Use high partition for extended time withLabel: process_long { queue = 'high' - cpus = 32 - memory = 250.GB time = 2.d + resourceLimits = [ + cpus: 32, + memory: 250.GB, + ] } // Memory-intensive tasks: Use high partition for maximum memory withLabel: process_high_memory { queue = 'high' - cpus = 32 - memory = 250.GB time = 2.d + resourceLimits = [ + cpus: 32, + memory: 250.GB, + ] } } From 563ffa3335d300cc8af4f421602209001cde462c Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 24 Mar 2025 09:10:36 +0100 Subject: [PATCH 039/227] higher walltime --- conf/slurm.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/slurm.config b/conf/slurm.config index 14318c8..8ece940 100644 --- a/conf/slurm.config +++ b/conf/slurm.config @@ -47,7 +47,7 @@ process { // Long-running tasks: Use high partition for extended time withLabel: process_long { queue = 'high' - time = 2.d + time = 4.d resourceLimits = [ cpus: 32, memory: 250.GB, @@ -57,7 +57,7 @@ process { // Memory-intensive tasks: Use high partition for maximum memory withLabel: process_high_memory { queue = 'high' - time = 2.d + time = 4.d resourceLimits = [ cpus: 32, memory: 250.GB, From 69e41def17a58fab9e6a2d6a442012c0070eb03f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 26 Mar 2025 11:13:46 +0100 Subject: [PATCH 040/227] use official sopa docker images --- subworkflows/local/baysor/main.nf | 4 ++-- subworkflows/local/cellpose/main.nf | 8 ++++---- subworkflows/local/proseg/main.nf | 4 ++-- subworkflows/local/stardist/main.nf | 8 ++++---- workflows/sopa.nf | 32 ++++++++++++++--------------- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index 51018da..f7575f3 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -51,8 +51,8 @@ process resolve { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index f2f5f7f..21f0f48 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -27,8 +27,8 @@ process patchSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -47,8 +47,8 @@ process resolve { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index 58161c3..8fc0e6f 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -20,8 +20,8 @@ process patchSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://tbencomo/proseg:latest' - : 'docker.io/tbencomo/proseg:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3-proseg' + : 'docker.io/quentinblampey/sopa:2.0.3-proseg'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/stardist/main.nf b/subworkflows/local/stardist/main.nf index b22b026..6912f41 100644 --- a/subworkflows/local/stardist/main.nf +++ b/subworkflows/local/stardist/main.nf @@ -27,8 +27,8 @@ process patchSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -47,8 +47,8 @@ process resolve { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" input: tuple val(meta), path(sdata_path) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 6d956cb..4f33107 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -91,8 +91,8 @@ process toSpatialData { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" input: tuple val(meta), val(sdata_dir) @@ -112,8 +112,8 @@ process tissueSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" input: tuple val(meta), path(sdata_path) @@ -134,8 +134,8 @@ process makeImagePatches { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" input: tuple val(meta), path(sdata_path) @@ -156,8 +156,8 @@ process makeTranscriptPatches { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" input: tuple val(meta), path(sdata_path) @@ -177,8 +177,8 @@ process aggregate { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" input: tuple val(meta), path(sdata_path) @@ -199,8 +199,8 @@ process explorer_raw { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -223,8 +223,8 @@ process explorer { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -250,8 +250,8 @@ process report { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/sopa:latest' - : 'docker.io/jeffquinnmsk/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3' + : 'docker.io/quentinblampey/sopa:2.0.3'}" publishDir "${params.outdir}", mode: params.publish_dir_mode From 99326a27307e37e35b1cf26f002bb83909913afa Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 26 Mar 2025 14:30:30 +0100 Subject: [PATCH 041/227] try wrong name for debugging --- subworkflows/local/proseg/main.nf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index 8fc0e6f..3e0e084 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -20,8 +20,8 @@ process patchSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3-proseg' - : 'docker.io/quentinblampey/sopa:2.0.3-proseg'}" + ? 'docker://quentinblampey/sopa:2.0.3-prosegx' + : 'docker.io/quentinblampey/sopa:2.0.3-prosegx'}" input: tuple val(meta), path(sdata_path) From d773e410bf1e867cd77634d6efb1d562276171d4 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 26 Mar 2025 14:31:12 +0100 Subject: [PATCH 042/227] reuse the right name --- subworkflows/local/proseg/main.nf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index 3e0e084..8fc0e6f 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -20,8 +20,8 @@ process patchSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3-prosegx' - : 'docker.io/quentinblampey/sopa:2.0.3-prosegx'}" + ? 'docker://quentinblampey/sopa:2.0.3-proseg' + : 'docker.io/quentinblampey/sopa:2.0.3-proseg'}" input: tuple val(meta), path(sdata_path) From b10738c9dc93562650408b48c072137c1410b6ba Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 26 Mar 2025 14:58:01 +0100 Subject: [PATCH 043/227] use label process_medium --- subworkflows/local/proseg/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index 8fc0e6f..97b11dc 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -16,7 +16,7 @@ workflow proseg { process patchSegmentation { - label "process_long" + label "process_medium" conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container From d2a28459c702e730a72b57c474daa2ada6e23c7d Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 26 Mar 2025 15:21:05 +0100 Subject: [PATCH 044/227] use process_high --- subworkflows/local/proseg/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index 97b11dc..37ba74a 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -16,7 +16,7 @@ workflow proseg { process patchSegmentation { - label "process_medium" + label "process_high" conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container From def5580a25c3a1f5f508c4e33d14de3ad4c94144 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 26 Mar 2025 15:55:03 +0100 Subject: [PATCH 045/227] use all the new docker images --- subworkflows/local/baysor/main.nf | 8 ++++---- subworkflows/local/cellpose/main.nf | 4 ++-- subworkflows/local/stardist/main.nf | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index f7575f3..3147eb5 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -27,8 +27,8 @@ process patchSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://jeffquinnmsk/baysor:latest' - : 'docker.io/jeffquinnmsk/baysor:latest'}" + ? 'docker://quentinblampey/sopa:2.0.3-baysor' + : 'docker.io/quentinblampey/sopa:2.0.3-baysor'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -51,8 +51,8 @@ process resolve { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.3-baysor' + : 'docker.io/quentinblampey/sopa:2.0.3-baysor'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index 21f0f48..53a58d2 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -27,8 +27,8 @@ process patchSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.3-cellpose' + : 'docker.io/quentinblampey/sopa:2.0.3-cellpose'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/subworkflows/local/stardist/main.nf b/subworkflows/local/stardist/main.nf index 6912f41..eb0b25a 100644 --- a/subworkflows/local/stardist/main.nf +++ b/subworkflows/local/stardist/main.nf @@ -27,8 +27,8 @@ process patchSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.3-stardist' + : 'docker.io/quentinblampey/sopa:2.0.3-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) From a53a317aece3be15f6cbaa934db53b8ad4276cef Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 26 Mar 2025 17:34:57 +0100 Subject: [PATCH 046/227] rename processes + update config for proseg --- conf/base.config | 5 +++++ conf/modules.config | 14 -------------- nextflow.config | 3 --- subworkflows/local/baysor/main.nf | 8 ++++---- subworkflows/local/cellpose/main.nf | 8 ++++---- subworkflows/local/proseg/main.nf | 4 ++-- subworkflows/local/stardist/main.nf | 8 ++++---- 7 files changed, 19 insertions(+), 31 deletions(-) delete mode 100644 conf/modules.config diff --git a/conf/base.config b/conf/base.config index 1dae7d1..6e7a477 100644 --- a/conf/base.config +++ b/conf/base.config @@ -52,6 +52,11 @@ process { withLabel:process_high_memory { memory = { 200.GB * task.attempt } } + withName:patchSegmentationProseg { + cpus = { 8 * task.attempt } + memory = { 200.GB * task.attempt } + time = { 4.d * task.attempt } + } withLabel:error_ignore { errorStrategy = 'ignore' } diff --git a/conf/modules.config b/conf/modules.config deleted file mode 100644 index 8b7dd54..0000000 --- a/conf/modules.config +++ /dev/null @@ -1,14 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Config file for defining DSL2 per module options and publishing paths -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Available keys to override module options: - ext.args = Additional arguments appended to command in module. - ext.args2 = Second set of arguments appended to command in module (multi-tool modules). - ext.args3 = Third set of arguments appended to command in module (multi-tool modules). - ext.prefix = File name prefix for output files. ----------------------------------------------------------------------------------------- -*/ - -process { -} diff --git a/nextflow.config b/nextflow.config index 0e79ead..2c49d97 100644 --- a/nextflow.config +++ b/nextflow.config @@ -270,6 +270,3 @@ validation { afterText = validation.help.afterText } } - -// Load modules.config for DSL2 module specific options -includeConfig 'conf/modules.config' diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index 3147eb5..cb71566 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -13,16 +13,16 @@ workflow baysor { .flatMap { meta, sdata_path, patches_indices -> patches_indices.collect { index -> [meta, sdata_path, baysor_args, index.trim().toInteger(), patches_indices.size] } } .set { ch_baysor } - ch_segmented = patchSegmentation(ch_baysor).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } + ch_segmented = patchSegmentationBaysor(ch_baysor).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - (ch_resolved, _out) = resolve(ch_segmented, resolveArgs(config)) + (ch_resolved, _out) = resolveBaysor(ch_segmented, resolveArgs(config)) emit: ch_resolved } -process patchSegmentation { +process patchSegmentationBaysor { label "process_long" conda "${moduleDir}/environment.yml" @@ -46,7 +46,7 @@ process patchSegmentation { """ } -process resolve { +process resolveBaysor { label "process_low" conda "${moduleDir}/environment.yml" diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index 53a58d2..b553972 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -13,16 +13,16 @@ workflow cellpose { .flatMap { meta, sdata_path, n_patches -> (0.. [meta, sdata_path, cellpose_args, index, n_patches] } } .set { ch_cellpose } - ch_segmented = patchSegmentation(ch_cellpose).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } + ch_segmented = patchSegmentationCellpose(ch_cellpose).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - (ch_resolved, _out) = resolve(ch_segmented) + (ch_resolved, _out) = resolveCellpose(ch_segmented) emit: ch_resolved } -process patchSegmentation { +process patchSegmentationCellpose { label "process_single" conda "${moduleDir}/environment.yml" @@ -42,7 +42,7 @@ process patchSegmentation { """ } -process resolve { +process resolveCellpose { label "process_low" conda "${moduleDir}/environment.yml" diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index 37ba74a..c1c4d62 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -8,14 +8,14 @@ workflow proseg { main: proseg_args = ArgsCLI(config.segmentation.proseg, null, ["command_line_suffix"]) - (ch_segmented, _out) = patchSegmentation(ch_patches, proseg_args) + (ch_segmented, _out) = patchSegmentationProseg(ch_patches, proseg_args) emit: ch_segmented } -process patchSegmentation { +process patchSegmentationProseg { label "process_high" conda "${moduleDir}/environment.yml" diff --git a/subworkflows/local/stardist/main.nf b/subworkflows/local/stardist/main.nf index eb0b25a..be0e608 100644 --- a/subworkflows/local/stardist/main.nf +++ b/subworkflows/local/stardist/main.nf @@ -13,16 +13,16 @@ workflow stardist { .flatMap { meta, sdata_path, n_patches -> (0.. [meta, sdata_path, stardist_args, index, n_patches] } } .set { ch_stardist } - ch_segmented = patchSegmentation(ch_stardist).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } + ch_segmented = patchSegmentationStardist(ch_stardist).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - (ch_resolved, _out) = resolve(ch_segmented) + (ch_resolved, _out) = resolveStardist(ch_segmented) emit: ch_resolved } -process patchSegmentation { +process patchSegmentationStardist { label "process_single" conda "${moduleDir}/environment.yml" @@ -42,7 +42,7 @@ process patchSegmentation { """ } -process resolve { +process resolveStardist { label "process_low" conda "${moduleDir}/environment.yml" From 5e5a2792c3322fd9d56896dcc84f26154fa5f8e8 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 26 Mar 2025 17:52:17 +0100 Subject: [PATCH 047/227] can output any raw file for the explorer --- workflows/sopa.nf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 4f33107..fe086b8 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -209,8 +209,8 @@ process explorer_raw { val cli_arguments output: - path "${meta.explorer_dir}/morphology.ome.tif" - path "${meta.explorer_dir}/transcripts.zarr.zip" + path "${meta.explorer_dir}/morphology*" + path "${meta.explorer_dir}/transcripts*" script: """ From 188d939361731dba5579d74eaf81f72dee58157f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 26 Mar 2025 17:53:51 +0100 Subject: [PATCH 048/227] add spaceranger/count --- modules.json | 8 +- modules/nf-core/spaceranger/count/main.nf | 71 ++++++++++++++++ modules/nf-core/spaceranger/count/meta.yml | 99 ++++++++++++++++++++++ 3 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 modules/nf-core/spaceranger/count/main.nf create mode 100644 modules/nf-core/spaceranger/count/meta.yml diff --git a/modules.json b/modules.json index 052719c..803171c 100644 --- a/modules.json +++ b/modules.json @@ -4,7 +4,13 @@ "repos": { "https://github.com/nf-core/modules.git": { "modules": { - "nf-core": {} + "nf-core": { + "spaceranger/count": { + "branch": "master", + "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", + "installed_by": ["modules"] + } + } }, "subworkflows": { "nf-core": { diff --git a/modules/nf-core/spaceranger/count/main.nf b/modules/nf-core/spaceranger/count/main.nf new file mode 100644 index 0000000..f33d82f --- /dev/null +++ b/modules/nf-core/spaceranger/count/main.nf @@ -0,0 +1,71 @@ +process SPACERANGER_COUNT { + tag "$meta.id" + label 'process_high' + + container "nf-core/modules/spaceranger:d71611e316a8614b" + + input: + tuple val(meta), path(reads), path(image), path(cytaimage), path(darkimage), path(colorizedimage), path(alignment), path(slidefile) + path(reference) + path(probeset) + + output: + tuple val(meta), path("outs/**"), emit: outs + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + // Exit if running this module with -profile conda / -profile mamba + if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { + error "SPACERANGER_COUNT module does not support Conda. Please use Docker / Singularity / Podman instead." + } + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + // Add flags for optional inputs on demand. + def probeset = probeset ? "--probe-set=\"${probeset}\"" : "" + def alignment = alignment ? "--loupe-alignment=\"${alignment}\"" : "" + def slidefile = slidefile ? "--slidefile=\"${slidefile}\"" : "" + def image = image ? "--image=\"${image}\"" : "" + def cytaimage = cytaimage ? "--cytaimage=\"${cytaimage}\"" : "" + def darkimage = darkimage ? "--darkimage=\"${darkimage}\"" : "" + def colorizedimage = colorizedimage ? "--colorizedimage=\"${colorizedimage}\"" : "" + """ + spaceranger count \\ + --id="${prefix}" \\ + --sample="${meta.id}" \\ + --fastqs=. \\ + --slide="${meta.slide}" \\ + --area="${meta.area}" \\ + --transcriptome="${reference}" \\ + --localcores=${task.cpus} \\ + --localmem=${task.memory.toGiga()} \\ + $image $cytaimage $darkimage $colorizedimage \\ + $probeset \\ + $alignment \\ + $slidefile \\ + $args + mv ${prefix}/outs outs + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + spaceranger: \$(spaceranger -V | sed -e "s/spaceranger spaceranger-//g") + END_VERSIONS + """ + + stub: + // Exit if running this module with -profile conda / -profile mamba + if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { + error "SPACERANGER_COUNT module does not support Conda. Please use Docker / Singularity / Podman instead." + } + """ + mkdir -p outs/ + touch outs/fake_file.txt + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + spaceranger: \$(spaceranger -V | sed -e "s/spaceranger spaceranger-//g") + END_VERSIONS + """ +} diff --git a/modules/nf-core/spaceranger/count/meta.yml b/modules/nf-core/spaceranger/count/meta.yml new file mode 100644 index 0000000..e1ffcef --- /dev/null +++ b/modules/nf-core/spaceranger/count/meta.yml @@ -0,0 +1,99 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/yaml-schema.json +name: "spaceranger_count" +description: Module to use the 10x Space Ranger pipeline to process 10x spatial transcriptomics + data +keywords: + - align + - count + - spatial + - spaceranger + - imaging +tools: + - "spaceranger": + description: | + Visium Spatial Gene Expression is a next-generation molecular profiling solution for classifying tissue + based on total mRNA. Space Ranger is a set of analysis pipelines that process Visium Spatial Gene Expression + data with brightfield and fluorescence microscope images. Space Ranger allows users to map the whole + transcriptome in formalin fixed paraffin embedded (FFPE) and fresh frozen tissues to discover novel + insights into normal development, disease pathology, and clinical translational research. Space Ranger provides + pipelines for end to end analysis of Visium Spatial Gene Expression experiments. + homepage: "https://support.10xgenomics.com/spatial-gene-expression/software/pipelines/latest/what-is-space-ranger" + documentation: "https://support.10xgenomics.com/spatial-gene-expression/software/pipelines/latest/what-is-space-ranger" + tool_dev_url: "https://support.10xgenomics.com/spatial-gene-expression/software/pipelines/latest/what-is-space-ranger" + licence: + - "10x Genomics EULA" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', slide:'10L13-020', area: 'B1'] + + `id`, `slide` and `area` are mandatory information! + - reads: + type: file + description: | + List of input FastQ files of size 1 and 2 for single-end and paired-end data, + respectively. + pattern: "${Sample_Name}_S1_L00${Lane_Number}_${I1,I2,R1,R2}_001.fastq.gz" + - image: + type: file + description: Brightfield tissue H&E image in JPEG or TIFF format. + pattern: "*.{tif,tiff,jpg,jpeg}" + - cytaimage: + type: file + description: | + CytAssist instrument captured eosin stained Brightfield tissue image with fiducial + frame in TIFF format. The size of this image is set at 3k in both dimensions and this image should + not be modified any way before passing it as input to either Space Ranger or Loupe Browser. + pattern: "*.{tif,tiff}" + - darkimage: + type: file + description: | + Optional for dark background fluorescence microscope image input. Multi-channel, dark-background fluorescence + image as either a single, multi-layer TIFF file or as multiple TIFF or JPEG files. + pattern: "*.{tif,tiff,jpg,jpeg}" + - colorizedimage: + type: file + description: | + Required for color composite fluorescence microscope image input. + A color composite of one or more fluorescence image channels saved as a single-page, + single-file color TIFF or JPEG. + pattern: "*.{tif,tiff,jpg,jpeg}" + - alignment: + type: file + description: OPTIONAL - Path to manual image alignment. + pattern: "*.json" + - slidefile: + type: file + description: OPTIONAL - Path to slide specifications. + pattern: "*.json" + - - reference: + type: directory + description: Folder containing all the reference indices needed by Space Ranger + - - probeset: + type: file + description: OPTIONAL - Probe set specification. + pattern: "*.csv" +output: + - outs: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - outs/**: + type: file + description: Files containing the outputs of Space Ranger, see official 10X + Genomics documentation for a complete list + pattern: "outs/*" + - versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "@grst" +maintainers: + - "@grst" From f35ca3847d4922b3c2971c90f2d042376dff8f56 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Mar 2025 14:43:02 +0100 Subject: [PATCH 049/227] add support for visium hd WIP --- assets/schema_input.json | 69 +++++++++++++-- conf/modules.config | 22 +++++ conf/test_vhd.config | 32 +++++++ modules.json | 5 ++ modules/nf-core/untar/environment.yml | 12 +++ modules/nf-core/untar/main.nf | 84 +++++++++++++++++++ modules/nf-core/untar/meta.yml | 52 ++++++++++++ nextflow.config | 1 + nextflow_schema.json | 26 ++++++ subworkflows/local/input_check.nf | 79 +++++++++++++++++ subworkflows/local/spaceranger.nf | 59 +++++++++++++ .../local/utils_nfcore_sopa_pipeline/main.nf | 25 +++++- toy/samplesheet.csv | 3 +- toy/samplesheet_vhd.csv | 2 + toy/vhd_stardist.yaml | 18 ++++ workflows/sopa.nf | 18 +++- 16 files changed, 493 insertions(+), 14 deletions(-) create mode 100644 conf/modules.config create mode 100644 conf/test_vhd.config create mode 100644 modules/nf-core/untar/environment.yml create mode 100644 modules/nf-core/untar/main.nf create mode 100644 modules/nf-core/untar/meta.yml create mode 100644 subworkflows/local/input_check.nf create mode 100644 subworkflows/local/spaceranger.nf create mode 100644 toy/samplesheet_vhd.csv create mode 100644 toy/vhd_stardist.yaml diff --git a/assets/schema_input.json b/assets/schema_input.json index e42e5fc..f3e7f5a 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -8,23 +8,76 @@ "type": "object", "properties": { "sample": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Sample name cannot contain spaces", + "meta": [ + "id" + ] + }, + "data_path": { + "type": "string", + "pattern": "^\\S+$", + "format": "path", + "exists": true, + "errorMessage": "Data path must exist" + }, + "fastq_dir": { "type": "string", "pattern": "^\\S+$", "format": "path", "exists": true, - "errorMessage": "Sample data path must exist", + "errorMessage": "Path to the fastq directory must exist", "meta": [ - "id" + "fastq_dir" + ] + }, + "cytaimage": { + "type": "string", + "pattern": "^\\S+$", + "format": "path", + "exists": true, + "errorMessage": "Path to the cytaimage file must exist", + "meta": [ + "cytaimage" + ] + }, + "slide": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Slide name cannot contain spaces", + "meta": [ + "slide" + ] + }, + "area": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Area name cannot contain spaces", + "meta": [ + "area" + ] + }, + "manual_alignment": { + "type": "string", + "pattern": "^\\S+$", + "format": "path", + "exists": true, + "errorMessage": "Path to the manual_alignment file must exist", + "meta": [ + "manual_alignment" ] }, - "dataset_id": { + "slidefile": { "type": "string", "pattern": "^\\S+$", - "errorMessage": "Dataset IDs cannot contain spaces" + "format": "path", + "exists": true, + "errorMessage": "Path to the slidefile must exist", + "meta": [ + "slidefile" + ] } - }, - "required": [ - "sample" - ] + } } } \ No newline at end of file diff --git a/conf/modules.config b/conf/modules.config new file mode 100644 index 0000000..8f67c34 --- /dev/null +++ b/conf/modules.config @@ -0,0 +1,22 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Config file for defining DSL2 per module options and publishing paths +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Available keys to override module options: + ext.args = Additional arguments appended to command in module. + ext.args2 = Second set of arguments appended to command in module (multi-tool modules). + ext.args3 = Third set of arguments appended to command in module (multi-tool modules). + ext.prefix = File name prefix for output files. +---------------------------------------------------------------------------------------- +*/ + +process { + withName: SPACERANGER_COUNT { + ext.args = '--create-bam="false"' + publishDir = [ + path: { "${params.outdir}/${meta.id}_spaceranger" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, + ] + } +} diff --git a/conf/test_vhd.config b/conf/test_vhd.config new file mode 100644 index 0000000..70fa04b --- /dev/null +++ b/conf/test_vhd.config @@ -0,0 +1,32 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/sopa -profile test, --outdir + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h', + ] +} + +params { + config_profile_name = 'Test profile for Visium HD data' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // 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 + input = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/samplesheet_spaceranger.csv" + spaceranger_probeset = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/outs/probe_set.csv" + spaceranger_reference = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/homo_sapiens_chr22_reference.tar.gz" + configfile = "${baseDir}/toy/vhd_stardist.yaml" +} diff --git a/modules.json b/modules.json index 803171c..4a44f9d 100644 --- a/modules.json +++ b/modules.json @@ -9,6 +9,11 @@ "branch": "master", "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", "installed_by": ["modules"] + }, + "untar": { + "branch": "master", + "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", + "installed_by": ["modules"] } } }, diff --git a/modules/nf-core/untar/environment.yml b/modules/nf-core/untar/environment.yml new file mode 100644 index 0000000..9b926b1 --- /dev/null +++ b/modules/nf-core/untar/environment.yml @@ -0,0 +1,12 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - conda-forge::coreutils=9.5 + - conda-forge::grep=3.11 + - conda-forge::gzip=1.13 + - conda-forge::lbzip2=2.5 + - conda-forge::sed=4.8 + - conda-forge::tar=1.34 diff --git a/modules/nf-core/untar/main.nf b/modules/nf-core/untar/main.nf new file mode 100644 index 0000000..e712ebe --- /dev/null +++ b/modules/nf-core/untar/main.nf @@ -0,0 +1,84 @@ +process UNTAR { + tag "${archive}" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/52/52ccce28d2ab928ab862e25aae26314d69c8e38bd41ca9431c67ef05221348aa/data' + : 'community.wave.seqera.io/library/coreutils_grep_gzip_lbzip2_pruned:838ba80435a629f8'}" + + input: + tuple val(meta), path(archive) + + output: + tuple val(meta), path("${prefix}"), emit: untar + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + prefix = task.ext.prefix ?: (meta.id ? "${meta.id}" : archive.baseName.toString().replaceFirst(/\.tar$/, "")) + + """ + mkdir ${prefix} + + ## Ensures --strip-components only applied when top level of tar contents is a directory + ## If just files or multiple directories, place all in prefix + if [[ \$(tar -taf ${archive} | grep -o -P "^.*?\\/" | uniq | wc -l) -eq 1 ]]; then + tar \\ + -C ${prefix} --strip-components 1 \\ + -xavf \\ + ${args} \\ + ${archive} \\ + ${args2} + else + tar \\ + -C ${prefix} \\ + -xavf \\ + ${args} \\ + ${archive} \\ + ${args2} + fi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + untar: \$(echo \$(tar --version 2>&1) | sed 's/^.*(GNU tar) //; s/ Copyright.*\$//') + END_VERSIONS + """ + + stub: + prefix = task.ext.prefix ?: (meta.id ? "${meta.id}" : archive.toString().replaceFirst(/\.[^\.]+(.gz)?$/, "")) + """ + mkdir ${prefix} + ## Dry-run untaring the archive to get the files and place all in prefix + if [[ \$(tar -taf ${archive} | grep -o -P "^.*?\\/" | uniq | wc -l) -eq 1 ]]; then + for i in `tar -tf ${archive}`; + do + if [[ \$(echo "\${i}" | grep -E "/\$") == "" ]]; + then + touch \${i} + else + mkdir -p \${i} + fi + done + else + for i in `tar -tf ${archive}`; + do + if [[ \$(echo "\${i}" | grep -E "/\$") == "" ]]; + then + touch ${prefix}/\${i} + else + mkdir -p ${prefix}/\${i} + fi + done + fi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + untar: \$(echo \$(tar --version 2>&1) | sed 's/^.*(GNU tar) //; s/ Copyright.*\$//') + END_VERSIONS + """ +} diff --git a/modules/nf-core/untar/meta.yml b/modules/nf-core/untar/meta.yml new file mode 100644 index 0000000..3a37bb3 --- /dev/null +++ b/modules/nf-core/untar/meta.yml @@ -0,0 +1,52 @@ +name: untar +description: Extract files. +keywords: + - untar + - uncompress + - extract +tools: + - untar: + description: | + Extract tar.gz files. + documentation: https://www.gnu.org/software/tar/manual/ + licence: ["GPL-3.0-or-later"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - archive: + type: file + description: File to be untar + pattern: "*.{tar}.{gz}" +output: + - untar: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + pattern: "*/" + - ${prefix}: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + pattern: "*/" + - versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "@joseespinosa" + - "@drpatelh" + - "@matthdsm" + - "@jfy133" +maintainers: + - "@joseespinosa" + - "@drpatelh" + - "@matthdsm" + - "@jfy133" diff --git a/nextflow.config b/nextflow.config index 2c49d97..7043ec8 100644 --- a/nextflow.config +++ b/nextflow.config @@ -148,6 +148,7 @@ profiles { ] } } + test_vhd { includeConfig 'conf/test_vhd.config' } test { includeConfig 'conf/test.config' } slurm { includeConfig 'conf/slurm.config' } test_full { includeConfig 'conf/test_full.config' } diff --git a/nextflow_schema.json b/nextflow_schema.json index 534c77a..2408c28 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -51,6 +51,32 @@ } } }, + "spaceranger_options": { + "title": "Space Ranger options", + "type": "object", + "fa_icon": "fas fa-rocket", + "description": "Options related to Space Ranger execution and raw spatial data processing", + "properties": { + "spaceranger_probeset": { + "type": "string", + "format": "file-path", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Location of Space Ranger probeset file.", + "fa_icon": "fas fa-file-csv", + "exists": true + }, + "spaceranger_reference": { + "type": "string", + "format": "path", + "description": "Location of Space Ranger reference directory. May be packed as `tar.gz` file.", + "help_text": "Please see the [10x website](https://support.10xgenomics.com/spatial-gene-expression/software/downloads/latest) to download either of the supported human or mouse references. If not specified the GRCh38 human reference is automatically downladed and used.", + "fa_icon": "fas fa-folder-open", + "default": "https://cf.10xgenomics.com/supp/spatial-exp/refdata-gex-GRCh38-2020-A.tar.gz", + "exists": true + } + } + }, "institutional_config_options": { "title": "Institutional config options", "type": "object", diff --git a/subworkflows/local/input_check.nf b/subworkflows/local/input_check.nf new file mode 100644 index 0000000..aaba9ea --- /dev/null +++ b/subworkflows/local/input_check.nf @@ -0,0 +1,79 @@ +// +// Check input samplesheet and get read channels +// + +include { UNTAR as UNTAR_SPACERANGER_INPUT } from "../../modules/nf-core/untar" + +workflow INPUT_CHECK { + + take: + ch_samplesheet + + main: + + ch_versions = Channel.empty() + + // Space Ranger analysis: -------------------------------------------------- + + // Split channel into tarballed and directory inputs + ch_spaceranger = ch_samplesheet + .map { it -> [it, it.fastq_dir]} + .branch { + tar: it[1].contains(".tar.gz") + dir: !it[1].contains(".tar.gz") + } + + // Extract tarballed inputs + UNTAR_SPACERANGER_INPUT ( ch_spaceranger.tar ) + ch_versions = ch_versions.mix(UNTAR_SPACERANGER_INPUT.out.versions) + + // Combine extracted and directory inputs into one channel + ch_spaceranger_combined = UNTAR_SPACERANGER_INPUT.out.untar + .mix ( ch_spaceranger.dir ) + .map { meta, dir -> meta + [fastq_dir: dir] } + + // Create final meta map and check input existance + ch_spaceranger_input = ch_spaceranger_combined.map { create_channel_spaceranger(it) } + + emit: + ch_spaceranger_input // channel: [ val(meta), [ st data ] ] + versions = ch_versions // channel: [ versions.yml ] +} + +// Function to get list of [ meta, [ fastq_dir, tissue_hires_image, slide, area ]] +def create_channel_spaceranger(LinkedHashMap meta) { + meta["id"] = meta.remove("sample") + + // Convert a path in `meta` to a file object and return it. If `key` is not contained in `meta` + // return an empty list which is recognized as 'no file' by nextflow. + def get_file_from_meta = {key -> + v = meta.remove(key); + return v ? file(v) : [] + } + + fastq_dir = meta.remove("fastq_dir") + fastq_files = file("${fastq_dir}/${meta['id']}*.fastq.gz") + manual_alignment = get_file_from_meta("manual_alignment") + slidefile = get_file_from_meta("slidefile") + image = get_file_from_meta("image") + cytaimage = get_file_from_meta("cytaimage") + colorizedimage = get_file_from_meta("colorizedimage") + darkimage = get_file_from_meta("darkimage") + + if(!fastq_files.size()) { + error "No `fastq_dir` specified or no samples found in folder." + } + + check_optional_files = ["manual_alignment", "slidefile", "image", "cytaimage", "colorizedimage", "darkimage"] + for(k in check_optional_files) { + if(this.binding[k] && !this.binding[k].exists()) { + error "File for `${k}` is specified, but does not exist: ${this.binding[k]}." + } + } + if(!(image || cytaimage || colorizedimage || darkimage)) { + error "Need to specify at least one of 'image', 'cytaimage', 'colorizedimage', or 'darkimage' in the samplesheet" + } + + return [meta, fastq_files, image, cytaimage, darkimage, colorizedimage, manual_alignment, slidefile] +} + diff --git a/subworkflows/local/spaceranger.nf b/subworkflows/local/spaceranger.nf new file mode 100644 index 0000000..3e415bc --- /dev/null +++ b/subworkflows/local/spaceranger.nf @@ -0,0 +1,59 @@ +// +// Raw data processing with Space Ranger +// + +include { UNTAR as SPACERANGER_UNTAR_REFERENCE } from "../../modules/nf-core/untar" +include { SPACERANGER_COUNT } from '../../modules/nf-core/spaceranger/count' + +workflow SPACERANGER { + take: + ch_data // channel: [ val(meta), [ raw st data ] ] + + main: + + ch_versions = Channel.empty() + + // + // Reference files + // + ch_reference = Channel.empty() + if (params.spaceranger_reference ==~ /.*\.tar\.gz$/) { + ref_file = file(params.spaceranger_reference) + SPACERANGER_UNTAR_REFERENCE( + [ + [id: "reference"], + ref_file, + ] + ) + ch_reference = SPACERANGER_UNTAR_REFERENCE.out.untar.map { meta, ref -> ref } + ch_versions = ch_versions.mix(SPACERANGER_UNTAR_REFERENCE.out.versions) + } + else { + ch_reference = file(params.spaceranger_reference, type: "dir", checkIfExists: true) + } + + // + // Optional: probe set + // + ch_probeset = Channel.empty() + if (params.spaceranger_probeset) { + ch_probeset = file(params.spaceranger_probeset, checkIfExists: true) + } + else { + ch_probeset = [] + } + + // + // Run Space Ranger count + // + SPACERANGER_COUNT( + ch_data, + ch_reference, + ch_probeset, + ) + ch_versions = ch_versions.mix(SPACERANGER_COUNT.out.versions.first()) + + emit: + sr_dir = SPACERANGER_COUNT.out.outs + versions = ch_versions // channel: [ versions.yml ] +} diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index 2fdf694..6ea9dff 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -68,12 +68,29 @@ workflow PIPELINE_INITIALISATION { Channel .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) - .map { meta, dataset_id -> - if (!dataset_id) { - dataset_id = file(meta.id).baseName + .map { meta, data_path -> + if (!meta.fastq_dir) { + if (!data_path) { + exit(1, "The data_path must be provided (path to the raw inputs)") + } + + if (!meta.id) { + meta.id = file(data_path).baseName + } + + meta.data_dir = data_path + } + else { + meta.data_dir = "${meta.id}/spaceranger/outs" + + if (!meta.id) { + exit(1, "The id must be provided when running on Visium HD data") + } } + meta.sdata_dir = "${meta.id}.zarr" + meta.explorer_dir = "${meta.id}.explorer" - return [id: meta.id, sdata_dir: "${dataset_id}.zarr", explorer_dir: "${dataset_id}.explorer"] + return meta } .map { samplesheet -> validateInputSamplesheet(samplesheet) diff --git a/toy/samplesheet.csv b/toy/samplesheet.csv index ede083c..de3ce63 100644 --- a/toy/samplesheet.csv +++ b/toy/samplesheet.csv @@ -1,2 +1,3 @@ -sample +data_path toy/data +toy/data2 diff --git a/toy/samplesheet_vhd.csv b/toy/samplesheet_vhd.csv new file mode 100644 index 0000000..9f28dd5 --- /dev/null +++ b/toy/samplesheet_vhd.csv @@ -0,0 +1,2 @@ +sample,fastq_dir +toy/data,fastq diff --git a/toy/vhd_stardist.yaml b/toy/vhd_stardist.yaml new file mode 100644 index 0000000..115fa6d --- /dev/null +++ b/toy/vhd_stardist.yaml @@ -0,0 +1,18 @@ +# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml +read: + technology: visium_hd + +patchify: + patch_width_pixel: 2000 + patch_overlap_pixel: 50 + +segmentation: + stardist: + min_area: 30 + +aggregate: + aggregate_channels: true + min_transcripts: 10 # [optional] cells whose transcript count is below that this threshold are filtered + +explorer: + ram_threshold_gb: 4 diff --git a/workflows/sopa.nf b/workflows/sopa.nf index fe086b8..2955b9d 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -12,6 +12,8 @@ include { baysor } from '../subworkflows/local/baysor' include { proseg } from '../subworkflows/local/proseg' include { readConfigFile } from '../modules/local/utils' include { ArgsCLI } from '../modules/local/utils' +include { SPACERANGER } from '../subworkflows/local/spaceranger' +include { INPUT_CHECK } from '../subworkflows/local/input_check' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -29,6 +31,20 @@ workflow SOPA { def config = readConfigFile(configfile) + if (config.read.technology == "visium_hd") { + INPUT_CHECK(ch_samplesheet) + + ch_space_ranger_input = INPUT_CHECK.out.ch_spaceranger_input + + ch_versions = ch_versions.mix(INPUT_CHECK.out.versions) + SPACERANGER(ch_space_ranger_input) + + (ch_samplesheet, _files) = SPACERANGER.out.sr_dir + ch_versions = ch_versions.mix(SPACERANGER.out.versions.first()) + + ch_samplesheet + } + ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }, ArgsCLI(config.read)) explorer_raw(ch_spatialdata, ArgsCLI(config.explorer)) @@ -103,7 +119,7 @@ process toSpatialData { script: """ - sopa convert ${meta.id} --sdata-path ${meta.sdata_dir} ${cli_arguments} + sopa convert ${meta.data_dir} --sdata-path ${meta.sdata_dir} ${cli_arguments} """ } From a8de3130386b07669afa8444cab07f2697c47962 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Mar 2025 14:56:17 +0100 Subject: [PATCH 050/227] add default Spaceranger options --- nextflow.config | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nextflow.config b/nextflow.config index 7043ec8..c9e3f4a 100644 --- a/nextflow.config +++ b/nextflow.config @@ -13,6 +13,11 @@ params { // Input options input = null + // Spaceranger options + spaceranger_reference = "https://cf.10xgenomics.com/supp/spatial-exp/refdata-gex-GRCh38-2020-A.tar.gz" + spaceranger_probeset = null + spaceranger_save_reference = false + // Boilerplate options outdir = null publish_dir_mode = 'copy' From 24589134968fb637013ba1a1baf25729db2c1f2a Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Mar 2025 16:51:40 +0100 Subject: [PATCH 051/227] use .name to detect tar.gz --- nextflow.config | 1 - subworkflows/local/input_check.nf | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/nextflow.config b/nextflow.config index c9e3f4a..7460902 100644 --- a/nextflow.config +++ b/nextflow.config @@ -16,7 +16,6 @@ params { // Spaceranger options spaceranger_reference = "https://cf.10xgenomics.com/supp/spatial-exp/refdata-gex-GRCh38-2020-A.tar.gz" spaceranger_probeset = null - spaceranger_save_reference = false // Boilerplate options outdir = null diff --git a/subworkflows/local/input_check.nf b/subworkflows/local/input_check.nf index aaba9ea..f810044 100644 --- a/subworkflows/local/input_check.nf +++ b/subworkflows/local/input_check.nf @@ -19,8 +19,8 @@ workflow INPUT_CHECK { ch_spaceranger = ch_samplesheet .map { it -> [it, it.fastq_dir]} .branch { - tar: it[1].contains(".tar.gz") - dir: !it[1].contains(".tar.gz") + tar: it[1].name.contains(".tar.gz") + dir: !it[1].name.contains(".tar.gz") } // Extract tarballed inputs From f0025424d1790e75fc8b3b07e0773422ebfbc068 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Mar 2025 17:06:38 +0100 Subject: [PATCH 052/227] avoid id null --- conf/test_vhd.config | 2 +- subworkflows/local/input_check.nf | 2 -- toy/samplesheet_fastq.csv | 2 ++ 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 toy/samplesheet_fastq.csv diff --git a/conf/test_vhd.config b/conf/test_vhd.config index 70fa04b..9b3e44b 100644 --- a/conf/test_vhd.config +++ b/conf/test_vhd.config @@ -25,7 +25,7 @@ params { // 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 - input = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/samplesheet_spaceranger.csv" + input = "${baseDir}/toy/samplesheet_fastq.csv" spaceranger_probeset = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/outs/probe_set.csv" spaceranger_reference = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/homo_sapiens_chr22_reference.tar.gz" configfile = "${baseDir}/toy/vhd_stardist.yaml" diff --git a/subworkflows/local/input_check.nf b/subworkflows/local/input_check.nf index f810044..7078cb0 100644 --- a/subworkflows/local/input_check.nf +++ b/subworkflows/local/input_check.nf @@ -42,8 +42,6 @@ workflow INPUT_CHECK { // Function to get list of [ meta, [ fastq_dir, tissue_hires_image, slide, area ]] def create_channel_spaceranger(LinkedHashMap meta) { - meta["id"] = meta.remove("sample") - // Convert a path in `meta` to a file object and return it. If `key` is not contained in `meta` // return an empty list which is recognized as 'no file' by nextflow. def get_file_from_meta = {key -> diff --git a/toy/samplesheet_fastq.csv b/toy/samplesheet_fastq.csv new file mode 100644 index 0000000..1b1f11b --- /dev/null +++ b/toy/samplesheet_fastq.csv @@ -0,0 +1,2 @@ +sample,fastq_dir,cytaimage,slide,area,manual_alignment,slidefile +CytAssist_11mm_FFPE_Human_Glioblastoma_2,/Users/quentinblampey/data/sandbox/fastq_dir,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_image.tif,V52Y10-317,B1,,https://s3.us-west-2.amazonaws.com/10x.spatial-slides/gpr/V52Y10/V52Y10-317.gpr \ No newline at end of file From aa705d80311ef46c2316af4ee95f1fd2a65e2486 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Mar 2025 17:11:25 +0100 Subject: [PATCH 053/227] debug vhd --- workflows/sopa.nf | 65 ++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 2955b9d..826b967 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -39,53 +39,50 @@ workflow SOPA { ch_versions = ch_versions.mix(INPUT_CHECK.out.versions) SPACERANGER(ch_space_ranger_input) - (ch_samplesheet, _files) = SPACERANGER.out.sr_dir - ch_versions = ch_versions.mix(SPACERANGER.out.versions.first()) - - ch_samplesheet + SPACERANGER.out.sr_dir.view() } - ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }, ArgsCLI(config.read)) + // ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }, ArgsCLI(config.read)) - explorer_raw(ch_spatialdata, ArgsCLI(config.explorer)) + // explorer_raw(ch_spatialdata, ArgsCLI(config.explorer)) - if (config.segmentation.tissue) { - (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, ArgsCLI(config.segmentation.tissue)) - } - else { - ch_tissue_seg = ch_spatialdata - } + // if (config.segmentation.tissue) { + // (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, ArgsCLI(config.segmentation.tissue)) + // } + // else { + // ch_tissue_seg = ch_spatialdata + // } - if (config.segmentation.cellpose) { - (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) - ch_resolved = cellpose(ch_image_patches, config) - } + // if (config.segmentation.cellpose) { + // (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) + // ch_resolved = cellpose(ch_image_patches, config) + // } - if (config.segmentation.stardist) { - (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) - ch_resolved = stardist(ch_image_patches, config) - } + // if (config.segmentation.stardist) { + // (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) + // ch_resolved = stardist(ch_image_patches, config) + // } - if (config.segmentation.baysor) { - ch_input_baysor = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg + // if (config.segmentation.baysor) { + // ch_input_baysor = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg - ch_transcripts_patches = makeTranscriptPatches(ch_input_baysor, transcriptPatchesArgs(config, "baysor")) - ch_resolved = baysor(ch_transcripts_patches, config) - } + // ch_transcripts_patches = makeTranscriptPatches(ch_input_baysor, transcriptPatchesArgs(config, "baysor")) + // ch_resolved = baysor(ch_transcripts_patches, config) + // } - if (config.segmentation.proseg) { - ch_input_proseg = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg + // if (config.segmentation.proseg) { + // ch_input_proseg = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg - ch_proseg_patches = makeTranscriptPatches(ch_input_proseg, transcriptPatchesArgs(config, "proseg")) - ch_resolved = proseg(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, config) - } + // ch_proseg_patches = makeTranscriptPatches(ch_input_proseg, transcriptPatchesArgs(config, "proseg")) + // ch_resolved = proseg(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, config) + // } - (ch_aggregated, _out) = aggregate(ch_resolved, ArgsCLI(config.aggregate)) + // (ch_aggregated, _out) = aggregate(ch_resolved, ArgsCLI(config.aggregate)) - explorer(ch_aggregated, ArgsCLI(config.explorer)) - report(ch_aggregated) + // explorer(ch_aggregated, ArgsCLI(config.explorer)) + // report(ch_aggregated) - publish(ch_aggregated.map { it[1] }) + // publish(ch_aggregated.map { it[1] }) // From 3e35eb1c26ec57e4e0454bdcb2f15b1481c7c09a Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Mar 2025 17:21:41 +0100 Subject: [PATCH 054/227] re-use online data for test --- conf/test_vhd.config | 2 +- toy/samplesheet_fastq.csv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/test_vhd.config b/conf/test_vhd.config index 9b3e44b..70fa04b 100644 --- a/conf/test_vhd.config +++ b/conf/test_vhd.config @@ -25,7 +25,7 @@ params { // 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 - input = "${baseDir}/toy/samplesheet_fastq.csv" + input = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/samplesheet_spaceranger.csv" spaceranger_probeset = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/outs/probe_set.csv" spaceranger_reference = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/homo_sapiens_chr22_reference.tar.gz" configfile = "${baseDir}/toy/vhd_stardist.yaml" diff --git a/toy/samplesheet_fastq.csv b/toy/samplesheet_fastq.csv index 1b1f11b..cbe6632 100644 --- a/toy/samplesheet_fastq.csv +++ b/toy/samplesheet_fastq.csv @@ -1,2 +1,2 @@ sample,fastq_dir,cytaimage,slide,area,manual_alignment,slidefile -CytAssist_11mm_FFPE_Human_Glioblastoma_2,/Users/quentinblampey/data/sandbox/fastq_dir,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_image.tif,V52Y10-317,B1,,https://s3.us-west-2.amazonaws.com/10x.spatial-slides/gpr/V52Y10/V52Y10-317.gpr \ No newline at end of file +CytAssist_11mm_FFPE_Human_Glioblastoma_2,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/fastq_dir.tar.gz,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_image.tif,V52Y10-317,B1,,https://s3.us-west-2.amazonaws.com/10x.spatial-slides/gpr/V52Y10/V52Y10-317.gpr \ No newline at end of file From 8e4e451905a2340ccfc88db637c23e94af54d25f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Mar 2025 17:29:59 +0100 Subject: [PATCH 055/227] add config create bam --- modules/nf-core/spaceranger/count/nextflow.config | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 modules/nf-core/spaceranger/count/nextflow.config diff --git a/modules/nf-core/spaceranger/count/nextflow.config b/modules/nf-core/spaceranger/count/nextflow.config new file mode 100644 index 0000000..e4b3571 --- /dev/null +++ b/modules/nf-core/spaceranger/count/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: SPACERANGER_COUNT { + ext.args = '--create-bam="false"' + } +} From 72c9bf7baea507ce0c8e5af92be89f36433685aa Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Mar 2025 17:55:57 +0100 Subject: [PATCH 056/227] --create-bam="false" --- modules/nf-core/spaceranger/count/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nf-core/spaceranger/count/main.nf b/modules/nf-core/spaceranger/count/main.nf index f33d82f..42d5a63 100644 --- a/modules/nf-core/spaceranger/count/main.nf +++ b/modules/nf-core/spaceranger/count/main.nf @@ -45,7 +45,7 @@ process SPACERANGER_COUNT { $probeset \\ $alignment \\ $slidefile \\ - $args + --create-bam="false" mv ${prefix}/outs outs cat <<-END_VERSIONS > versions.yml From dfb0ea025a47b7d808c06ae822ef152a89e6edb4 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 27 Mar 2025 18:02:28 +0100 Subject: [PATCH 057/227] cleanup create bam --- modules/nf-core/spaceranger/count/main.nf | 2 +- modules/nf-core/spaceranger/count/nextflow.config | 5 ----- nextflow.config | 3 +++ 3 files changed, 4 insertions(+), 6 deletions(-) delete mode 100644 modules/nf-core/spaceranger/count/nextflow.config diff --git a/modules/nf-core/spaceranger/count/main.nf b/modules/nf-core/spaceranger/count/main.nf index 42d5a63..f33d82f 100644 --- a/modules/nf-core/spaceranger/count/main.nf +++ b/modules/nf-core/spaceranger/count/main.nf @@ -45,7 +45,7 @@ process SPACERANGER_COUNT { $probeset \\ $alignment \\ $slidefile \\ - --create-bam="false" + $args mv ${prefix}/outs outs cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/spaceranger/count/nextflow.config b/modules/nf-core/spaceranger/count/nextflow.config deleted file mode 100644 index e4b3571..0000000 --- a/modules/nf-core/spaceranger/count/nextflow.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: SPACERANGER_COUNT { - ext.args = '--create-bam="false"' - } -} diff --git a/nextflow.config b/nextflow.config index 7460902..11cd9aa 100644 --- a/nextflow.config +++ b/nextflow.config @@ -275,3 +275,6 @@ validation { afterText = validation.help.afterText } } + +// Load modules.config for DSL2 module specific options +includeConfig 'conf/modules.config' From 24fc4f2f176a3c822745ba9ba3778fa3521ead5d Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 28 Mar 2025 09:17:34 +0100 Subject: [PATCH 058/227] cleanup spaceranger --- subworkflows/local/input_check.nf | 77 ------------------------------- subworkflows/local/spaceranger.nf | 76 +++++++++++++++++++++++++++--- workflows/sopa.nf | 10 +--- 3 files changed, 71 insertions(+), 92 deletions(-) delete mode 100644 subworkflows/local/input_check.nf diff --git a/subworkflows/local/input_check.nf b/subworkflows/local/input_check.nf deleted file mode 100644 index 7078cb0..0000000 --- a/subworkflows/local/input_check.nf +++ /dev/null @@ -1,77 +0,0 @@ -// -// Check input samplesheet and get read channels -// - -include { UNTAR as UNTAR_SPACERANGER_INPUT } from "../../modules/nf-core/untar" - -workflow INPUT_CHECK { - - take: - ch_samplesheet - - main: - - ch_versions = Channel.empty() - - // Space Ranger analysis: -------------------------------------------------- - - // Split channel into tarballed and directory inputs - ch_spaceranger = ch_samplesheet - .map { it -> [it, it.fastq_dir]} - .branch { - tar: it[1].name.contains(".tar.gz") - dir: !it[1].name.contains(".tar.gz") - } - - // Extract tarballed inputs - UNTAR_SPACERANGER_INPUT ( ch_spaceranger.tar ) - ch_versions = ch_versions.mix(UNTAR_SPACERANGER_INPUT.out.versions) - - // Combine extracted and directory inputs into one channel - ch_spaceranger_combined = UNTAR_SPACERANGER_INPUT.out.untar - .mix ( ch_spaceranger.dir ) - .map { meta, dir -> meta + [fastq_dir: dir] } - - // Create final meta map and check input existance - ch_spaceranger_input = ch_spaceranger_combined.map { create_channel_spaceranger(it) } - - emit: - ch_spaceranger_input // channel: [ val(meta), [ st data ] ] - versions = ch_versions // channel: [ versions.yml ] -} - -// Function to get list of [ meta, [ fastq_dir, tissue_hires_image, slide, area ]] -def create_channel_spaceranger(LinkedHashMap meta) { - // Convert a path in `meta` to a file object and return it. If `key` is not contained in `meta` - // return an empty list which is recognized as 'no file' by nextflow. - def get_file_from_meta = {key -> - v = meta.remove(key); - return v ? file(v) : [] - } - - fastq_dir = meta.remove("fastq_dir") - fastq_files = file("${fastq_dir}/${meta['id']}*.fastq.gz") - manual_alignment = get_file_from_meta("manual_alignment") - slidefile = get_file_from_meta("slidefile") - image = get_file_from_meta("image") - cytaimage = get_file_from_meta("cytaimage") - colorizedimage = get_file_from_meta("colorizedimage") - darkimage = get_file_from_meta("darkimage") - - if(!fastq_files.size()) { - error "No `fastq_dir` specified or no samples found in folder." - } - - check_optional_files = ["manual_alignment", "slidefile", "image", "cytaimage", "colorizedimage", "darkimage"] - for(k in check_optional_files) { - if(this.binding[k] && !this.binding[k].exists()) { - error "File for `${k}` is specified, but does not exist: ${this.binding[k]}." - } - } - if(!(image || cytaimage || colorizedimage || darkimage)) { - error "Need to specify at least one of 'image', 'cytaimage', 'colorizedimage', or 'darkimage' in the samplesheet" - } - - return [meta, fastq_files, image, cytaimage, darkimage, colorizedimage, manual_alignment, slidefile] -} - diff --git a/subworkflows/local/spaceranger.nf b/subworkflows/local/spaceranger.nf index 3e415bc..5c57eb6 100644 --- a/subworkflows/local/spaceranger.nf +++ b/subworkflows/local/spaceranger.nf @@ -2,31 +2,54 @@ // Raw data processing with Space Ranger // -include { UNTAR as SPACERANGER_UNTAR_REFERENCE } from "../../modules/nf-core/untar" +include { UNTAR } from "../../modules/nf-core/untar" include { SPACERANGER_COUNT } from '../../modules/nf-core/spaceranger/count' workflow SPACERANGER { take: - ch_data // channel: [ val(meta), [ raw st data ] ] + ch_samplesheet main: ch_versions = Channel.empty() + // Space Ranger analysis: -------------------------------------------------- + + // Split channel into tarballed and directory inputs + ch_spaceranger = ch_samplesheet + .map { it -> [it, it.fastq_dir]} + .branch { + tar: it[1].name.contains(".tar.gz") + dir: !it[1].name.contains(".tar.gz") + } + + // Extract tarballed inputs + UNTAR ( ch_spaceranger.tar ) + ch_versions = ch_versions.mix(UNTAR.out.versions) + + // Combine extracted and directory inputs into one channel + ch_spaceranger_combined = UNTAR.out.untar + .mix ( ch_spaceranger.dir ) + .map { meta, dir -> meta + [fastq_dir: dir] } + + // Create final meta map and check input existance + ch_spaceranger_input = ch_spaceranger_combined.map { create_channel_spaceranger(it) } + + // // Reference files // ch_reference = Channel.empty() if (params.spaceranger_reference ==~ /.*\.tar\.gz$/) { ref_file = file(params.spaceranger_reference) - SPACERANGER_UNTAR_REFERENCE( + UNTAR( [ [id: "reference"], ref_file, ] ) - ch_reference = SPACERANGER_UNTAR_REFERENCE.out.untar.map { meta, ref -> ref } - ch_versions = ch_versions.mix(SPACERANGER_UNTAR_REFERENCE.out.versions) + ch_reference = UNTAR.out.untar.map { meta, ref -> ref } + ch_versions = ch_versions.mix(UNTAR.out.versions) } else { ch_reference = file(params.spaceranger_reference, type: "dir", checkIfExists: true) @@ -47,13 +70,52 @@ workflow SPACERANGER { // Run Space Ranger count // SPACERANGER_COUNT( - ch_data, + ch_spaceranger_input, ch_reference, ch_probeset, ) + + ch_samplesheet = SPACERANGER_COUNT.out.outs.map { outs -> outs[0] } ch_versions = ch_versions.mix(SPACERANGER_COUNT.out.versions.first()) emit: - sr_dir = SPACERANGER_COUNT.out.outs + ch_samplesheet = ch_samplesheet versions = ch_versions // channel: [ versions.yml ] } + + +// Function to get list of [ meta, [ fastq_dir, tissue_hires_image, slide, area ]] +def create_channel_spaceranger(LinkedHashMap meta) { + // Convert a path in `meta` to a file object and return it. If `key` is not contained in `meta` + // return an empty list which is recognized as 'no file' by nextflow. + def get_file_from_meta = {key -> + v = meta.remove(key); + return v ? file(v) : [] + } + + fastq_dir = meta.remove("fastq_dir") + fastq_files = file("${fastq_dir}/${meta['id']}*.fastq.gz") + manual_alignment = get_file_from_meta("manual_alignment") + slidefile = get_file_from_meta("slidefile") + image = get_file_from_meta("image") + cytaimage = get_file_from_meta("cytaimage") + colorizedimage = get_file_from_meta("colorizedimage") + darkimage = get_file_from_meta("darkimage") + + if(!fastq_files.size()) { + error "No `fastq_dir` specified or no samples found in folder." + } + + check_optional_files = ["manual_alignment", "slidefile", "image", "cytaimage", "colorizedimage", "darkimage"] + for(k in check_optional_files) { + if(this.binding[k] && !this.binding[k].exists()) { + error "File for `${k}` is specified, but does not exist: ${this.binding[k]}." + } + } + if(!(image || cytaimage || colorizedimage || darkimage)) { + error "Need to specify at least one of 'image', 'cytaimage', 'colorizedimage', or 'darkimage' in the samplesheet" + } + + return [meta, fastq_files, image, cytaimage, darkimage, colorizedimage, manual_alignment, slidefile] +} + diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 826b967..214d753 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -13,7 +13,6 @@ include { proseg } from '../subworkflows/local/proseg' include { readConfigFile } from '../modules/local/utils' include { ArgsCLI } from '../modules/local/utils' include { SPACERANGER } from '../subworkflows/local/spaceranger' -include { INPUT_CHECK } from '../subworkflows/local/input_check' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -32,14 +31,9 @@ workflow SOPA { def config = readConfigFile(configfile) if (config.read.technology == "visium_hd") { - INPUT_CHECK(ch_samplesheet) + SPACERANGER(ch_samplesheet) - ch_space_ranger_input = INPUT_CHECK.out.ch_spaceranger_input - - ch_versions = ch_versions.mix(INPUT_CHECK.out.versions) - SPACERANGER(ch_space_ranger_input) - - SPACERANGER.out.sr_dir.view() + SPACERANGER.out.ch_samplesheet.view() } // ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }, ArgsCLI(config.read)) From 4202263bb9f23cd4e83c55602b26e9a943e3d144 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 28 Mar 2025 09:20:44 +0100 Subject: [PATCH 059/227] rename untar --- subworkflows/local/spaceranger.nf | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/subworkflows/local/spaceranger.nf b/subworkflows/local/spaceranger.nf index 5c57eb6..df69926 100644 --- a/subworkflows/local/spaceranger.nf +++ b/subworkflows/local/spaceranger.nf @@ -2,7 +2,8 @@ // Raw data processing with Space Ranger // -include { UNTAR } from "../../modules/nf-core/untar" +include { UNTAR as SPACERANGER_UNTAR_REFERENCE} from "../../modules/nf-core/untar" +include { UNTAR as UNTAR_SPACERANGER_INPUT} from "../../modules/nf-core/untar" include { SPACERANGER_COUNT } from '../../modules/nf-core/spaceranger/count' workflow SPACERANGER { @@ -24,11 +25,11 @@ workflow SPACERANGER { } // Extract tarballed inputs - UNTAR ( ch_spaceranger.tar ) - ch_versions = ch_versions.mix(UNTAR.out.versions) + UNTAR_SPACERANGER_INPUT ( ch_spaceranger.tar ) + ch_versions = ch_versions.mix(UNTAR_SPACERANGER_INPUT.out.versions) // Combine extracted and directory inputs into one channel - ch_spaceranger_combined = UNTAR.out.untar + ch_spaceranger_combined = UNTAR_SPACERANGER_INPUT.out.untar .mix ( ch_spaceranger.dir ) .map { meta, dir -> meta + [fastq_dir: dir] } @@ -42,14 +43,14 @@ workflow SPACERANGER { ch_reference = Channel.empty() if (params.spaceranger_reference ==~ /.*\.tar\.gz$/) { ref_file = file(params.spaceranger_reference) - UNTAR( + SPACERANGER_UNTAR_REFERENCE( [ [id: "reference"], ref_file, ] ) - ch_reference = UNTAR.out.untar.map { meta, ref -> ref } - ch_versions = ch_versions.mix(UNTAR.out.versions) + ch_reference = SPACERANGER_UNTAR_REFERENCE.out.untar.map { meta, ref -> ref } + ch_versions = ch_versions.mix(SPACERANGER_UNTAR_REFERENCE.out.versions) } else { ch_reference = file(params.spaceranger_reference, type: "dir", checkIfExists: true) From 5064f531b9b21eb4440fb30a55c2ac8c5cc25e63 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 28 Mar 2025 10:23:05 +0100 Subject: [PATCH 060/227] cleanup vhd and pass kwargs to reader --- modules/local/utils.nf | 35 +++++++++ subworkflows/local/spaceranger.nf | 51 +++++++------ .../local/utils_nfcore_sopa_pipeline/main.nf | 2 +- toy/samplesheet.csv | 1 - workflows/sopa.nf | 71 ++++++++++--------- 5 files changed, 98 insertions(+), 62 deletions(-) diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 6ae6b16..fe3a1ed 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -40,6 +40,25 @@ def ArgsCLI(Map params, String contains = null, List keys = null) { .join(" ") } +def ArgsReaderCLI(Map args, Map meta) { + if (args.technology == "visium_hd") { + args = deepCopyCollection(args) + + if (!args.kwargs) { + args.kwargs = ["dataset_id": meta.id] + } + else { + args.kwargs["dataset_id"] = meta.id + } + + if (meta.image) { + args.kwargs["fullres_image_file"] = meta.image + } + } + + return ArgsCLI(args) +} + def readConfigFile(String configfile) { def config = new groovy.yaml.YamlSlurper().parse(configfile as File) @@ -54,3 +73,19 @@ def readConfigFile(String configfile) { } return config } + +def deepCopyCollection(object) { + if (object instanceof Map) { + object.collectEntries { key, value -> + [key, deepCopyCollection(value)] + } + } + else if (object instanceof List) { + object.collect { item -> + deepCopyCollection(item) + } + } + else { + object + } +} diff --git a/subworkflows/local/spaceranger.nf b/subworkflows/local/spaceranger.nf index df69926..2426c30 100644 --- a/subworkflows/local/spaceranger.nf +++ b/subworkflows/local/spaceranger.nf @@ -2,8 +2,8 @@ // Raw data processing with Space Ranger // -include { UNTAR as SPACERANGER_UNTAR_REFERENCE} from "../../modules/nf-core/untar" -include { UNTAR as UNTAR_SPACERANGER_INPUT} from "../../modules/nf-core/untar" +include { UNTAR as SPACERANGER_UNTAR_REFERENCE } from "../../modules/nf-core/untar" +include { UNTAR as UNTAR_SPACERANGER_INPUT } from "../../modules/nf-core/untar" include { SPACERANGER_COUNT } from '../../modules/nf-core/spaceranger/count' workflow SPACERANGER { @@ -18,19 +18,19 @@ workflow SPACERANGER { // Split channel into tarballed and directory inputs ch_spaceranger = ch_samplesheet - .map { it -> [it, it.fastq_dir]} + .map { it -> [it, it.fastq_dir] } .branch { tar: it[1].name.contains(".tar.gz") dir: !it[1].name.contains(".tar.gz") } // Extract tarballed inputs - UNTAR_SPACERANGER_INPUT ( ch_spaceranger.tar ) + UNTAR_SPACERANGER_INPUT(ch_spaceranger.tar) ch_versions = ch_versions.mix(UNTAR_SPACERANGER_INPUT.out.versions) // Combine extracted and directory inputs into one channel ch_spaceranger_combined = UNTAR_SPACERANGER_INPUT.out.untar - .mix ( ch_spaceranger.dir ) + .mix(ch_spaceranger.dir) .map { meta, dir -> meta + [fastq_dir: dir] } // Create final meta map and check input existance @@ -49,7 +49,7 @@ workflow SPACERANGER { ref_file, ] ) - ch_reference = SPACERANGER_UNTAR_REFERENCE.out.untar.map { meta, ref -> ref } + ch_reference = SPACERANGER_UNTAR_REFERENCE.out.untar.map { _meta, ref -> ref } ch_versions = ch_versions.mix(SPACERANGER_UNTAR_REFERENCE.out.versions) } else { @@ -89,34 +89,33 @@ workflow SPACERANGER { def create_channel_spaceranger(LinkedHashMap meta) { // Convert a path in `meta` to a file object and return it. If `key` is not contained in `meta` // return an empty list which is recognized as 'no file' by nextflow. - def get_file_from_meta = {key -> - v = meta.remove(key); + def get_file_from_meta = { key -> + def v = meta.remove(key) return v ? file(v) : [] } - fastq_dir = meta.remove("fastq_dir") - fastq_files = file("${fastq_dir}/${meta['id']}*.fastq.gz") - manual_alignment = get_file_from_meta("manual_alignment") - slidefile = get_file_from_meta("slidefile") - image = get_file_from_meta("image") - cytaimage = get_file_from_meta("cytaimage") - colorizedimage = get_file_from_meta("colorizedimage") - darkimage = get_file_from_meta("darkimage") - - if(!fastq_files.size()) { - error "No `fastq_dir` specified or no samples found in folder." + def fastq_dir = meta.remove("fastq_dir") + def fastq_files = file("${fastq_dir}/${meta['id']}*.fastq.gz") + def manual_alignment = get_file_from_meta("manual_alignment") + def slidefile = get_file_from_meta("slidefile") + def image = get_file_from_meta("image") + def cytaimage = get_file_from_meta("cytaimage") + def colorizedimage = get_file_from_meta("colorizedimage") + def darkimage = get_file_from_meta("darkimage") + + if (!fastq_files.size()) { + error("No `fastq_dir` specified or no samples found in folder.") } - check_optional_files = ["manual_alignment", "slidefile", "image", "cytaimage", "colorizedimage", "darkimage"] - for(k in check_optional_files) { - if(this.binding[k] && !this.binding[k].exists()) { - error "File for `${k}` is specified, but does not exist: ${this.binding[k]}." + def check_optional_files = [["manual_alignment", manual_alignment], ["slidefile", slidefile], ["image", image], ["cytaimage", cytaimage], ["colorizedimage", colorizedimage], ["darkimage", darkimage]] + check_optional_files.each { name, value -> + if (value && !file(value).exists()) { + error("File for `${name}` is specified, but does not exist: ${value}.") } } - if(!(image || cytaimage || colorizedimage || darkimage)) { - error "Need to specify at least one of 'image', 'cytaimage', 'colorizedimage', or 'darkimage' in the samplesheet" + if (!(image || cytaimage || colorizedimage || darkimage)) { + error("Need to specify at least one of 'image', 'cytaimage', 'colorizedimage', or 'darkimage' in the samplesheet") } return [meta, fastq_files, image, cytaimage, darkimage, colorizedimage, manual_alignment, slidefile] } - diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index 6ea9dff..c35c632 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -81,7 +81,7 @@ workflow PIPELINE_INITIALISATION { meta.data_dir = data_path } else { - meta.data_dir = "${meta.id}/spaceranger/outs" + meta.data_dir = "${meta.id}_spaceranger/outs" if (!meta.id) { exit(1, "The id must be provided when running on Visium HD data") diff --git a/toy/samplesheet.csv b/toy/samplesheet.csv index de3ce63..9a0db1b 100644 --- a/toy/samplesheet.csv +++ b/toy/samplesheet.csv @@ -1,3 +1,2 @@ data_path toy/data -toy/data2 diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 214d753..a0885d8 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -12,6 +12,7 @@ include { baysor } from '../subworkflows/local/baysor' include { proseg } from '../subworkflows/local/proseg' include { readConfigFile } from '../modules/local/utils' include { ArgsCLI } from '../modules/local/utils' +include { ArgsReaderCLI } from '../modules/local/utils' include { SPACERANGER } from '../subworkflows/local/spaceranger' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -31,52 +32,54 @@ workflow SOPA { def config = readConfigFile(configfile) if (config.read.technology == "visium_hd") { - SPACERANGER(ch_samplesheet) + (ch_samplesheet, versions) = SPACERANGER(ch_samplesheet) - SPACERANGER.out.ch_samplesheet.view() + ch_versions = ch_versions.mix(versions) } - // ch_spatialdata = toSpatialData(ch_samplesheet.map { meta -> [meta, meta.sdata_dir] }, ArgsCLI(config.read)) + ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.sdata_dir] } - // explorer_raw(ch_spatialdata, ArgsCLI(config.explorer)) + ch_spatialdata = toSpatialData(ch_input_spatialdata, config.read) - // if (config.segmentation.tissue) { - // (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, ArgsCLI(config.segmentation.tissue)) - // } - // else { - // ch_tissue_seg = ch_spatialdata - // } + explorer_raw(ch_spatialdata, ArgsCLI(config.explorer)) - // if (config.segmentation.cellpose) { - // (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) - // ch_resolved = cellpose(ch_image_patches, config) - // } + if (config.segmentation.tissue) { + (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, ArgsCLI(config.segmentation.tissue)) + } + else { + ch_tissue_seg = ch_spatialdata + } + + if (config.segmentation.cellpose) { + (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) + ch_resolved = cellpose(ch_image_patches, config) + } - // if (config.segmentation.stardist) { - // (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) - // ch_resolved = stardist(ch_image_patches, config) - // } + if (config.segmentation.stardist) { + (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) + ch_resolved = stardist(ch_image_patches, config) + } - // if (config.segmentation.baysor) { - // ch_input_baysor = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg + if (config.segmentation.baysor) { + ch_input_baysor = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg - // ch_transcripts_patches = makeTranscriptPatches(ch_input_baysor, transcriptPatchesArgs(config, "baysor")) - // ch_resolved = baysor(ch_transcripts_patches, config) - // } + ch_transcripts_patches = makeTranscriptPatches(ch_input_baysor, transcriptPatchesArgs(config, "baysor")) + ch_resolved = baysor(ch_transcripts_patches, config) + } - // if (config.segmentation.proseg) { - // ch_input_proseg = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg + if (config.segmentation.proseg) { + ch_input_proseg = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg - // ch_proseg_patches = makeTranscriptPatches(ch_input_proseg, transcriptPatchesArgs(config, "proseg")) - // ch_resolved = proseg(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, config) - // } + ch_proseg_patches = makeTranscriptPatches(ch_input_proseg, transcriptPatchesArgs(config, "proseg")) + ch_resolved = proseg(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, config) + } - // (ch_aggregated, _out) = aggregate(ch_resolved, ArgsCLI(config.aggregate)) + (ch_aggregated, _out) = aggregate(ch_resolved, ArgsCLI(config.aggregate)) - // explorer(ch_aggregated, ArgsCLI(config.explorer)) - // report(ch_aggregated) + explorer(ch_aggregated, ArgsCLI(config.explorer)) + report(ch_aggregated) - // publish(ch_aggregated.map { it[1] }) + publish(ch_aggregated.map { it[1] }) // @@ -103,14 +106,14 @@ process toSpatialData { input: tuple val(meta), val(sdata_dir) - val cli_arguments + val args output: tuple val(meta), path(sdata_dir) script: """ - sopa convert ${meta.data_dir} --sdata-path ${meta.sdata_dir} ${cli_arguments} + sopa convert ${meta.data_dir} --sdata-path ${meta.sdata_dir} ${ArgsReaderCLI(args, meta)} """ } From 60f1148a29ec78cb1317d155887b75dec17609a5 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 28 Mar 2025 12:03:55 +0100 Subject: [PATCH 061/227] update time limit proseg --- conf/base.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/base.config b/conf/base.config index 6e7a477..b7451e2 100644 --- a/conf/base.config +++ b/conf/base.config @@ -55,7 +55,7 @@ process { withName:patchSegmentationProseg { cpus = { 8 * task.attempt } memory = { 200.GB * task.attempt } - time = { 4.d * task.attempt } + time = { 10.d * task.attempt } } withLabel:error_ignore { errorStrategy = 'ignore' From 59dae3aeb8263bb7294075bdf1c3d7e6fff71f69 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 31 Mar 2025 09:27:28 +0200 Subject: [PATCH 062/227] make transcripts optional --- workflows/sopa.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index a0885d8..a2374ac 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -220,7 +220,7 @@ process explorer_raw { output: path "${meta.explorer_dir}/morphology*" - path "${meta.explorer_dir}/transcripts*" + path "${meta.explorer_dir}/transcripts*", optional: true script: """ From 49268bd3b2eb1364718f3085cc8a49192c17081a Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 1 Apr 2025 10:21:35 +0200 Subject: [PATCH 063/227] try to use space ranger --- subworkflows/local/spaceranger.nf | 3 +-- subworkflows/local/utils_nfcore_sopa_pipeline/main.nf | 3 ++- workflows/sopa.nf | 10 ++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/subworkflows/local/spaceranger.nf b/subworkflows/local/spaceranger.nf index 2426c30..999f501 100644 --- a/subworkflows/local/spaceranger.nf +++ b/subworkflows/local/spaceranger.nf @@ -76,11 +76,10 @@ workflow SPACERANGER { ch_probeset, ) - ch_samplesheet = SPACERANGER_COUNT.out.outs.map { outs -> outs[0] } ch_versions = ch_versions.mix(SPACERANGER_COUNT.out.versions.first()) emit: - ch_samplesheet = ch_samplesheet + sr_dir = SPACERANGER_COUNT.out.outs versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index c35c632..78e7ca4 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -81,7 +81,8 @@ workflow PIPELINE_INITIALISATION { meta.data_dir = data_path } else { - meta.data_dir = "${meta.id}_spaceranger/outs" + // spaceranger output directory + meta.data_dir = "outs" if (!meta.id) { exit(1, "The id must be provided when running on Visium HD data") diff --git a/workflows/sopa.nf b/workflows/sopa.nf index a2374ac..7fda360 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -32,12 +32,14 @@ workflow SOPA { def config = readConfigFile(configfile) if (config.read.technology == "visium_hd") { - (ch_samplesheet, versions) = SPACERANGER(ch_samplesheet) + (sr_dir, versions) = SPACERANGER(ch_samplesheet) ch_versions = ch_versions.mix(versions) + ch_input_spatialdata = sr_dir.map { outs -> [outs[0], outs[0].sdata_dir, outs[1]] } + } + else { + ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.sdata_dir, []] } } - - ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.sdata_dir] } ch_spatialdata = toSpatialData(ch_input_spatialdata, config.read) @@ -105,7 +107,7 @@ process toSpatialData { : 'docker.io/quentinblampey/sopa:2.0.3'}" input: - tuple val(meta), val(sdata_dir) + tuple val(meta), val(sdata_dir), path(intermediate_files) val args output: From a13eaad2d4a19e2326cd031b914d1c1b5a2b2ef4 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 1 Apr 2025 10:44:00 +0200 Subject: [PATCH 064/227] add again docker.runOptions --- nextflow.config | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/nextflow.config b/nextflow.config index 11cd9aa..5a66d72 100644 --- a/nextflow.config +++ b/nextflow.config @@ -13,10 +13,6 @@ params { // Input options input = null - // Spaceranger options - spaceranger_reference = "https://cf.10xgenomics.com/supp/spatial-exp/refdata-gex-GRCh38-2020-A.tar.gz" - spaceranger_probeset = null - // Boilerplate options outdir = null publish_dir_mode = 'copy' @@ -152,11 +148,10 @@ profiles { ] } } - test_vhd { includeConfig 'conf/test_vhd.config' } test { includeConfig 'conf/test.config' } slurm { includeConfig 'conf/slurm.config' } test_full { includeConfig 'conf/test_full.config' } -} +} // Load nf-core custom profiles from different Institutions includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/nfcore_custom.config" : "/dev/null" From 9d9d77a1c1efb1fb30e37849a7a4df039cf7725f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 1 Apr 2025 11:37:49 +0200 Subject: [PATCH 065/227] use input files --- workflows/sopa.nf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 7fda360..e52ad7c 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -32,13 +32,13 @@ workflow SOPA { def config = readConfigFile(configfile) if (config.read.technology == "visium_hd") { - (sr_dir, versions) = SPACERANGER(ch_samplesheet) + (ch_input_spatialdata, versions) = SPACERANGER(ch_samplesheet) ch_versions = ch_versions.mix(versions) - ch_input_spatialdata = sr_dir.map { outs -> [outs[0], outs[0].sdata_dir, outs[1]] } + ch_input_spatialdata = ch_input_spatialdata.map { meta, sr_outs -> [meta, meta.sdata_dir, sr_outs] } } else { - ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.sdata_dir, []] } + ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.sdata_dir, meta.data_dir] } } ch_spatialdata = toSpatialData(ch_input_spatialdata, config.read) @@ -107,7 +107,7 @@ process toSpatialData { : 'docker.io/quentinblampey/sopa:2.0.3'}" input: - tuple val(meta), val(sdata_dir), path(intermediate_files) + tuple val(meta), val(sdata_dir), path(input_files) val args output: From f6ec7b6764a304ade32d9de438c1e2a3af8f6f93 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 1 Apr 2025 11:43:09 +0200 Subject: [PATCH 066/227] use process_low --- workflows/sopa.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index e52ad7c..7ecd554 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -99,7 +99,7 @@ workflow SOPA { } process toSpatialData { - label "process_high" + label "process_low" conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container From 45d0ffb8353dedf358aa4414327b59bb04380469 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 1 Apr 2025 11:52:27 +0200 Subject: [PATCH 067/227] back to process_high --- workflows/sopa.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 7ecd554..e52ad7c 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -99,7 +99,7 @@ workflow SOPA { } process toSpatialData { - label "process_low" + label "process_high" conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container From 982ebff5e935ac6e6950f912a4d718807f6ae420 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 1 Apr 2025 12:09:24 +0200 Subject: [PATCH 068/227] minor cleanup --- workflows/sopa.nf | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index e52ad7c..07ec5a5 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -35,10 +35,9 @@ workflow SOPA { (ch_input_spatialdata, versions) = SPACERANGER(ch_samplesheet) ch_versions = ch_versions.mix(versions) - ch_input_spatialdata = ch_input_spatialdata.map { meta, sr_outs -> [meta, meta.sdata_dir, sr_outs] } } else { - ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.sdata_dir, meta.data_dir] } + ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.data_dir] } } ch_spatialdata = toSpatialData(ch_input_spatialdata, config.read) @@ -107,11 +106,11 @@ process toSpatialData { : 'docker.io/quentinblampey/sopa:2.0.3'}" input: - tuple val(meta), val(sdata_dir), path(input_files) + tuple val(meta), path(input_files) val args output: - tuple val(meta), path(sdata_dir) + tuple val(meta), path("${meta.sdata_dir}") script: """ From ac00cbca052f57d5b350cdd172f1e447322f12a3 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 1 Apr 2025 16:56:05 +0200 Subject: [PATCH 069/227] try using outs instead of outs/** --- modules/local/utils.nf | 2 ++ modules/nf-core/spaceranger/count/main.nf | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/local/utils.nf b/modules/local/utils.nf index fe3a1ed..4faa8e9 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -56,6 +56,8 @@ def ArgsReaderCLI(Map args, Map meta) { } } + println("ArgsReaderCLI: ${args}") + return ArgsCLI(args) } diff --git a/modules/nf-core/spaceranger/count/main.nf b/modules/nf-core/spaceranger/count/main.nf index f33d82f..fb6733b 100644 --- a/modules/nf-core/spaceranger/count/main.nf +++ b/modules/nf-core/spaceranger/count/main.nf @@ -10,7 +10,7 @@ process SPACERANGER_COUNT { path(probeset) output: - tuple val(meta), path("outs/**"), emit: outs + tuple val(meta), path("outs"), emit: outs path "versions.yml", emit: versions when: From efde657b9018fcb8636fd0ecf17b2607e0bb2209 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 1 Apr 2025 17:16:00 +0200 Subject: [PATCH 070/227] add back test_vhd --- nextflow.config | 1 + 1 file changed, 1 insertion(+) diff --git a/nextflow.config b/nextflow.config index 5a66d72..13623d6 100644 --- a/nextflow.config +++ b/nextflow.config @@ -148,6 +148,7 @@ profiles { ] } } + test_vhd { includeConfig 'conf/test_vhd.config' } test { includeConfig 'conf/test.config' } slurm { includeConfig 'conf/slurm.config' } test_full { includeConfig 'conf/test_full.config' } From 1cdb6698372a3c8a80139e6afeb255e49c281acf Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 1 Apr 2025 17:18:49 +0200 Subject: [PATCH 071/227] try temp process low --- modules/nf-core/spaceranger/count/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nf-core/spaceranger/count/main.nf b/modules/nf-core/spaceranger/count/main.nf index fb6733b..e415b01 100644 --- a/modules/nf-core/spaceranger/count/main.nf +++ b/modules/nf-core/spaceranger/count/main.nf @@ -1,6 +1,6 @@ process SPACERANGER_COUNT { tag "$meta.id" - label 'process_high' + label 'process_low' container "nf-core/modules/spaceranger:d71611e316a8614b" From 15676b8a5521591b0c945d5af1dcc4d1e6ad3ff7 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 1 Apr 2025 17:43:38 +0200 Subject: [PATCH 072/227] fixes vhd --- assets/schema_input.json | 8 ++++++++ nextflow.config | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/assets/schema_input.json b/assets/schema_input.json index f3e7f5a..d64300c 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -42,6 +42,14 @@ "cytaimage" ] }, + "image": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Slide image cannot contain spaces", + "meta": [ + "image" + ] + }, "slide": { "type": "string", "pattern": "^\\S+$", diff --git a/nextflow.config b/nextflow.config index 13623d6..9d06590 100644 --- a/nextflow.config +++ b/nextflow.config @@ -13,6 +13,10 @@ params { // Input options input = null + // Spaceranger options + spaceranger_reference = "https://cf.10xgenomics.com/supp/spatial-exp/refdata-gex-GRCh38-2020-A.tar.gz" + spaceranger_probeset = null + // Boilerplate options outdir = null publish_dir_mode = 'copy' From 85a77da8062585a9fd07a30c21a423ec65fc1ee7 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 1 Apr 2025 17:47:58 +0200 Subject: [PATCH 073/227] add missing inputs --- assets/schema_input.json | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/assets/schema_input.json b/assets/schema_input.json index d64300c..5dea935 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -42,10 +42,32 @@ "cytaimage" ] }, + "colorizedimage": { + "type": "string", + "pattern": "^\\S+$", + "format": "path", + "exists": true, + "errorMessage": "Path to the colorizedimage file must exist", + "meta": [ + "colorizedimage" + ] + }, + "darkimage": { + "type": "string", + "pattern": "^\\S+$", + "format": "path", + "exists": true, + "errorMessage": "Path to the darkimage file must exist", + "meta": [ + "darkimage" + ] + }, "image": { "type": "string", "pattern": "^\\S+$", - "errorMessage": "Slide image cannot contain spaces", + "format": "path", + "exists": true, + "errorMessage": "Path to the image must exist", "meta": [ "image" ] From 605ee4f0aab9e8f198cf4e0d9de70d55a5ddb8e2 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 2 Apr 2025 10:18:39 +0200 Subject: [PATCH 074/227] fix stringifyValueForCli --- modules/local/utils.nf | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 4faa8e9..8cfe592 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -28,7 +28,10 @@ def stringifyValueForCli(value) { if (value instanceof Boolean) { return value ? "True" : "False" } - return value.toString() + if (value instanceof Number) { + return value.toString() + } + return "'${value.toString()}'" } def ArgsCLI(Map params, String contains = null, List keys = null) { @@ -51,6 +54,8 @@ def ArgsReaderCLI(Map args, Map meta) { args.kwargs["dataset_id"] = meta.id } + println("meta: ${meta}") + if (meta.image) { args.kwargs["fullres_image_file"] = meta.image } From fdba687b32a86e21b3cade8a485aa8b61c7cdfb1 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 2 Apr 2025 10:41:54 +0200 Subject: [PATCH 075/227] keep image in meta --- subworkflows/local/spaceranger.nf | 2 +- subworkflows/local/utils_nfcore_sopa_pipeline/main.nf | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/subworkflows/local/spaceranger.nf b/subworkflows/local/spaceranger.nf index 999f501..91a77fd 100644 --- a/subworkflows/local/spaceranger.nf +++ b/subworkflows/local/spaceranger.nf @@ -89,7 +89,7 @@ def create_channel_spaceranger(LinkedHashMap meta) { // Convert a path in `meta` to a file object and return it. If `key` is not contained in `meta` // return an empty list which is recognized as 'no file' by nextflow. def get_file_from_meta = { key -> - def v = meta.remove(key) + def v = meta[key] return v ? file(v) : [] } diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index 78e7ca4..1e449dd 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -71,7 +71,7 @@ workflow PIPELINE_INITIALISATION { .map { meta, data_path -> if (!meta.fastq_dir) { if (!data_path) { - exit(1, "The data_path must be provided (path to the raw inputs)") + error("The data_path must be provided (path to the raw inputs)") } if (!meta.id) { @@ -85,7 +85,11 @@ workflow PIPELINE_INITIALISATION { meta.data_dir = "outs" if (!meta.id) { - exit(1, "The id must be provided when running on Visium HD data") + error("The id must be provided when running on Visium HD data") + } + + if (!meta.image) { + error("The image (full resolution image) must be provided when running Sopa on Visium HD data - it is required for the cell segmentation") } } meta.sdata_dir = "${meta.id}.zarr" From 2d952a9ced998056bffbe3a0db410180d2db7772 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 2 Apr 2025 15:58:47 +0200 Subject: [PATCH 076/227] back to process_high in spaceranger count --- modules/nf-core/spaceranger/count/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nf-core/spaceranger/count/main.nf b/modules/nf-core/spaceranger/count/main.nf index e415b01..fb6733b 100644 --- a/modules/nf-core/spaceranger/count/main.nf +++ b/modules/nf-core/spaceranger/count/main.nf @@ -1,6 +1,6 @@ process SPACERANGER_COUNT { tag "$meta.id" - label 'process_low' + label 'process_high' container "nf-core/modules/spaceranger:d71611e316a8614b" From abc91fa7c63bb06a696c4fd481ed24d3d468ee8c Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 14 Apr 2025 15:37:20 +0200 Subject: [PATCH 077/227] add vhd image as input to Spatialdata process --- workflows/sopa.nf | 1 + 1 file changed, 1 insertion(+) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 07ec5a5..db1cf6b 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -33,6 +33,7 @@ workflow SOPA { if (config.read.technology == "visium_hd") { (ch_input_spatialdata, versions) = SPACERANGER(ch_samplesheet) + ch_input_spatialdata = ch_input_spatialdata.map { meta, out -> [meta, [out, meta.image]] } ch_versions = ch_versions.mix(versions) } From 575bc7560addf3c756e9fc3c579556b0d4ab1277 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 22 Apr 2025 11:42:08 +0200 Subject: [PATCH 078/227] use recent docker images --- subworkflows/local/cellpose/main.nf | 4 ++-- subworkflows/local/proseg/main.nf | 4 ++-- subworkflows/local/stardist/main.nf | 8 ++++---- workflows/sopa.nf | 32 ++++++++++++++--------------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index b553972..0c609e0 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -47,8 +47,8 @@ process resolveCellpose { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.4' + : 'docker.io/quentinblampey/sopa:2.0.4'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index c1c4d62..c950a1a 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -20,8 +20,8 @@ process patchSegmentationProseg { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3-proseg' - : 'docker.io/quentinblampey/sopa:2.0.3-proseg'}" + ? 'docker://quentinblampey/sopa:2.0.4-proseg' + : 'docker.io/quentinblampey/sopa:2.0.4-proseg'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/stardist/main.nf b/subworkflows/local/stardist/main.nf index be0e608..a1b8f67 100644 --- a/subworkflows/local/stardist/main.nf +++ b/subworkflows/local/stardist/main.nf @@ -27,8 +27,8 @@ process patchSegmentationStardist { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3-stardist' - : 'docker.io/quentinblampey/sopa:2.0.3-stardist'}" + ? 'docker://quentinblampey/sopa:2.0.4-stardist' + : 'docker.io/quentinblampey/sopa:2.0.4-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -47,8 +47,8 @@ process resolveStardist { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.4' + : 'docker.io/quentinblampey/sopa:2.0.4'}" input: tuple val(meta), path(sdata_path) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index db1cf6b..cc5a07f 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -103,8 +103,8 @@ process toSpatialData { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.4' + : 'docker.io/quentinblampey/sopa:2.0.4'}" input: tuple val(meta), path(input_files) @@ -124,8 +124,8 @@ process tissueSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.4' + : 'docker.io/quentinblampey/sopa:2.0.4'}" input: tuple val(meta), path(sdata_path) @@ -146,8 +146,8 @@ process makeImagePatches { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.4' + : 'docker.io/quentinblampey/sopa:2.0.4'}" input: tuple val(meta), path(sdata_path) @@ -168,8 +168,8 @@ process makeTranscriptPatches { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.4' + : 'docker.io/quentinblampey/sopa:2.0.4'}" input: tuple val(meta), path(sdata_path) @@ -189,8 +189,8 @@ process aggregate { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.4' + : 'docker.io/quentinblampey/sopa:2.0.4'}" input: tuple val(meta), path(sdata_path) @@ -211,8 +211,8 @@ process explorer_raw { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.4' + : 'docker.io/quentinblampey/sopa:2.0.4'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -235,8 +235,8 @@ process explorer { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.4' + : 'docker.io/quentinblampey/sopa:2.0.4'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -262,8 +262,8 @@ process report { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3' - : 'docker.io/quentinblampey/sopa:2.0.3'}" + ? 'docker://quentinblampey/sopa:2.0.4' + : 'docker.io/quentinblampey/sopa:2.0.4'}" publishDir "${params.outdir}", mode: params.publish_dir_mode From 0c25deb283777ba73722ffb420412cd4792ee396 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 23 Apr 2025 11:57:07 +0200 Subject: [PATCH 079/227] move to sopa_config --- .gitignore | 3 ++- {toy => sopa_config}/baysor.yaml | 0 {toy => sopa_config}/baysor_overlaps.yaml | 0 {toy => sopa_config}/baysor_vizgen.yaml | 0 {toy => sopa_config}/cellpose.yaml | 0 {toy => sopa_config}/cellpose_baysor.yaml | 0 {toy => sopa_config}/cellpose_comseg.yaml | 0 {toy => sopa_config}/comseg.yaml | 0 {toy => sopa_config}/data | 0 {toy => sopa_config}/data2 | 0 {toy => sopa_config}/proseg.yaml | 0 {toy => sopa_config}/samplesheet.csv | 0 {toy => sopa_config}/samplesheet_fastq.csv | 0 {toy => sopa_config}/samplesheet_vhd.csv | 0 {toy => sopa_config}/tissue_cellpose.yaml | 0 {toy => sopa_config}/vhd_stardist.yaml | 0 sopa_config/xenium_proseg.yaml | 22 ++++++++++++++++++++++ 17 files changed, 24 insertions(+), 1 deletion(-) rename {toy => sopa_config}/baysor.yaml (100%) rename {toy => sopa_config}/baysor_overlaps.yaml (100%) rename {toy => sopa_config}/baysor_vizgen.yaml (100%) rename {toy => sopa_config}/cellpose.yaml (100%) rename {toy => sopa_config}/cellpose_baysor.yaml (100%) rename {toy => sopa_config}/cellpose_comseg.yaml (100%) rename {toy => sopa_config}/comseg.yaml (100%) rename {toy => sopa_config}/data (100%) rename {toy => sopa_config}/data2 (100%) rename {toy => sopa_config}/proseg.yaml (100%) rename {toy => sopa_config}/samplesheet.csv (100%) rename {toy => sopa_config}/samplesheet_fastq.csv (100%) rename {toy => sopa_config}/samplesheet_vhd.csv (100%) rename {toy => sopa_config}/tissue_cellpose.yaml (100%) rename {toy => sopa_config}/vhd_stardist.yaml (100%) create mode 100644 sopa_config/xenium_proseg.yaml diff --git a/.gitignore b/.gitignore index 42eba98..ae18b0d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ testing/ testing* *.pyc null/ -tests \ No newline at end of file +tests +sandbox \ No newline at end of file diff --git a/toy/baysor.yaml b/sopa_config/baysor.yaml similarity index 100% rename from toy/baysor.yaml rename to sopa_config/baysor.yaml diff --git a/toy/baysor_overlaps.yaml b/sopa_config/baysor_overlaps.yaml similarity index 100% rename from toy/baysor_overlaps.yaml rename to sopa_config/baysor_overlaps.yaml diff --git a/toy/baysor_vizgen.yaml b/sopa_config/baysor_vizgen.yaml similarity index 100% rename from toy/baysor_vizgen.yaml rename to sopa_config/baysor_vizgen.yaml diff --git a/toy/cellpose.yaml b/sopa_config/cellpose.yaml similarity index 100% rename from toy/cellpose.yaml rename to sopa_config/cellpose.yaml diff --git a/toy/cellpose_baysor.yaml b/sopa_config/cellpose_baysor.yaml similarity index 100% rename from toy/cellpose_baysor.yaml rename to sopa_config/cellpose_baysor.yaml diff --git a/toy/cellpose_comseg.yaml b/sopa_config/cellpose_comseg.yaml similarity index 100% rename from toy/cellpose_comseg.yaml rename to sopa_config/cellpose_comseg.yaml diff --git a/toy/comseg.yaml b/sopa_config/comseg.yaml similarity index 100% rename from toy/comseg.yaml rename to sopa_config/comseg.yaml diff --git a/toy/data b/sopa_config/data similarity index 100% rename from toy/data rename to sopa_config/data diff --git a/toy/data2 b/sopa_config/data2 similarity index 100% rename from toy/data2 rename to sopa_config/data2 diff --git a/toy/proseg.yaml b/sopa_config/proseg.yaml similarity index 100% rename from toy/proseg.yaml rename to sopa_config/proseg.yaml diff --git a/toy/samplesheet.csv b/sopa_config/samplesheet.csv similarity index 100% rename from toy/samplesheet.csv rename to sopa_config/samplesheet.csv diff --git a/toy/samplesheet_fastq.csv b/sopa_config/samplesheet_fastq.csv similarity index 100% rename from toy/samplesheet_fastq.csv rename to sopa_config/samplesheet_fastq.csv diff --git a/toy/samplesheet_vhd.csv b/sopa_config/samplesheet_vhd.csv similarity index 100% rename from toy/samplesheet_vhd.csv rename to sopa_config/samplesheet_vhd.csv diff --git a/toy/tissue_cellpose.yaml b/sopa_config/tissue_cellpose.yaml similarity index 100% rename from toy/tissue_cellpose.yaml rename to sopa_config/tissue_cellpose.yaml diff --git a/toy/vhd_stardist.yaml b/sopa_config/vhd_stardist.yaml similarity index 100% rename from toy/vhd_stardist.yaml rename to sopa_config/vhd_stardist.yaml diff --git a/sopa_config/xenium_proseg.yaml b/sopa_config/xenium_proseg.yaml new file mode 100644 index 0000000..6097bab --- /dev/null +++ b/sopa_config/xenium_proseg.yaml @@ -0,0 +1,22 @@ +# Using the 10X Genomics multi-channel segmentation as a prior for Proseg. + +# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml +read: + technology: xenium + +patchify: + patch_width_microns: -1 + patch_overlap_microns: 20 + +segmentation: + proseg: + prior_shapes_key: cell_id # this allows to use the prior segmentation performed by 10X Genomics + unassigned_value: UNASSIGNED + +aggregate: + average_intensities: true + min_transcripts: 10 # [optional] cells whose transcript count is below that this threshold are filtered + +explorer: + gene_column: "feature_name" + ram_threshold_gb: 4 From 7c469894c6e388296916c804e5cc7bd9564b3fa3 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Apr 2025 11:40:47 +0200 Subject: [PATCH 080/227] use docker images sopa:2.0.6 --- subworkflows/local/baysor/main.nf | 8 ++++---- subworkflows/local/cellpose/main.nf | 8 ++++---- subworkflows/local/proseg/main.nf | 4 ++-- subworkflows/local/stardist/main.nf | 8 ++++---- workflows/sopa.nf | 32 ++++++++++++++--------------- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index cb71566..92e9acd 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -27,8 +27,8 @@ process patchSegmentationBaysor { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3-baysor' - : 'docker.io/quentinblampey/sopa:2.0.3-baysor'}" + ? 'docker://quentinblampey/sopa:2.0.6-baysor' + : 'docker.io/quentinblampey/sopa:2.0.6-baysor'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -51,8 +51,8 @@ process resolveBaysor { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3-baysor' - : 'docker.io/quentinblampey/sopa:2.0.3-baysor'}" + ? 'docker://quentinblampey/sopa:2.0.6-baysor' + : 'docker.io/quentinblampey/sopa:2.0.6-baysor'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index 0c609e0..024e2c0 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -27,8 +27,8 @@ process patchSegmentationCellpose { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.3-cellpose' - : 'docker.io/quentinblampey/sopa:2.0.3-cellpose'}" + ? 'docker://quentinblampey/sopa:2.0.6-cellpose' + : 'docker.io/quentinblampey/sopa:2.0.6-cellpose'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -47,8 +47,8 @@ process resolveCellpose { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.4' - : 'docker.io/quentinblampey/sopa:2.0.4'}" + ? 'docker://quentinblampey/sopa:2.0.6' + : 'docker.io/quentinblampey/sopa:2.0.6'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index c950a1a..ceef276 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -20,8 +20,8 @@ process patchSegmentationProseg { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.4-proseg' - : 'docker.io/quentinblampey/sopa:2.0.4-proseg'}" + ? 'docker://quentinblampey/sopa:2.0.6-proseg' + : 'docker.io/quentinblampey/sopa:2.0.6-proseg'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/stardist/main.nf b/subworkflows/local/stardist/main.nf index a1b8f67..3ae8e42 100644 --- a/subworkflows/local/stardist/main.nf +++ b/subworkflows/local/stardist/main.nf @@ -27,8 +27,8 @@ process patchSegmentationStardist { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.4-stardist' - : 'docker.io/quentinblampey/sopa:2.0.4-stardist'}" + ? 'docker://quentinblampey/sopa:2.0.6-stardist' + : 'docker.io/quentinblampey/sopa:2.0.6-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -47,8 +47,8 @@ process resolveStardist { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.4' - : 'docker.io/quentinblampey/sopa:2.0.4'}" + ? 'docker://quentinblampey/sopa:2.0.6' + : 'docker.io/quentinblampey/sopa:2.0.6'}" input: tuple val(meta), path(sdata_path) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index cc5a07f..cf43655 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -103,8 +103,8 @@ process toSpatialData { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.4' - : 'docker.io/quentinblampey/sopa:2.0.4'}" + ? 'docker://quentinblampey/sopa:2.0.6' + : 'docker.io/quentinblampey/sopa:2.0.6'}" input: tuple val(meta), path(input_files) @@ -124,8 +124,8 @@ process tissueSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.4' - : 'docker.io/quentinblampey/sopa:2.0.4'}" + ? 'docker://quentinblampey/sopa:2.0.6' + : 'docker.io/quentinblampey/sopa:2.0.6'}" input: tuple val(meta), path(sdata_path) @@ -146,8 +146,8 @@ process makeImagePatches { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.4' - : 'docker.io/quentinblampey/sopa:2.0.4'}" + ? 'docker://quentinblampey/sopa:2.0.6' + : 'docker.io/quentinblampey/sopa:2.0.6'}" input: tuple val(meta), path(sdata_path) @@ -168,8 +168,8 @@ process makeTranscriptPatches { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.4' - : 'docker.io/quentinblampey/sopa:2.0.4'}" + ? 'docker://quentinblampey/sopa:2.0.6' + : 'docker.io/quentinblampey/sopa:2.0.6'}" input: tuple val(meta), path(sdata_path) @@ -189,8 +189,8 @@ process aggregate { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.4' - : 'docker.io/quentinblampey/sopa:2.0.4'}" + ? 'docker://quentinblampey/sopa:2.0.6' + : 'docker.io/quentinblampey/sopa:2.0.6'}" input: tuple val(meta), path(sdata_path) @@ -211,8 +211,8 @@ process explorer_raw { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.4' - : 'docker.io/quentinblampey/sopa:2.0.4'}" + ? 'docker://quentinblampey/sopa:2.0.6' + : 'docker.io/quentinblampey/sopa:2.0.6'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -235,8 +235,8 @@ process explorer { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.4' - : 'docker.io/quentinblampey/sopa:2.0.4'}" + ? 'docker://quentinblampey/sopa:2.0.6' + : 'docker.io/quentinblampey/sopa:2.0.6'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -262,8 +262,8 @@ process report { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.4' - : 'docker.io/quentinblampey/sopa:2.0.4'}" + ? 'docker://quentinblampey/sopa:2.0.6' + : 'docker.io/quentinblampey/sopa:2.0.6'}" publishDir "${params.outdir}", mode: params.publish_dir_mode From 92904c10d1e2f78b5c9ca68fdf42e656c294f581 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Apr 2025 16:59:21 +0200 Subject: [PATCH 081/227] gitignore samplesheets --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ae18b0d..653aaec 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ testing* *.pyc null/ tests -sandbox \ No newline at end of file +sandbox +samplesheets \ No newline at end of file From 765a83bed2051ac8c96e56b2c21ef1dbe14c173b Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 15 May 2025 17:16:12 +0200 Subject: [PATCH 082/227] cleanup to move to nf-core org --- .gitignore | 1 - conf/test.config | 4 +- conf/test_full.config | 4 +- modules/local/utils.nf | 2 - .../spaceranger/count/tests/main.nf.test | 228 ++++++++++++++++++ .../spaceranger/count/tests/main.nf.test.snap | 96 ++++++++ .../spaceranger/count/tests/nextflow.config | 5 + modules/nf-core/untar/tests/main.nf.test | 85 +++++++ modules/nf-core/untar/tests/main.nf.test.snap | 158 ++++++++++++ sopa_config/data | 0 sopa_config/data2 | 0 sopa_config/samplesheet.csv | 2 - sopa_config/samplesheet_vhd.csv | 2 - {sopa_config => tests/config}/baysor.yaml | 0 .../config}/baysor_overlaps.yaml | 0 .../config}/baysor_vizgen.yaml | 0 {sopa_config => tests/config}/cellpose.yaml | 0 .../config}/cellpose_baysor.yaml | 0 .../config}/cellpose_comseg.yaml | 0 {sopa_config => tests/config}/comseg.yaml | 0 {sopa_config => tests/config}/proseg.yaml | 0 .../config}/tissue_cellpose.yaml | 0 .../config}/vhd_stardist.yaml | 0 .../config}/xenium_proseg.yaml | 0 tests/sample1 | 2 + tests/sample2 | 2 + tests/samplesheet.csv | 2 + {sopa_config => tests}/samplesheet_fastq.csv | 4 +- 28 files changed, 584 insertions(+), 13 deletions(-) create mode 100644 modules/nf-core/spaceranger/count/tests/main.nf.test create mode 100644 modules/nf-core/spaceranger/count/tests/main.nf.test.snap create mode 100644 modules/nf-core/spaceranger/count/tests/nextflow.config create mode 100644 modules/nf-core/untar/tests/main.nf.test create mode 100644 modules/nf-core/untar/tests/main.nf.test.snap delete mode 100644 sopa_config/data delete mode 100644 sopa_config/data2 delete mode 100644 sopa_config/samplesheet.csv delete mode 100644 sopa_config/samplesheet_vhd.csv rename {sopa_config => tests/config}/baysor.yaml (100%) rename {sopa_config => tests/config}/baysor_overlaps.yaml (100%) rename {sopa_config => tests/config}/baysor_vizgen.yaml (100%) rename {sopa_config => tests/config}/cellpose.yaml (100%) rename {sopa_config => tests/config}/cellpose_baysor.yaml (100%) rename {sopa_config => tests/config}/cellpose_comseg.yaml (100%) rename {sopa_config => tests/config}/comseg.yaml (100%) rename {sopa_config => tests/config}/proseg.yaml (100%) rename {sopa_config => tests/config}/tissue_cellpose.yaml (100%) rename {sopa_config => tests/config}/vhd_stardist.yaml (100%) rename {sopa_config => tests/config}/xenium_proseg.yaml (100%) create mode 100644 tests/sample1 create mode 100644 tests/sample2 create mode 100644 tests/samplesheet.csv rename {sopa_config => tests}/samplesheet_fastq.csv (65%) diff --git a/.gitignore b/.gitignore index 653aaec..df30ed1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,5 @@ testing/ testing* *.pyc null/ -tests sandbox samplesheets \ No newline at end of file diff --git a/conf/test.config b/conf/test.config index ea129ca..a8fab29 100644 --- a/conf/test.config +++ b/conf/test.config @@ -25,6 +25,6 @@ params { // 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 - input = "${baseDir}/toy/samplesheet.csv" - configfile = "${baseDir}/toy/baysor.yaml" + input = "${baseDir}/tests/samplesheet.csv" + configfile = "${baseDir}/tests/config/cellpose.yaml" } diff --git a/conf/test_full.config b/conf/test_full.config index 8b14459..e095497 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -17,6 +17,6 @@ params { // Input data for full size test // TODO nf-core: Specify the paths to your full test data ( on nf-core/test-datasets or directly in repositories, e.g. SRA) // TODO nf-core: Give any required params for the test so that command line flags are not needed - input = "${baseDir}/toy/samplesheet.csv" - configfile = "${baseDir}/toy/cellpose.yaml" + input = "${baseDir}/tests/samplesheet.csv" + configfile = "${baseDir}/tests/config/baysor.yaml" } diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 8cfe592..d5e24e6 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -61,8 +61,6 @@ def ArgsReaderCLI(Map args, Map meta) { } } - println("ArgsReaderCLI: ${args}") - return ArgsCLI(args) } diff --git a/modules/nf-core/spaceranger/count/tests/main.nf.test b/modules/nf-core/spaceranger/count/tests/main.nf.test new file mode 100644 index 0000000..49a9d5f --- /dev/null +++ b/modules/nf-core/spaceranger/count/tests/main.nf.test @@ -0,0 +1,228 @@ +nextflow_process { + + name "Test Process SPACERANGER_COUNT" + script "../main.nf" + config "./nextflow.config" + process "SPACERANGER_COUNT" + + tag "modules" + tag "modules_nfcore" + tag "spaceranger" + tag "spaceranger/count" + tag "spaceranger/mkgtf" + tag "spaceranger/mkref" + + test("spaceranger v1 - homo_sapiens - fasta - gtf - fastq - tif - csv") { + + setup { + run("SPACERANGER_MKGTF") { + script "../../mkgtf/main.nf" + process { + """ + input[0] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) + """ + } + } + } + + setup { + run("SPACERANGER_MKREF") { + script "../../mkref/main.nf" + process { + """ + input[0] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + input[1] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) + input[2] = 'homo_sapiens_chr22_reference' + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ + id: 'Visium_FFPE_Human_Ovarian_Cancer', + slide: 'V10L13-020', + area: 'D1' + ], // Meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-ovarian-cancer-1-standard_v1_ffpe/Visium_FFPE_Human_Ovarian_Cancer_S1_L001_R1_001.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-ovarian-cancer-1-standard_v1_ffpe/Visium_FFPE_Human_Ovarian_Cancer_S1_L001_R2_001.fastq.gz', checkIfExists: true) + ], // Reads + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-ovarian-cancer-1-standard_v1_ffpe/Visium_FFPE_Human_Ovarian_Cancer_image.jpg', checkIfExists: true), // Image + [], // Cytaimage + [], // Darkimage + [], // Colorizedimage + [], // Manual alignment (default: automatic alignment) + [], // Slide specification (default: automatic download) + ] + input[1] = SPACERANGER_MKREF.out.reference // Reference + input[2] = [] // Probeset (default: use the one included with Space Ranger) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.versions.get(0)).yaml, + process.out.outs.get(0).get(1).findAll { file(it).name !in [ + 'web_summary.html', + 'scalefactors_json.json', + 'barcodes.tsv.gz', + 'features.tsv.gz', + 'matrix.mtx.gz' + ]} + ).match() + }, + { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'web_summary.html' }).exists() }, + { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'scalefactors_json.json' }).exists() }, + { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'barcodes.tsv.gz' }).exists() }, + { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'features.tsv.gz' }).exists() }, + { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'matrix.mtx.gz' }).exists() } + ) + } + } + + test("spaceranger v1 (stub) - homo_sapiens - fasta - gtf - fastq - tif - csv") { + + setup { + run("SPACERANGER_MKGTF") { + script "../../mkgtf/main.nf" + process { + """ + input[0] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) + """ + } + } + } + + setup { + run("SPACERANGER_MKREF") { + script "../../mkref/main.nf" + process { + """ + input[0] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + input[1] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) + input[2] = 'homo_sapiens_chr22_reference' + """ + } + } + } + + options "-stub" + + when { + process { + """ + input[0] = [ + [ + id: 'Visium_FFPE_Human_Ovarian_Cancer', + slide: 'V10L13-020', + area: 'D1' + ], // Meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-ovarian-cancer-1-standard_v1_ffpe/Visium_FFPE_Human_Ovarian_Cancer_S1_L001_R1_001.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-ovarian-cancer-1-standard_v1_ffpe/Visium_FFPE_Human_Ovarian_Cancer_S1_L001_R2_001.fastq.gz', checkIfExists: true) + ], // Reads + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-ovarian-cancer-1-standard_v1_ffpe/Visium_FFPE_Human_Ovarian_Cancer_image.jpg', checkIfExists: true), // Image + [], // Cytaimage + [], // Darkimage + [], // Colorizedimage + [], // Manual alignment (default: automatic alignment) + [], // Slide specification (default: automatic download) + ] + input[1] = SPACERANGER_MKREF.out.reference // Reference + input[2] = [] // Probeset (default: use the one included with Space Ranger) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(path(process.out.versions.get(0)).yaml).match() }, + ) + } + } + + test("spaceranger v2 - homo_sapiens - fasta - gtf - fastq - tif - csv") { + setup { + run("SPACERANGER_MKGTF") { + script "../../mkgtf/main.nf" + process { + """ + input[0] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) + """ + } + } + } + + setup { + run("SPACERANGER_MKREF") { + script "../../mkref/main.nf" + process { + """ + input[0] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + input[1] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) + input[2] = 'homo_sapiens_chr22_reference' + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ + id: 'CytAssist_11mm_FFPE_Human_Glioblastoma_2', + slide: 'V52Y10-317', + area: 'B1' + ], // Meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_2_S1_L001_R1_001.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_2_S1_L001_R2_001.fastq.gz', checkIfExists: true) + ], // Reads + [], // Image + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_image.tif', checkIfExists: true), // Cytaimage + [], // Darkimage + [], // Colorizedimage + [], // Manual alignment (default: automatic alignment) + file('https://s3.us-west-2.amazonaws.com/10x.spatial-slides/gpr/V52Y10/V52Y10-317.gpr') // Slide specification (default: automatic download) + ] + input[1] = SPACERANGER_MKREF.out.reference // Reference + input[2] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_probe_set.csv', checkIfExists: true) // Probeset (default: use the one included with Space Ranger) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.versions.get(0)).yaml, + process.out.outs.get(0).get(1).findAll { file(it).name !in [ + 'web_summary.html', + 'scalefactors_json.json', + 'molecule_info.h5', + 'barcodes.tsv.gz', + 'features.tsv.gz', + 'matrix.mtx.gz', + 'cloupe.cloupe' + ]} + ).match() + }, + { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'web_summary.html' }).exists() }, + { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'scalefactors_json.json' }).exists() }, + { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'molecule_info.h5' }).exists() }, + { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'barcodes.tsv.gz' }).exists() }, + { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'features.tsv.gz' }).exists() }, + { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'matrix.mtx.gz' }).exists() } + ) + } + } +} \ No newline at end of file diff --git a/modules/nf-core/spaceranger/count/tests/main.nf.test.snap b/modules/nf-core/spaceranger/count/tests/main.nf.test.snap new file mode 100644 index 0000000..7a49d45 --- /dev/null +++ b/modules/nf-core/spaceranger/count/tests/main.nf.test.snap @@ -0,0 +1,96 @@ +{ + "spaceranger v1 (stub) - homo_sapiens - fasta - gtf - fastq - tif - csv": { + "content": [ + { + "SPACERANGER_COUNT": { + "spaceranger": "3.1.2" + } + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-26T01:48:31.348979531" + }, + "spaceranger v2 - homo_sapiens - fasta - gtf - fastq - tif - csv": { + "content": [ + { + "SPACERANGER_COUNT": { + "spaceranger": "3.1.2" + } + }, + [ + "clusters.csv:md5,221a4554e62ea94b0df8dbf637d2c13c", + "clusters.csv:md5,53ee76645943b5562392aac51d2d9f3f", + "clusters.csv:md5,b791359469683ad19cdb8d1af3de5705", + "clusters.csv:md5,9a4f9148e0e834c1127bf8393ece6330", + "clusters.csv:md5,c11bcc64f870469ab2f136d9272a7a6d", + "clusters.csv:md5,488846bbb469365e199928c7a440320a", + "clusters.csv:md5,5941f7e847d35a4f06d3631e21d2eb9d", + "clusters.csv:md5,d244d405c32766339d2b7a3fa8bf8cee", + "clusters.csv:md5,981386408cd953548994c31253e787de", + "clusters.csv:md5,24c4f13449e5362fcbcd41b9ff413992", + "differential_expression.csv:md5,589c1bd4529f092bb1d332e7da561dad", + "differential_expression.csv:md5,d9d978b398b33ac9687b44531909e0cd", + "differential_expression.csv:md5,4edbc893280f9d03c3de00a503e86f8c", + "differential_expression.csv:md5,316181d501c495384016227309856b09", + "differential_expression.csv:md5,dae49941396609fb08df13b82fe89151", + "differential_expression.csv:md5,4a13ae44c8454dbcb0298eb63df8b8e8", + "differential_expression.csv:md5,eeb02c4afe1f49d5502fb024b25b2c38", + "differential_expression.csv:md5,9a456828fe5d762e6e07383da5c2791d", + "differential_expression.csv:md5,bcbd1504976824e9f4d20a8dd36e2a1f", + "differential_expression.csv:md5,3ad93fc4d52950cfede885dc58cd2823", + "components.csv:md5,811a32dce6c795e958dc4bc635ee53be", + "dispersion.csv:md5,64c2e57ef0ca9a80cce8b952c81b62f5", + "features_selected.csv:md5,bd0c0a20b0b0009df796e8a755d028c1", + "projection.csv:md5,e530c925a185965514fa82f4da83fa81", + "variance.csv:md5,4159711ab5d64e97737fad9d75d945b3", + "projection.csv:md5,ce729f7e237df4570ac3e4a79251df24", + "projection.csv:md5,fa7bdefa8424b233fe6461129ab76d57", + "filtered_feature_bc_matrix.h5:md5,f625d7e2c063c8c079ccc35a853b356d", + "metrics_summary.csv:md5,5ece84f5f8e08839749b1c8f2bff6701", + "probe_set.csv:md5,5bfb8f12319be1b2b6c14142537c3804", + "raw_feature_bc_matrix.h5:md5,90575715eb252f0b652c9d36a1f5628e", + "raw_probe_bc_matrix.h5:md5,8ab08437814506f98e3f10107cfc38ac", + "aligned_fiducials.jpg:md5,51dcc3a32d3d5ca4704f664c8ede81ef", + "cytassist_image.tiff:md5,0fb04a55e5658f4d158d986a334b034d", + "detected_tissue_image.jpg:md5,11c9fa90913b5c6e93cecdb8f53d58db", + "spatial_enrichment.csv:md5,4379bc4fef891b45ff9264ee8c408bd0", + "tissue_hires_image.png:md5,834706fff299024fab48e6366afc9cb9", + "tissue_lowres_image.png:md5,8c1fcb378f7f886301f49ffc4f84360a", + "tissue_positions.csv:md5,930aeb2b790032337d91dd27cc70f135" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-26T01:58:16.555517048" + }, + "spaceranger v1 - homo_sapiens - fasta - gtf - fastq - tif - csv": { + "content": [ + { + "SPACERANGER_COUNT": { + "spaceranger": "3.1.2" + } + }, + [ + "filtered_feature_bc_matrix.h5:md5,a756f6dda550f52f9fb3e347207a2c6c", + "metrics_summary.csv:md5,38774fc5f54873d711b4898a2dd50e72", + "molecule_info.h5:md5,9e6393dbbccdfe58edf9e92181261f88", + "raw_feature_bc_matrix.h5:md5,860702876f936f89fdcec2b5f599a7d2", + "aligned_fiducials.jpg:md5,f6217ddd707bb189e665f56b130c3da8", + "detected_tissue_image.jpg:md5,c1c7e8741701a576c1ec103c1aaf98ea", + "tissue_hires_image.png:md5,d91f8f176ae35ab824ede87117ac0889", + "tissue_lowres_image.png:md5,475a04208d193191c84d7a3b5d4eb287", + "tissue_positions.csv:md5,7f9cb407b3dd69726a12967b979a5624" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-26T01:48:13.569651476" + } +} \ No newline at end of file diff --git a/modules/nf-core/spaceranger/count/tests/nextflow.config b/modules/nf-core/spaceranger/count/tests/nextflow.config new file mode 100644 index 0000000..fe9d61a --- /dev/null +++ b/modules/nf-core/spaceranger/count/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: SPACERANGER_COUNT { + ext.args = '--create-bam false' + } +} diff --git a/modules/nf-core/untar/tests/main.nf.test b/modules/nf-core/untar/tests/main.nf.test new file mode 100644 index 0000000..c957517 --- /dev/null +++ b/modules/nf-core/untar/tests/main.nf.test @@ -0,0 +1,85 @@ +nextflow_process { + + name "Test Process UNTAR" + script "../main.nf" + process "UNTAR" + tag "modules" + tag "modules_nfcore" + tag "untar" + + test("test_untar") { + + when { + process { + """ + input[0] = [ [], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/db/kraken2.tar.gz', checkIfExists: true) ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() }, + ) + } + } + + test("test_untar_onlyfiles") { + + when { + process { + """ + input[0] = [ [], file(params.modules_testdata_base_path + 'generic/tar/hello.tar.gz', checkIfExists: true) ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() }, + ) + } + } + + test("test_untar - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ [], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/db/kraken2.tar.gz', checkIfExists: true) ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() }, + ) + } + } + + test("test_untar_onlyfiles - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ [], file(params.modules_testdata_base_path + 'generic/tar/hello.tar.gz', checkIfExists: true) ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() }, + ) + } + } +} diff --git a/modules/nf-core/untar/tests/main.nf.test.snap b/modules/nf-core/untar/tests/main.nf.test.snap new file mode 100644 index 0000000..ceb91b7 --- /dev/null +++ b/modules/nf-core/untar/tests/main.nf.test.snap @@ -0,0 +1,158 @@ +{ + "test_untar_onlyfiles": { + "content": [ + { + "0": [ + [ + [ + + ], + [ + "hello.txt:md5,e59ff97941044f85df5297e1c302d260" + ] + ] + ], + "1": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ], + "untar": [ + [ + [ + + ], + [ + "hello.txt:md5,e59ff97941044f85df5297e1c302d260" + ] + ] + ], + "versions": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-10T12:04:28.231047" + }, + "test_untar_onlyfiles - stub": { + "content": [ + { + "0": [ + [ + [ + + ], + [ + "hello.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ], + "untar": [ + [ + [ + + ], + [ + "hello.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-10T12:04:45.773103" + }, + "test_untar - stub": { + "content": [ + { + "0": [ + [ + [ + + ], + [ + "hash.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", + "opts.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", + "taxo.k2d:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ], + "untar": [ + [ + [ + + ], + [ + "hash.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", + "opts.k2d:md5,d41d8cd98f00b204e9800998ecf8427e", + "taxo.k2d:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-10T12:04:36.777441" + }, + "test_untar": { + "content": [ + { + "0": [ + [ + [ + + ], + [ + "hash.k2d:md5,8b8598468f54a7087c203ad0190555d9", + "opts.k2d:md5,a033d00cf6759407010b21700938f543", + "taxo.k2d:md5,094d5891cdccf2f1468088855c214b2c" + ] + ] + ], + "1": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ], + "untar": [ + [ + [ + + ], + [ + "hash.k2d:md5,8b8598468f54a7087c203ad0190555d9", + "opts.k2d:md5,a033d00cf6759407010b21700938f543", + "taxo.k2d:md5,094d5891cdccf2f1468088855c214b2c" + ] + ] + ], + "versions": [ + "versions.yml:md5,6063247258c56fd271d076bb04dd7536" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-10T12:04:19.377674" + } +} \ No newline at end of file diff --git a/sopa_config/data b/sopa_config/data deleted file mode 100644 index e69de29..0000000 diff --git a/sopa_config/data2 b/sopa_config/data2 deleted file mode 100644 index e69de29..0000000 diff --git a/sopa_config/samplesheet.csv b/sopa_config/samplesheet.csv deleted file mode 100644 index 9a0db1b..0000000 --- a/sopa_config/samplesheet.csv +++ /dev/null @@ -1,2 +0,0 @@ -data_path -toy/data diff --git a/sopa_config/samplesheet_vhd.csv b/sopa_config/samplesheet_vhd.csv deleted file mode 100644 index 9f28dd5..0000000 --- a/sopa_config/samplesheet_vhd.csv +++ /dev/null @@ -1,2 +0,0 @@ -sample,fastq_dir -toy/data,fastq diff --git a/sopa_config/baysor.yaml b/tests/config/baysor.yaml similarity index 100% rename from sopa_config/baysor.yaml rename to tests/config/baysor.yaml diff --git a/sopa_config/baysor_overlaps.yaml b/tests/config/baysor_overlaps.yaml similarity index 100% rename from sopa_config/baysor_overlaps.yaml rename to tests/config/baysor_overlaps.yaml diff --git a/sopa_config/baysor_vizgen.yaml b/tests/config/baysor_vizgen.yaml similarity index 100% rename from sopa_config/baysor_vizgen.yaml rename to tests/config/baysor_vizgen.yaml diff --git a/sopa_config/cellpose.yaml b/tests/config/cellpose.yaml similarity index 100% rename from sopa_config/cellpose.yaml rename to tests/config/cellpose.yaml diff --git a/sopa_config/cellpose_baysor.yaml b/tests/config/cellpose_baysor.yaml similarity index 100% rename from sopa_config/cellpose_baysor.yaml rename to tests/config/cellpose_baysor.yaml diff --git a/sopa_config/cellpose_comseg.yaml b/tests/config/cellpose_comseg.yaml similarity index 100% rename from sopa_config/cellpose_comseg.yaml rename to tests/config/cellpose_comseg.yaml diff --git a/sopa_config/comseg.yaml b/tests/config/comseg.yaml similarity index 100% rename from sopa_config/comseg.yaml rename to tests/config/comseg.yaml diff --git a/sopa_config/proseg.yaml b/tests/config/proseg.yaml similarity index 100% rename from sopa_config/proseg.yaml rename to tests/config/proseg.yaml diff --git a/sopa_config/tissue_cellpose.yaml b/tests/config/tissue_cellpose.yaml similarity index 100% rename from sopa_config/tissue_cellpose.yaml rename to tests/config/tissue_cellpose.yaml diff --git a/sopa_config/vhd_stardist.yaml b/tests/config/vhd_stardist.yaml similarity index 100% rename from sopa_config/vhd_stardist.yaml rename to tests/config/vhd_stardist.yaml diff --git a/sopa_config/xenium_proseg.yaml b/tests/config/xenium_proseg.yaml similarity index 100% rename from sopa_config/xenium_proseg.yaml rename to tests/config/xenium_proseg.yaml diff --git a/tests/sample1 b/tests/sample1 new file mode 100644 index 0000000..0704b24 --- /dev/null +++ b/tests/sample1 @@ -0,0 +1,2 @@ +This is a fake sample +Tests datasets are generated on the fly by Sopa \ No newline at end of file diff --git a/tests/sample2 b/tests/sample2 new file mode 100644 index 0000000..0704b24 --- /dev/null +++ b/tests/sample2 @@ -0,0 +1,2 @@ +This is a fake sample +Tests datasets are generated on the fly by Sopa \ No newline at end of file diff --git a/tests/samplesheet.csv b/tests/samplesheet.csv new file mode 100644 index 0000000..10e7f31 --- /dev/null +++ b/tests/samplesheet.csv @@ -0,0 +1,2 @@ +data_path +tests/sample1 diff --git a/sopa_config/samplesheet_fastq.csv b/tests/samplesheet_fastq.csv similarity index 65% rename from sopa_config/samplesheet_fastq.csv rename to tests/samplesheet_fastq.csv index cbe6632..c5d0348 100644 --- a/sopa_config/samplesheet_fastq.csv +++ b/tests/samplesheet_fastq.csv @@ -1,2 +1,2 @@ -sample,fastq_dir,cytaimage,slide,area,manual_alignment,slidefile -CytAssist_11mm_FFPE_Human_Glioblastoma_2,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/fastq_dir.tar.gz,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_image.tif,V52Y10-317,B1,,https://s3.us-west-2.amazonaws.com/10x.spatial-slides/gpr/V52Y10/V52Y10-317.gpr \ No newline at end of file +sample,fastq_dir,cytaimage,slide,area +CytAssist_11mm_FFPE_Human_Glioblastoma_2,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/fastq_dir.tar.gz,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_image.tif,V52Y10-317,B1 \ No newline at end of file From 2fb6b31c92251e8608d166b772e73028b535d6e3 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 19 Jun 2025 15:47:27 +0200 Subject: [PATCH 083/227] remove no space pattern --- assets/schema_input.json | 9 --------- 1 file changed, 9 deletions(-) diff --git a/assets/schema_input.json b/assets/schema_input.json index 5dea935..45fc6b8 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -17,14 +17,12 @@ }, "data_path": { "type": "string", - "pattern": "^\\S+$", "format": "path", "exists": true, "errorMessage": "Data path must exist" }, "fastq_dir": { "type": "string", - "pattern": "^\\S+$", "format": "path", "exists": true, "errorMessage": "Path to the fastq directory must exist", @@ -34,7 +32,6 @@ }, "cytaimage": { "type": "string", - "pattern": "^\\S+$", "format": "path", "exists": true, "errorMessage": "Path to the cytaimage file must exist", @@ -44,7 +41,6 @@ }, "colorizedimage": { "type": "string", - "pattern": "^\\S+$", "format": "path", "exists": true, "errorMessage": "Path to the colorizedimage file must exist", @@ -54,7 +50,6 @@ }, "darkimage": { "type": "string", - "pattern": "^\\S+$", "format": "path", "exists": true, "errorMessage": "Path to the darkimage file must exist", @@ -64,7 +59,6 @@ }, "image": { "type": "string", - "pattern": "^\\S+$", "format": "path", "exists": true, "errorMessage": "Path to the image must exist", @@ -74,7 +68,6 @@ }, "slide": { "type": "string", - "pattern": "^\\S+$", "errorMessage": "Slide name cannot contain spaces", "meta": [ "slide" @@ -90,7 +83,6 @@ }, "manual_alignment": { "type": "string", - "pattern": "^\\S+$", "format": "path", "exists": true, "errorMessage": "Path to the manual_alignment file must exist", @@ -100,7 +92,6 @@ }, "slidefile": { "type": "string", - "pattern": "^\\S+$", "format": "path", "exists": true, "errorMessage": "Path to the slidefile must exist", From 854fcbf1563a864aeeee38db551d03da36006b39 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 19 Jun 2025 16:03:42 +0200 Subject: [PATCH 084/227] revert remove spaces --- assets/schema_input.json | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/assets/schema_input.json b/assets/schema_input.json index 45fc6b8..eca9c9e 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -17,57 +17,64 @@ }, "data_path": { "type": "string", + "pattern": "^\\S+$", "format": "path", "exists": true, - "errorMessage": "Data path must exist" + "errorMessage": "Data path must exist and not contain spaces" }, "fastq_dir": { "type": "string", + "pattern": "^\\S+$", "format": "path", "exists": true, - "errorMessage": "Path to the fastq directory must exist", + "errorMessage": "Path to the fastq directory must exist and not contain spaces", "meta": [ "fastq_dir" ] }, "cytaimage": { "type": "string", + "pattern": "^\\S+$", "format": "path", "exists": true, - "errorMessage": "Path to the cytaimage file must exist", + "errorMessage": "Path to the cytaimage file must exist and not contain spaces", "meta": [ "cytaimage" ] }, "colorizedimage": { "type": "string", + "pattern": "^\\S+$", "format": "path", "exists": true, - "errorMessage": "Path to the colorizedimage file must exist", + "errorMessage": "Path to the colorizedimage file must exist and not contain spaces", "meta": [ "colorizedimage" ] }, "darkimage": { "type": "string", + "pattern": "^\\S+$", "format": "path", "exists": true, - "errorMessage": "Path to the darkimage file must exist", + "errorMessage": "Path to the darkimage file must exist and not contain spaces", "meta": [ "darkimage" ] }, "image": { "type": "string", + "pattern": "^\\S+$", "format": "path", "exists": true, - "errorMessage": "Path to the image must exist", + "errorMessage": "Path to the image must exist and not contain spaces", "meta": [ "image" ] }, "slide": { "type": "string", + "pattern": "^\\S+$", "errorMessage": "Slide name cannot contain spaces", "meta": [ "slide" @@ -83,18 +90,20 @@ }, "manual_alignment": { "type": "string", + "pattern": "^\\S+$", "format": "path", "exists": true, - "errorMessage": "Path to the manual_alignment file must exist", + "errorMessage": "Path to the manual_alignment file must exist and not contain spaces", "meta": [ "manual_alignment" ] }, "slidefile": { "type": "string", + "pattern": "^\\S+$", "format": "path", "exists": true, - "errorMessage": "Path to the slidefile must exist", + "errorMessage": "Path to the slidefile must exist and not contain spaces", "meta": [ "slidefile" ] From 2ffeb72ccad90ad3e97071bc32f4e971f84c3b50 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 23 Jun 2025 09:44:39 +0200 Subject: [PATCH 085/227] rename cure51 config - to be removed --- conf/{slurm.config => cure51.config} | 26 ++++++++++++++++++++------ nextflow.config | 2 +- 2 files changed, 21 insertions(+), 7 deletions(-) rename conf/{slurm.config => cure51.config} (67%) diff --git a/conf/slurm.config b/conf/cure51.config similarity index 67% rename from conf/slurm.config rename to conf/cure51.config index 8ece940..1e9a43b 100644 --- a/conf/slurm.config +++ b/conf/cure51.config @@ -7,7 +7,9 @@ process { // Lightweight tasks: Fits into the standard partition withLabel: process_single { queue = 'standard' - time = 2.d + cpus = { 1 } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } resourceLimits = [ cpus: 4, memory: 30.GB, @@ -17,7 +19,9 @@ process { // Low resource tasks: Use nf-standard-mem withLabel: process_low { queue = 'nf-standard-mem' - time = 2.d + cpus = { 2 * task.attempt } + memory = { 12.GB * task.attempt } + time = { 4.h * task.attempt } resourceLimits = [ cpus: 8, memory: 60.GB, @@ -27,7 +31,9 @@ process { // Medium resource tasks: Use nf-standard-mem or nf-high-mem withLabel: process_medium { queue = 'nf-high-mem' - time = 2.d + cpus = { 6 * task.attempt } + memory = { 36.GB * task.attempt } + time = { 8.h * task.attempt } resourceLimits = [ cpus: 16, memory: 120.GB, @@ -37,7 +43,9 @@ process { // High resource tasks: Use nf-high-mem withLabel: process_high { queue = 'nf-high-mem' - time = 2.d + cpus = { 12 * task.attempt } + memory = { 72.GB * task.attempt } + time = { 16.h * task.attempt } resourceLimits = [ cpus: 16, memory: 120.GB, @@ -47,7 +55,7 @@ process { // Long-running tasks: Use high partition for extended time withLabel: process_long { queue = 'high' - time = 4.d + time = { 20.h * task.attempt } resourceLimits = [ cpus: 32, memory: 250.GB, @@ -57,12 +65,18 @@ process { // Memory-intensive tasks: Use high partition for maximum memory withLabel: process_high_memory { queue = 'high' - time = 4.d + memory = { 200.GB * task.attempt } resourceLimits = [ cpus: 32, memory: 250.GB, ] } + + withName: patchSegmentationProseg { + cpus = { 8 * task.attempt } + memory = { 200.GB * task.attempt } + time = { 10.d * task.attempt } + } } aws { diff --git a/nextflow.config b/nextflow.config index 9d06590..33ac9db 100644 --- a/nextflow.config +++ b/nextflow.config @@ -154,7 +154,7 @@ profiles { } test_vhd { includeConfig 'conf/test_vhd.config' } test { includeConfig 'conf/test.config' } - slurm { includeConfig 'conf/slurm.config' } + cure51 { includeConfig 'conf/cure51.config' } // TODO: remove this profile once the pipeline is merged into nf-core/sopa test_full { includeConfig 'conf/test_full.config' } } From c7940f4781534ad025a2f3da99cfd47f3382e104 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 25 Jun 2025 09:28:42 +0200 Subject: [PATCH 086/227] update patchSegmentationProseg config --- conf/cure51.config | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/conf/cure51.config b/conf/cure51.config index 1e9a43b..8aa208b 100644 --- a/conf/cure51.config +++ b/conf/cure51.config @@ -73,9 +73,14 @@ process { } withName: patchSegmentationProseg { + queue = 'high' cpus = { 8 * task.attempt } memory = { 200.GB * task.attempt } time = { 10.d * task.attempt } + resourceLimits = [ + cpus: 32, + memory: 400.GB, + ] } } From a56e4f6801bcad61f709bf4a46ad4909aa8af382 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 2 Jul 2025 10:46:41 +0200 Subject: [PATCH 087/227] configfile can read from existing github files --- modules/local/utils.nf | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/modules/local/utils.nf b/modules/local/utils.nf index d5e24e6..99f9927 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -65,7 +65,16 @@ def ArgsReaderCLI(Map args, Map meta) { } def readConfigFile(String configfile) { - def config = new groovy.yaml.YamlSlurper().parse(configfile as File) + def reader + + if (configfile ==~ /^https?:\/\/.*/) { + reader = new InputStreamReader(new URL(configfile).openStream()) + } + else { + reader = new File(configfile).newReader() + } + + def config = new groovy.yaml.YamlSlurper().parse(reader) if (config.segmentation.baysor) { if (config.segmentation.cellpose) { From 5c2ee633ff6b2d03099db0d683a3c8fedc65416e Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 7 Jul 2025 09:16:09 +0200 Subject: [PATCH 088/227] update sopa version --- subworkflows/local/baysor/main.nf | 8 ++++---- subworkflows/local/cellpose/main.nf | 8 ++++---- subworkflows/local/proseg/main.nf | 4 ++-- subworkflows/local/stardist/main.nf | 8 ++++---- workflows/sopa.nf | 32 ++++++++++++++--------------- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index 92e9acd..aa652d5 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -27,8 +27,8 @@ process patchSegmentationBaysor { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6-baysor' - : 'docker.io/quentinblampey/sopa:2.0.6-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.0-baysor' + : 'docker.io/quentinblampey/sopa:2.1.0-baysor'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -51,8 +51,8 @@ process resolveBaysor { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6-baysor' - : 'docker.io/quentinblampey/sopa:2.0.6-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.0-baysor' + : 'docker.io/quentinblampey/sopa:2.1.0-baysor'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index 024e2c0..43d2aed 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -27,8 +27,8 @@ process patchSegmentationCellpose { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6-cellpose' - : 'docker.io/quentinblampey/sopa:2.0.6-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.0-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.0-cellpose'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -47,8 +47,8 @@ process resolveCellpose { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6' - : 'docker.io/quentinblampey/sopa:2.0.6'}" + ? 'docker://quentinblampey/sopa:2.1.0' + : 'docker.io/quentinblampey/sopa:2.1.0'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index ceef276..5ec9394 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -20,8 +20,8 @@ process patchSegmentationProseg { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6-proseg' - : 'docker.io/quentinblampey/sopa:2.0.6-proseg'}" + ? 'docker://quentinblampey/sopa:2.1.0-proseg' + : 'docker.io/quentinblampey/sopa:2.1.0-proseg'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/stardist/main.nf b/subworkflows/local/stardist/main.nf index 3ae8e42..cd60cfa 100644 --- a/subworkflows/local/stardist/main.nf +++ b/subworkflows/local/stardist/main.nf @@ -27,8 +27,8 @@ process patchSegmentationStardist { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6-stardist' - : 'docker.io/quentinblampey/sopa:2.0.6-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.0-stardist' + : 'docker.io/quentinblampey/sopa:2.1.0-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -47,8 +47,8 @@ process resolveStardist { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6' - : 'docker.io/quentinblampey/sopa:2.0.6'}" + ? 'docker://quentinblampey/sopa:2.1.0' + : 'docker.io/quentinblampey/sopa:2.1.0'}" input: tuple val(meta), path(sdata_path) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index cf43655..ceb4a01 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -103,8 +103,8 @@ process toSpatialData { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6' - : 'docker.io/quentinblampey/sopa:2.0.6'}" + ? 'docker://quentinblampey/sopa:2.1.0' + : 'docker.io/quentinblampey/sopa:2.1.0'}" input: tuple val(meta), path(input_files) @@ -124,8 +124,8 @@ process tissueSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6' - : 'docker.io/quentinblampey/sopa:2.0.6'}" + ? 'docker://quentinblampey/sopa:2.1.0' + : 'docker.io/quentinblampey/sopa:2.1.0'}" input: tuple val(meta), path(sdata_path) @@ -146,8 +146,8 @@ process makeImagePatches { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6' - : 'docker.io/quentinblampey/sopa:2.0.6'}" + ? 'docker://quentinblampey/sopa:2.1.0' + : 'docker.io/quentinblampey/sopa:2.1.0'}" input: tuple val(meta), path(sdata_path) @@ -168,8 +168,8 @@ process makeTranscriptPatches { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6' - : 'docker.io/quentinblampey/sopa:2.0.6'}" + ? 'docker://quentinblampey/sopa:2.1.0' + : 'docker.io/quentinblampey/sopa:2.1.0'}" input: tuple val(meta), path(sdata_path) @@ -189,8 +189,8 @@ process aggregate { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6' - : 'docker.io/quentinblampey/sopa:2.0.6'}" + ? 'docker://quentinblampey/sopa:2.1.0' + : 'docker.io/quentinblampey/sopa:2.1.0'}" input: tuple val(meta), path(sdata_path) @@ -211,8 +211,8 @@ process explorer_raw { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6' - : 'docker.io/quentinblampey/sopa:2.0.6'}" + ? 'docker://quentinblampey/sopa:2.1.0' + : 'docker.io/quentinblampey/sopa:2.1.0'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -235,8 +235,8 @@ process explorer { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6' - : 'docker.io/quentinblampey/sopa:2.0.6'}" + ? 'docker://quentinblampey/sopa:2.1.0' + : 'docker.io/quentinblampey/sopa:2.1.0'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -262,8 +262,8 @@ process report { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.6' - : 'docker.io/quentinblampey/sopa:2.0.6'}" + ? 'docker://quentinblampey/sopa:2.1.0' + : 'docker.io/quentinblampey/sopa:2.1.0'}" publishDir "${params.outdir}", mode: params.publish_dir_mode From 415358dae475ca0b67dbde12abc9da563eca7c96 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 8 Jul 2025 16:10:59 +0200 Subject: [PATCH 089/227] go back to image with ps command for nextflow --- subworkflows/local/baysor/main.nf | 8 ++++---- subworkflows/local/cellpose/main.nf | 8 ++++---- subworkflows/local/proseg/main.nf | 4 ++-- subworkflows/local/stardist/main.nf | 8 ++++---- workflows/sopa.nf | 32 ++++++++++++++--------------- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index aa652d5..c93c4ab 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -27,8 +27,8 @@ process patchSegmentationBaysor { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0-baysor' - : 'docker.io/quentinblampey/sopa:2.1.0-baysor'}" + ? 'docker://quentinblampey/sopa:2.0.7-baysor' + : 'docker.io/quentinblampey/sopa:2.0.7-baysor'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -51,8 +51,8 @@ process resolveBaysor { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0-baysor' - : 'docker.io/quentinblampey/sopa:2.1.0-baysor'}" + ? 'docker://quentinblampey/sopa:2.0.7-baysor' + : 'docker.io/quentinblampey/sopa:2.0.7-baysor'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index 43d2aed..c4586f6 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -27,8 +27,8 @@ process patchSegmentationCellpose { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.0-cellpose'}" + ? 'docker://quentinblampey/sopa:2.0.7-cellpose' + : 'docker.io/quentinblampey/sopa:2.0.7-cellpose'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -47,8 +47,8 @@ process resolveCellpose { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0' - : 'docker.io/quentinblampey/sopa:2.1.0'}" + ? 'docker://quentinblampey/sopa:2.0.7' + : 'docker.io/quentinblampey/sopa:2.0.7'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index 5ec9394..c8400ff 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -20,8 +20,8 @@ process patchSegmentationProseg { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0-proseg' - : 'docker.io/quentinblampey/sopa:2.1.0-proseg'}" + ? 'docker://quentinblampey/sopa:2.0.7-proseg' + : 'docker.io/quentinblampey/sopa:2.0.7-proseg'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/stardist/main.nf b/subworkflows/local/stardist/main.nf index cd60cfa..2340a59 100644 --- a/subworkflows/local/stardist/main.nf +++ b/subworkflows/local/stardist/main.nf @@ -27,8 +27,8 @@ process patchSegmentationStardist { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0-stardist' - : 'docker.io/quentinblampey/sopa:2.1.0-stardist'}" + ? 'docker://quentinblampey/sopa:2.0.7-stardist' + : 'docker.io/quentinblampey/sopa:2.0.7-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -47,8 +47,8 @@ process resolveStardist { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0' - : 'docker.io/quentinblampey/sopa:2.1.0'}" + ? 'docker://quentinblampey/sopa:2.0.7' + : 'docker.io/quentinblampey/sopa:2.0.7'}" input: tuple val(meta), path(sdata_path) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index ceb4a01..6ee9e3a 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -103,8 +103,8 @@ process toSpatialData { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0' - : 'docker.io/quentinblampey/sopa:2.1.0'}" + ? 'docker://quentinblampey/sopa:2.0.7' + : 'docker.io/quentinblampey/sopa:2.0.7'}" input: tuple val(meta), path(input_files) @@ -124,8 +124,8 @@ process tissueSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0' - : 'docker.io/quentinblampey/sopa:2.1.0'}" + ? 'docker://quentinblampey/sopa:2.0.7' + : 'docker.io/quentinblampey/sopa:2.0.7'}" input: tuple val(meta), path(sdata_path) @@ -146,8 +146,8 @@ process makeImagePatches { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0' - : 'docker.io/quentinblampey/sopa:2.1.0'}" + ? 'docker://quentinblampey/sopa:2.0.7' + : 'docker.io/quentinblampey/sopa:2.0.7'}" input: tuple val(meta), path(sdata_path) @@ -168,8 +168,8 @@ process makeTranscriptPatches { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0' - : 'docker.io/quentinblampey/sopa:2.1.0'}" + ? 'docker://quentinblampey/sopa:2.0.7' + : 'docker.io/quentinblampey/sopa:2.0.7'}" input: tuple val(meta), path(sdata_path) @@ -189,8 +189,8 @@ process aggregate { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0' - : 'docker.io/quentinblampey/sopa:2.1.0'}" + ? 'docker://quentinblampey/sopa:2.0.7' + : 'docker.io/quentinblampey/sopa:2.0.7'}" input: tuple val(meta), path(sdata_path) @@ -211,8 +211,8 @@ process explorer_raw { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0' - : 'docker.io/quentinblampey/sopa:2.1.0'}" + ? 'docker://quentinblampey/sopa:2.0.7' + : 'docker.io/quentinblampey/sopa:2.0.7'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -235,8 +235,8 @@ process explorer { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0' - : 'docker.io/quentinblampey/sopa:2.1.0'}" + ? 'docker://quentinblampey/sopa:2.0.7' + : 'docker.io/quentinblampey/sopa:2.0.7'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -262,8 +262,8 @@ process report { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.0' - : 'docker.io/quentinblampey/sopa:2.1.0'}" + ? 'docker://quentinblampey/sopa:2.0.7' + : 'docker.io/quentinblampey/sopa:2.0.7'}" publishDir "${params.outdir}", mode: params.publish_dir_mode From 553c6705fca87a1ba475346c7a63e03557316a4f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 9 Jul 2025 13:00:51 +0200 Subject: [PATCH 090/227] remove organization-specific config --- conf/cure51.config | 91 ---------------------------------------------- 1 file changed, 91 deletions(-) delete mode 100644 conf/cure51.config diff --git a/conf/cure51.config b/conf/cure51.config deleted file mode 100644 index 8aa208b..0000000 --- a/conf/cure51.config +++ /dev/null @@ -1,91 +0,0 @@ -process { - executor = 'slurm' - containerOptions = '--user $(id -u):$(id -g)' - errorStrategy = 'retry' - maxRetries = 2 - - // Lightweight tasks: Fits into the standard partition - withLabel: process_single { - queue = 'standard' - cpus = { 1 } - memory = { 6.GB * task.attempt } - time = { 4.h * task.attempt } - resourceLimits = [ - cpus: 4, - memory: 30.GB, - ] - } - - // Low resource tasks: Use nf-standard-mem - withLabel: process_low { - queue = 'nf-standard-mem' - cpus = { 2 * task.attempt } - memory = { 12.GB * task.attempt } - time = { 4.h * task.attempt } - resourceLimits = [ - cpus: 8, - memory: 60.GB, - ] - } - - // Medium resource tasks: Use nf-standard-mem or nf-high-mem - withLabel: process_medium { - queue = 'nf-high-mem' - cpus = { 6 * task.attempt } - memory = { 36.GB * task.attempt } - time = { 8.h * task.attempt } - resourceLimits = [ - cpus: 16, - memory: 120.GB, - ] - } - - // High resource tasks: Use nf-high-mem - withLabel: process_high { - queue = 'nf-high-mem' - cpus = { 12 * task.attempt } - memory = { 72.GB * task.attempt } - time = { 16.h * task.attempt } - resourceLimits = [ - cpus: 16, - memory: 120.GB, - ] - } - - // Long-running tasks: Use high partition for extended time - withLabel: process_long { - queue = 'high' - time = { 20.h * task.attempt } - resourceLimits = [ - cpus: 32, - memory: 250.GB, - ] - } - - // Memory-intensive tasks: Use high partition for maximum memory - withLabel: process_high_memory { - queue = 'high' - memory = { 200.GB * task.attempt } - resourceLimits = [ - cpus: 32, - memory: 250.GB, - ] - } - - withName: patchSegmentationProseg { - queue = 'high' - cpus = { 8 * task.attempt } - memory = { 200.GB * task.attempt } - time = { 10.d * task.attempt } - resourceLimits = [ - cpus: 32, - memory: 400.GB, - ] - } -} - -aws { - client { - anonymous = true - } -} From 97afb6120adbbe4b2cea5a14d4e5198d41e1c168 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 9 Jul 2025 13:07:33 +0200 Subject: [PATCH 091/227] fix pre-commit --- .gitignore | 2 +- assets/schema_input.json | 42 ++++++--------------- nextflow.config | 5 +-- nextflow_schema.json | 17 ++------- subworkflows/local/baysor/environment.yml | 12 +++--- subworkflows/local/baysor/main.nf | 2 +- subworkflows/local/cellpose/environment.yml | 12 +++--- subworkflows/local/proseg/environment.yml | 12 +++--- subworkflows/local/stardist/environment.yml | 12 +++--- tests/sample1 | 2 +- tests/sample2 | 2 +- tests/samplesheet_fastq.csv | 2 +- workflows/environment.yml | 12 +++--- 13 files changed, 51 insertions(+), 83 deletions(-) diff --git a/.gitignore b/.gitignore index df30ed1..12b7d78 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,4 @@ testing* *.pyc null/ sandbox -samplesheets \ No newline at end of file +samplesheets diff --git a/assets/schema_input.json b/assets/schema_input.json index eca9c9e..a829f96 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -11,9 +11,7 @@ "type": "string", "pattern": "^\\S+$", "errorMessage": "Sample name cannot contain spaces", - "meta": [ - "id" - ] + "meta": ["id"] }, "data_path": { "type": "string", @@ -28,9 +26,7 @@ "format": "path", "exists": true, "errorMessage": "Path to the fastq directory must exist and not contain spaces", - "meta": [ - "fastq_dir" - ] + "meta": ["fastq_dir"] }, "cytaimage": { "type": "string", @@ -38,9 +34,7 @@ "format": "path", "exists": true, "errorMessage": "Path to the cytaimage file must exist and not contain spaces", - "meta": [ - "cytaimage" - ] + "meta": ["cytaimage"] }, "colorizedimage": { "type": "string", @@ -48,9 +42,7 @@ "format": "path", "exists": true, "errorMessage": "Path to the colorizedimage file must exist and not contain spaces", - "meta": [ - "colorizedimage" - ] + "meta": ["colorizedimage"] }, "darkimage": { "type": "string", @@ -58,9 +50,7 @@ "format": "path", "exists": true, "errorMessage": "Path to the darkimage file must exist and not contain spaces", - "meta": [ - "darkimage" - ] + "meta": ["darkimage"] }, "image": { "type": "string", @@ -68,25 +58,19 @@ "format": "path", "exists": true, "errorMessage": "Path to the image must exist and not contain spaces", - "meta": [ - "image" - ] + "meta": ["image"] }, "slide": { "type": "string", "pattern": "^\\S+$", "errorMessage": "Slide name cannot contain spaces", - "meta": [ - "slide" - ] + "meta": ["slide"] }, "area": { "type": "string", "pattern": "^\\S+$", "errorMessage": "Area name cannot contain spaces", - "meta": [ - "area" - ] + "meta": ["area"] }, "manual_alignment": { "type": "string", @@ -94,9 +78,7 @@ "format": "path", "exists": true, "errorMessage": "Path to the manual_alignment file must exist and not contain spaces", - "meta": [ - "manual_alignment" - ] + "meta": ["manual_alignment"] }, "slidefile": { "type": "string", @@ -104,10 +86,8 @@ "format": "path", "exists": true, "errorMessage": "Path to the slidefile must exist and not contain spaces", - "meta": [ - "slidefile" - ] + "meta": ["slidefile"] } } } -} \ No newline at end of file +} diff --git a/nextflow.config b/nextflow.config index 33ac9db..6aa9b47 100644 --- a/nextflow.config +++ b/nextflow.config @@ -16,7 +16,7 @@ params { // Spaceranger options spaceranger_reference = "https://cf.10xgenomics.com/supp/spatial-exp/refdata-gex-GRCh38-2020-A.tar.gz" spaceranger_probeset = null - + // Boilerplate options outdir = null publish_dir_mode = 'copy' @@ -154,9 +154,8 @@ profiles { } test_vhd { includeConfig 'conf/test_vhd.config' } test { includeConfig 'conf/test.config' } - cure51 { includeConfig 'conf/cure51.config' } // TODO: remove this profile once the pipeline is merged into nf-core/sopa test_full { includeConfig 'conf/test_full.config' } -} +} // Load nf-core custom profiles from different Institutions includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/nfcore_custom.config" : "/dev/null" diff --git a/nextflow_schema.json b/nextflow_schema.json index 2408c28..dd516e8 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -10,11 +10,7 @@ "type": "object", "fa_icon": "fas fa-terminal", "description": "Define where the pipeline should find input data and save output data.", - "required": [ - "input", - "outdir", - "configfile" - ], + "required": ["input", "outdir", "configfile"], "properties": { "input": { "type": "string", @@ -144,14 +140,7 @@ "description": "Method used to save pipeline results to output directory.", "help_text": "The Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.", "fa_icon": "fas fa-copy", - "enum": [ - "symlink", - "rellink", - "link", - "copy", - "copyNoFollow", - "move" - ], + "enum": ["symlink", "rellink", "link", "copy", "copyNoFollow", "move"], "hidden": true }, "email_on_fail": { @@ -215,4 +204,4 @@ "$ref": "#/$defs/generic_options" } ] -} \ No newline at end of file +} diff --git a/subworkflows/local/baysor/environment.yml b/subworkflows/local/baysor/environment.yml index 03ebdf2..6808f3c 100644 --- a/subworkflows/local/baysor/environment.yml +++ b/subworkflows/local/baysor/environment.yml @@ -1,8 +1,8 @@ channels: -- conda-forge -- bioconda + - conda-forge + - bioconda dependencies: -- python=3.10 -- pip=24.3.1 -- pip: - - sopa[baysor]>=2.0.2 + - python=3.10 + - pip=24.3.1 + - pip: + - sopa[baysor]>=2.0.2 diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index c93c4ab..9e600cb 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -41,7 +41,7 @@ process patchSegmentationBaysor { if command -v module &> /dev/null; then module purge fi - + sopa segmentation baysor ${sdata_path} --patch-index ${index} ${cli_arguments} """ } diff --git a/subworkflows/local/cellpose/environment.yml b/subworkflows/local/cellpose/environment.yml index fa547f9..8c8a60d 100644 --- a/subworkflows/local/cellpose/environment.yml +++ b/subworkflows/local/cellpose/environment.yml @@ -1,8 +1,8 @@ channels: -- conda-forge -- bioconda + - conda-forge + - bioconda dependencies: -- python=3.10 -- pip=24.3.1 -- pip: - - sopa[cellpose]>=2.0.2 + - python=3.10 + - pip=24.3.1 + - pip: + - sopa[cellpose]>=2.0.2 diff --git a/subworkflows/local/proseg/environment.yml b/subworkflows/local/proseg/environment.yml index 18c06ff..1fd551b 100644 --- a/subworkflows/local/proseg/environment.yml +++ b/subworkflows/local/proseg/environment.yml @@ -1,8 +1,8 @@ channels: -- conda-forge -- bioconda + - conda-forge + - bioconda dependencies: -- python=3.10 -- pip=24.3.1 -- pip: - - sopa>=2.0.3 + - python=3.10 + - pip=24.3.1 + - pip: + - sopa>=2.0.3 diff --git a/subworkflows/local/stardist/environment.yml b/subworkflows/local/stardist/environment.yml index eb5da04..389491b 100644 --- a/subworkflows/local/stardist/environment.yml +++ b/subworkflows/local/stardist/environment.yml @@ -1,8 +1,8 @@ channels: -- conda-forge -- bioconda + - conda-forge + - bioconda dependencies: -- python=3.10 -- pip=24.3.1 -- pip: - - sopa[stardist]>=2.0.2 + - python=3.10 + - pip=24.3.1 + - pip: + - sopa[stardist]>=2.0.2 diff --git a/tests/sample1 b/tests/sample1 index 0704b24..f78b913 100644 --- a/tests/sample1 +++ b/tests/sample1 @@ -1,2 +1,2 @@ This is a fake sample -Tests datasets are generated on the fly by Sopa \ No newline at end of file +Tests datasets are generated on the fly by Sopa diff --git a/tests/sample2 b/tests/sample2 index 0704b24..f78b913 100644 --- a/tests/sample2 +++ b/tests/sample2 @@ -1,2 +1,2 @@ This is a fake sample -Tests datasets are generated on the fly by Sopa \ No newline at end of file +Tests datasets are generated on the fly by Sopa diff --git a/tests/samplesheet_fastq.csv b/tests/samplesheet_fastq.csv index c5d0348..b026106 100644 --- a/tests/samplesheet_fastq.csv +++ b/tests/samplesheet_fastq.csv @@ -1,2 +1,2 @@ sample,fastq_dir,cytaimage,slide,area -CytAssist_11mm_FFPE_Human_Glioblastoma_2,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/fastq_dir.tar.gz,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_image.tif,V52Y10-317,B1 \ No newline at end of file +CytAssist_11mm_FFPE_Human_Glioblastoma_2,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/fastq_dir.tar.gz,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_image.tif,V52Y10-317,B1 diff --git a/workflows/environment.yml b/workflows/environment.yml index 18c06ff..1fd551b 100644 --- a/workflows/environment.yml +++ b/workflows/environment.yml @@ -1,8 +1,8 @@ channels: -- conda-forge -- bioconda + - conda-forge + - bioconda dependencies: -- python=3.10 -- pip=24.3.1 -- pip: - - sopa>=2.0.3 + - python=3.10 + - pip=24.3.1 + - pip: + - sopa>=2.0.3 From fac972f8c5da3238aef81ebd8271a6bafa4c3a6c Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 9 Jul 2025 13:33:03 +0200 Subject: [PATCH 092/227] fill TODO sections - wip --- README.md | 48 ++++++++++++++++++++++++------------------- conf/test.config | 2 -- conf/test_full.config | 2 -- conf/test_vhd.config | 2 -- docs/output.md | 6 ++---- nextflow.config | 13 ++++++------ 6 files changed, 35 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 5aba081..e6a691c 100644 --- a/README.md +++ b/README.md @@ -17,48 +17,38 @@ ## Introduction -**nf-core/sopa** is a bioinformatics pipeline that ... +**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization. - +

    + sopa_overview +

    - ## Usage > [!NOTE] -> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow.Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data. +> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data. - +Then, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config). Follow the README instructions of the latter link to get your `--configfile`. Now, you can run the pipeline using: - - ```bash nextflow run nf-core/sopa \ -profile \ --input samplesheet.csv \ - --configfile sopa_config_name.yaml \ + --configfile \ --outdir ``` @@ -94,6 +84,22 @@ For further information or help, don't hesitate to get in touch on the [Slack `# An extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file. +You can cite the `sopa` publication as follows: + +```txt +@article{blampey_sopa_2024, + title = {Sopa: a technology-invariant pipeline for analyses of image-based spatial omics}, + volume = {15}, + url = {https://www.nature.com/articles/s41467-024-48981-z}, + doi = {10.1038/s41467-024-48981-z}, + journal = {Nature Communications}, + author = {Blampey, Quentin and Mulder, Kevin and Gardet, Margaux and Christodoulidis, Stergios and Dutertre, Charles-Antoine and André, Fabrice and Ginhoux, Florent and Cournède, Paul-Henry}, + year = {2024}, + note = {Publisher: Nature Publishing Group}, + pages = {4981}, +} +``` + You can cite the `nf-core` publication as follows: > **The nf-core framework for community-curated bioinformatics pipelines.** diff --git a/conf/test.config b/conf/test.config index a8fab29..2f11d39 100644 --- a/conf/test.config +++ b/conf/test.config @@ -23,8 +23,6 @@ params { config_profile_description = 'Minimal test dataset to check pipeline function' // 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 input = "${baseDir}/tests/samplesheet.csv" configfile = "${baseDir}/tests/config/cellpose.yaml" } diff --git a/conf/test_full.config b/conf/test_full.config index e095497..f86d576 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -15,8 +15,6 @@ params { config_profile_description = 'Full test dataset to check pipeline function' // Input data for full size test - // TODO nf-core: Specify the paths to your full test data ( on nf-core/test-datasets or directly in repositories, e.g. SRA) - // TODO nf-core: Give any required params for the test so that command line flags are not needed input = "${baseDir}/tests/samplesheet.csv" configfile = "${baseDir}/tests/config/baysor.yaml" } diff --git a/conf/test_vhd.config b/conf/test_vhd.config index 70fa04b..1f3daf8 100644 --- a/conf/test_vhd.config +++ b/conf/test_vhd.config @@ -23,8 +23,6 @@ params { config_profile_description = 'Minimal test dataset to check pipeline function' // 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 input = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/samplesheet_spaceranger.csv" spaceranger_probeset = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/outs/probe_set.csv" spaceranger_reference = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/homo_sapiens_chr22_reference.tar.gz" diff --git a/docs/output.md b/docs/output.md index 8aa16f1..56569d3 100644 --- a/docs/output.md +++ b/docs/output.md @@ -2,11 +2,9 @@ ## Introduction -This document describes the output produced by the pipeline. +[This section from the Sopa documentation](https://gustaveroussy.github.io/sopa/tutorials/snakemake/#pipeline-outputs) describes the output produced by the pipeline. -The directories listed below will be created in the results directory after the pipeline has finished. All paths are relative to the top-level results directory. - - +The directories listed in the above link will be created in the results directory after the pipeline has finished. All paths are relative to the top-level results directory. ## Pipeline overview diff --git a/nextflow.config b/nextflow.config index 6aa9b47..641e74a 100644 --- a/nextflow.config +++ b/nextflow.config @@ -9,9 +9,9 @@ // Global default params, used in configs params { - // TODO nf-core: Specify your pipeline's command line flags // Input options input = null + configfile = null // Spaceranger options spaceranger_reference = "https://cf.10xgenomics.com/supp/spatial-exp/refdata-gex-GRCh38-2020-A.tar.gz" @@ -219,14 +219,13 @@ manifest { name = 'nf-core/sopa' author = """Quentin Blampey""" // The author field is deprecated from Nextflow version 24.10.0, use contributors instead contributors = [ - // TODO nf-core: Update the field with the details of the contributors to your pipeline. New with Nextflow version 24.10.0 [ name: 'Quentin Blampey', - affiliation: '', - email: '', - github: '', - contribution: [], // List of contribution types ('author', 'maintainer' or 'contributor') - orcid: '' + affiliation: 'CentraleSupélec, Gustave Roussy', + email: 'quentin.blampey@gmail.com', + github: 'https://github.com/quentinblampey', + contribution: ['author', 'maintainer'], // List of contribution types ('author', 'maintainer' or 'contributor') + orcid: '0000-0002-3836-2889' ], ] homePage = 'https://github.com/nf-core/sopa' From 48f866f871124daa10fc39ba1f444af945c2d7c9 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 9 Jul 2025 14:36:59 +0200 Subject: [PATCH 093/227] update readme and citations --- CITATIONS.md | 20 ++++++++++++++++++++ README.md | 28 ++++++++++++---------------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/CITATIONS.md b/CITATIONS.md index 3a62896..2f2372f 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -1,5 +1,9 @@ # nf-core/sopa: Citations +## [sopa](https://www.nature.com/articles/s41467-024-48981-z) + +> Blampey, Q., Mulder, K., Gardet, M. et al. Sopa: a technology-invariant pipeline for analyses of image-based spatial omics. Nat Commun 15, 4981 (2024). https://doi.org/10.1038/s41467-024-48981-z + ## [nf-core](https://pubmed.ncbi.nlm.nih.gov/32055031/) > Ewels PA, Peltzer A, Fillinger S, Patel H, Alneberg J, Wilm A, Garcia MU, Di Tommaso P, Nahnsen S. The nf-core framework for community-curated bioinformatics pipelines. Nat Biotechnol. 2020 Mar;38(3):276-278. doi: 10.1038/s41587-020-0439-x. PubMed PMID: 32055031. @@ -10,6 +14,22 @@ ## Pipeline tools +- [AnnData](https://github.com/scverse/anndata) + + > Virshup I, Rybakov S, Theis FJ, Angerer P, Wolf FA. bioRxiv 2021.12.16.473007; doi: https://doi.org/10.1101/2021.12.16.473007 + +- [Scanpy](https://github.com/theislab/scanpy) + + > Wolf F, Angerer P, Theis F. SCANPY: large-scale single-cell gene expression data analysis. Genome Biol 19, 15 (2018). doi: https://doi.org/10.1186/s13059-017-1382-0 + +- [Space Ranger](https://www.10xgenomics.com/support/software/space-ranger) + + > 10x Genomics Space Ranger 2.1.0 [Online] + +- [SpatialData](https://www.biorxiv.org/content/10.1101/2023.05.05.539647v1) + + > Marconato L, Palla G, Yamauchi K, Virshup I, Heidari E, Treis T, Toth M, Shrestha R, Vöhringer H, Huber W, Gerstung M, Moore J, Theis F, Stegle O. SpatialData: an open and universal data framework for spatial omics. bioRxiv 2023.05.05.539647; doi: https://doi.org/10.1101/2023.05.05.539647 + ## Software packaging/containerisation tools - [Anaconda](https://anaconda.com) diff --git a/README.md b/README.md index e6a691c..ed866f6 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,12 @@ nf-core/sopa -[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/ci.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/ci.yml) -[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX) + + +[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/ci.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/ci.yml) +[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml) +[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results) +[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX) [![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com) [![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-23aa62.svg)](https://www.nextflow.io/) @@ -65,7 +69,7 @@ For more details about the output files and reports, please refer to the ## Credits -nf-core/sopa was originally written by Quentin Blampey. +nf-core/sopa was originally written by Quentin Blampey based on fundings from the following institutions: CentraleSupélec, Gustave Roussy Institute, and Université Paris-Saclay. We thank the following people for their extensive assistance in the development of this pipeline: @@ -86,19 +90,11 @@ An extensive list of references for the tools used by the pipeline can be found You can cite the `sopa` publication as follows: -```txt -@article{blampey_sopa_2024, - title = {Sopa: a technology-invariant pipeline for analyses of image-based spatial omics}, - volume = {15}, - url = {https://www.nature.com/articles/s41467-024-48981-z}, - doi = {10.1038/s41467-024-48981-z}, - journal = {Nature Communications}, - author = {Blampey, Quentin and Mulder, Kevin and Gardet, Margaux and Christodoulidis, Stergios and Dutertre, Charles-Antoine and André, Fabrice and Ginhoux, Florent and Cournède, Paul-Henry}, - year = {2024}, - note = {Publisher: Nature Publishing Group}, - pages = {4981}, -} -``` +> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics. +> +> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice André, Florent Ginhoux & Paul-Henry Cournède. +> +> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z) You can cite the `nf-core` publication as follows: From 7805e067d17142f84f8ab11ebe72eaf51587b6ab Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 9 Jul 2025 14:55:20 +0200 Subject: [PATCH 094/227] fix linting ci --- README.md | 2 +- nextflow_schema.json | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ed866f6..3f05021 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ For more details about the output files and reports, please refer to the ## Credits -nf-core/sopa was originally written by Quentin Blampey based on fundings from the following institutions: CentraleSupélec, Gustave Roussy Institute, and Université Paris-Saclay. +nf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSupélec, Gustave Roussy Institute, and Université Paris-Saclay. We thank the following people for their extensive assistance in the development of this pipeline: diff --git a/nextflow_schema.json b/nextflow_schema.json index dd516e8..d63b4bf 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -197,6 +197,9 @@ { "$ref": "#/$defs/input_output_options" }, + { + "$ref": "#/$defs/spaceranger_options" + }, { "$ref": "#/$defs/institutional_config_options" }, From 63504292c4e78daf0c9a929ff254cf123bfe6355 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 9 Jul 2025 15:05:44 +0200 Subject: [PATCH 095/227] consistent publish_dir_mode --- .gitignore | 1 + nextflow_schema.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 12b7d78..cf06435 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ testing* null/ sandbox samplesheets +lint_* diff --git a/nextflow_schema.json b/nextflow_schema.json index d63b4bf..c3fd33e 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -136,7 +136,7 @@ }, "publish_dir_mode": { "type": "string", - "default": "symlink", + "default": "copy", "description": "Method used to save pipeline results to output directory.", "help_text": "The Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.", "fa_icon": "fas fa-copy", From dd924cdf9cad1f828e0faaa736b71746d43cb518 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 10 Jul 2025 09:40:32 +0200 Subject: [PATCH 096/227] visium hd wip --- docs/output.md | 7 +++++-- tests/README.md | 24 ++++++++++++++++++++++++ tests/samplesheet_fastq.csv | 2 -- tests/samplesheet_visium_hd.csv | 2 ++ 4 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 tests/README.md delete mode 100644 tests/samplesheet_fastq.csv create mode 100644 tests/samplesheet_visium_hd.csv diff --git a/docs/output.md b/docs/output.md index 56569d3..f69d5cd 100644 --- a/docs/output.md +++ b/docs/output.md @@ -2,9 +2,12 @@ ## Introduction -[This section from the Sopa documentation](https://gustaveroussy.github.io/sopa/tutorials/snakemake/#pipeline-outputs) describes the output produced by the pipeline. +This document describes the output produced by the pipeline. -The directories listed in the above link will be created in the results directory after the pipeline has finished. All paths are relative to the top-level results directory. +The directories listed below will be created in the results directory after the pipeline has finished. All paths are relative to the top-level results directory. + +1. A `{sample}.zarr` directory containing a [SpatialData](https://spatialdata.scverse.org/en/stable/) object, where the `sample` name is either (i) specified by the samplesheet, or (ii) based on the name of the corresponding input directory. Refer to the [SpatialData docs](https://spatialdata.scverse.org/en/stable/) for usage details. If you are not familiar with `SpatialData`, you can also use directly the extracted `AnnData` object (see below). +2. A Xenium Explorer directory named `{sample}.explorer`. It contains a `report.html` with Sopa quality controls, `adata.h5ad` the AnnData object (extracted from the above SpatialData object), and `experiment.xenium` (double-click on it to open it on the Xenium Explorer ; you can download the software [here](https://www.10xgenomics.com/support/software/xenium-explorer/downloads)). The other files are data files related and required by the Xenium Explorer. ## Pipeline overview diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..2d6842e --- /dev/null +++ b/tests/README.md @@ -0,0 +1,24 @@ +# Tests + +The `samplesheet.csv` is technology-agnostic, and uses synthetic data generated when running the pipeline. + +## Visium HD specific case + +There is an exception for Visium HD data, as it requires to run SpaceRanger before Sopa, and the corresponding samplesheet require more arguments. + +The `samplesheet_visium_hd.csv` is made for [this sample](https://www.10xgenomics.com/datasets/visium-hd-cytassist-gene-expression-human-lung-cancer-fixed-frozen). The corresponding data can be downloading via: + +```sh +mkdir Visium_HD_Human_Lung_Cancer_Fixed_Frozen +cd Visium_HD_Human_Lung_Cancer_Fixed_Frozen + +# Input Files +curl -O https://cf.10xgenomics.com/samples/spatial-exp/3.1.1/Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_image.tif +curl -O https://cf.10xgenomics.com/samples/spatial-exp/3.1.1/Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_tissue_image.btf +curl -O https://cf.10xgenomics.com/samples/spatial-exp/3.1.1/Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_alignment_file.json +curl -O https://s3-us-west-2.amazonaws.com/10x.files/samples/spatial-exp/3.1.1/Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_fastqs.tar +curl -O https://cf.10xgenomics.com/samples/spatial-exp/3.1.1/Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_probe_set.csv + +# untar FASTQs +tar xvf Visium_HD_Human_Lung_Cancer_Fixed_Frozen_fastqs.tar +``` diff --git a/tests/samplesheet_fastq.csv b/tests/samplesheet_fastq.csv deleted file mode 100644 index b026106..0000000 --- a/tests/samplesheet_fastq.csv +++ /dev/null @@ -1,2 +0,0 @@ -sample,fastq_dir,cytaimage,slide,area -CytAssist_11mm_FFPE_Human_Glioblastoma_2,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/fastq_dir.tar.gz,https://raw.githubusercontent.com/nf-core/test-datasets/spatialtranscriptomics/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_image.tif,V52Y10-317,B1 diff --git a/tests/samplesheet_visium_hd.csv b/tests/samplesheet_visium_hd.csv new file mode 100644 index 0000000..00acae2 --- /dev/null +++ b/tests/samplesheet_visium_hd.csv @@ -0,0 +1,2 @@ +sample,fastq_dir,image,cytaimage,slide,area +Visium_HD_Human_Lung_Cancer_Fixed_Frozen,Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_fastqs,Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_tissue_image.btf,Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_image.tif,H1-TY834G7,D1 From a3eafbaa973a4cdc9eec32f5e535c16fbe079860 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 10 Jul 2025 09:43:03 +0200 Subject: [PATCH 097/227] run nf-core lint --- ro-crate-metadata.json | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index ff16b8b..c42f549 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "InProgress", "datePublished": "2025-07-09T19:52:43+00:00", - "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is a bioinformatics pipeline that ...\n\n\n\n\n\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\n\n\nNow, you can run the pipeline using:\n\n\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n

    \n \"sopa_overview\"\n

    \n\n\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\nThen, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config). Follow the README instructions of the latter link to get your `--configfile`.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n --configfile \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" @@ -115,7 +115,11 @@ }, { "@id": "main.nf", - "@type": ["File", "SoftwareSourceCode", "ComputationalWorkflow"], + "@type": [ + "File", + "SoftwareSourceCode", + "ComputationalWorkflow" + ], "creator": [ { "@id": "https://orcid.org/0000-0002-3836-2889" @@ -133,21 +137,30 @@ "spatial-transcriptomics", "spatialdata" ], - "license": ["MIT"], + "license": [ + "MIT" + ], "maintainer": [ { "@id": "https://orcid.org/0000-0002-3836-2889" } ], - "name": ["nf-core/sopa"], + "name": [ + "nf-core/sopa" + ], "programmingLanguage": { "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow" }, "sdPublisher": { "@id": "https://nf-co.re/" }, - "url": ["https://github.com/nf-core/sopa", "https://nf-co.re/sopa/dev/"], - "version": ["1.0.0dev"] + "url": [ + "https://github.com/nf-core/sopa", + "https://nf-co.re/sopa/dev/" + ], + "version": [ + "1.0.0dev" + ] }, { "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow", @@ -300,4 +313,4 @@ "name": "Quentin Blampey" } ] -} +} \ No newline at end of file From 7c8d84bae3b556203b06ca28ff307e891d8566b2 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 10 Jul 2025 09:55:38 +0200 Subject: [PATCH 098/227] update spaceranger count --- modules.json | 2 +- modules/nf-core/spaceranger/count/main.nf | 14 +++-- modules/nf-core/spaceranger/count/meta.yml | 48 ++++++++++++----- .../spaceranger/count/tests/main.nf.test | 24 ++++----- .../spaceranger/count/tests/main.nf.test.snap | 52 ++++++++----------- 5 files changed, 79 insertions(+), 61 deletions(-) diff --git a/modules.json b/modules.json index 4a44f9d..d60ea67 100644 --- a/modules.json +++ b/modules.json @@ -7,7 +7,7 @@ "nf-core": { "spaceranger/count": { "branch": "master", - "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", + "git_sha": "41dfa3f7c0ffabb96a6a813fe321c6d1cc5b6e46", "installed_by": ["modules"] }, "untar": { diff --git a/modules/nf-core/spaceranger/count/main.nf b/modules/nf-core/spaceranger/count/main.nf index fb6733b..6d882b2 100644 --- a/modules/nf-core/spaceranger/count/main.nf +++ b/modules/nf-core/spaceranger/count/main.nf @@ -2,15 +2,15 @@ process SPACERANGER_COUNT { tag "$meta.id" label 'process_high' - container "nf-core/modules/spaceranger:d71611e316a8614b" + container "nf-core/spaceranger:3.1.3" input: - tuple val(meta), path(reads), path(image), path(cytaimage), path(darkimage), path(colorizedimage), path(alignment), path(slidefile) + tuple val(meta), path(reads), path(image), val(slide), val(area), path(cytaimage), path(darkimage), path(colorizedimage), path(alignment), path(slidefile) path(reference) path(probeset) output: - tuple val(meta), path("outs"), emit: outs + tuple val(meta), path("outs/**"), emit: outs path "versions.yml", emit: versions when: @@ -31,17 +31,21 @@ process SPACERANGER_COUNT { def cytaimage = cytaimage ? "--cytaimage=\"${cytaimage}\"" : "" def darkimage = darkimage ? "--darkimage=\"${darkimage}\"" : "" def colorizedimage = colorizedimage ? "--colorizedimage=\"${colorizedimage}\"" : "" + if (slide.matches("visium-(.*)") && area == "" && slidefile == "") { + slide_and_area = "--unknown-slide=\"${slide}\"" + } else { + slide_and_area = "--slide=\"${slide}\" --area=\"${area}\"" + } """ spaceranger count \\ --id="${prefix}" \\ --sample="${meta.id}" \\ --fastqs=. \\ - --slide="${meta.slide}" \\ - --area="${meta.area}" \\ --transcriptome="${reference}" \\ --localcores=${task.cpus} \\ --localmem=${task.memory.toGiga()} \\ $image $cytaimage $darkimage $colorizedimage \\ + $slide_and_area \\ $probeset \\ $alignment \\ $slidefile \\ diff --git a/modules/nf-core/spaceranger/count/meta.yml b/modules/nf-core/spaceranger/count/meta.yml index e1ffcef..cf6efb5 100644 --- a/modules/nf-core/spaceranger/count/meta.yml +++ b/modules/nf-core/spaceranger/count/meta.yml @@ -37,10 +37,18 @@ input: List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. pattern: "${Sample_Name}_S1_L00${Lane_Number}_${I1,I2,R1,R2}_001.fastq.gz" + ontologies: [] - image: type: file description: Brightfield tissue H&E image in JPEG or TIFF format. pattern: "*.{tif,tiff,jpg,jpeg}" + ontologies: [] + - slide: + type: string + description: Visium slide ID used for the sample. + - area: + type: string + description: Visium slide capture area used for the sample. - cytaimage: type: file description: | @@ -48,12 +56,14 @@ input: frame in TIFF format. The size of this image is set at 3k in both dimensions and this image should not be modified any way before passing it as input to either Space Ranger or Loupe Browser. pattern: "*.{tif,tiff}" + ontologies: [] - darkimage: type: file description: | Optional for dark background fluorescence microscope image input. Multi-channel, dark-background fluorescence image as either a single, multi-layer TIFF file or as multiple TIFF or JPEG files. pattern: "*.{tif,tiff,jpg,jpeg}" + ontologies: [] - colorizedimage: type: file description: | @@ -61,24 +71,31 @@ input: A color composite of one or more fluorescence image channels saved as a single-page, single-file color TIFF or JPEG. pattern: "*.{tif,tiff,jpg,jpeg}" + ontologies: [] - alignment: type: file description: OPTIONAL - Path to manual image alignment. pattern: "*.json" + ontologies: + - edam: http://edamontology.org/format_3464 # JSON - slidefile: type: file description: OPTIONAL - Path to slide specifications. pattern: "*.json" - - - reference: - type: directory - description: Folder containing all the reference indices needed by Space Ranger - - - probeset: - type: file - description: OPTIONAL - Probe set specification. - pattern: "*.csv" + ontologies: + - edam: http://edamontology.org/format_3464 # JSON + - reference: + type: directory + description: Folder containing all the reference indices needed by Space Ranger + - probeset: + type: file + description: OPTIONAL - Probe set specification. + pattern: "*.csv" + ontologies: + - edam: http://edamontology.org/format_3752 # CSV output: - - outs: - - meta: + outs: + - - meta: type: map description: | Groovy Map containing sample information @@ -88,11 +105,14 @@ output: description: Files containing the outputs of Space Ranger, see official 10X Genomics documentation for a complete list pattern: "outs/*" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@grst" maintainers: diff --git a/modules/nf-core/spaceranger/count/tests/main.nf.test b/modules/nf-core/spaceranger/count/tests/main.nf.test index 49a9d5f..3d65e68 100644 --- a/modules/nf-core/spaceranger/count/tests/main.nf.test +++ b/modules/nf-core/spaceranger/count/tests/main.nf.test @@ -43,15 +43,15 @@ nextflow_process { """ input[0] = [ [ - id: 'Visium_FFPE_Human_Ovarian_Cancer', - slide: 'V10L13-020', - area: 'D1' + id: 'Visium_FFPE_Human_Ovarian_Cancer' ], // Meta map [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-ovarian-cancer-1-standard_v1_ffpe/Visium_FFPE_Human_Ovarian_Cancer_S1_L001_R1_001.fastq.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-ovarian-cancer-1-standard_v1_ffpe/Visium_FFPE_Human_Ovarian_Cancer_S1_L001_R2_001.fastq.gz', checkIfExists: true) ], // Reads file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-ovarian-cancer-1-standard_v1_ffpe/Visium_FFPE_Human_Ovarian_Cancer_image.jpg', checkIfExists: true), // Image + 'V10L13-020', // Slide + 'D1', // Area [], // Cytaimage [], // Darkimage [], // Colorizedimage @@ -68,7 +68,7 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - path(process.out.versions.get(0)).yaml, + process.out.versions, process.out.outs.get(0).get(1).findAll { file(it).name !in [ 'web_summary.html', 'scalefactors_json.json', @@ -120,15 +120,15 @@ nextflow_process { """ input[0] = [ [ - id: 'Visium_FFPE_Human_Ovarian_Cancer', - slide: 'V10L13-020', - area: 'D1' + id: 'Visium_FFPE_Human_Ovarian_Cancer' ], // Meta map [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-ovarian-cancer-1-standard_v1_ffpe/Visium_FFPE_Human_Ovarian_Cancer_S1_L001_R1_001.fastq.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-ovarian-cancer-1-standard_v1_ffpe/Visium_FFPE_Human_Ovarian_Cancer_S1_L001_R2_001.fastq.gz', checkIfExists: true) ], // Reads file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-ovarian-cancer-1-standard_v1_ffpe/Visium_FFPE_Human_Ovarian_Cancer_image.jpg', checkIfExists: true), // Image + 'V10L13-020', // Slide + 'D1', // Area [], // Cytaimage [], // Darkimage [], // Colorizedimage @@ -144,7 +144,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(path(process.out.versions.get(0)).yaml).match() }, + { assert snapshot(process.out.versions).match() }, ) } } @@ -179,15 +179,15 @@ nextflow_process { """ input[0] = [ [ - id: 'CytAssist_11mm_FFPE_Human_Glioblastoma_2', - slide: 'V52Y10-317', - area: 'B1' + id: 'CytAssist_11mm_FFPE_Human_Glioblastoma_2' ], // Meta map [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_2_S1_L001_R1_001.fastq.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_2_S1_L001_R2_001.fastq.gz', checkIfExists: true) ], // Reads [], // Image + 'V52Y10-317', // Slide + 'B1', // Area file(params.modules_testdata_base_path + 'genomics/homo_sapiens/10xgenomics/spaceranger/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/CytAssist_11mm_FFPE_Human_Glioblastoma_image.tif', checkIfExists: true), // Cytaimage [], // Darkimage [], // Colorizedimage @@ -204,7 +204,7 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - path(process.out.versions.get(0)).yaml, + process.out.versions, process.out.outs.get(0).get(1).findAll { file(it).name !in [ 'web_summary.html', 'scalefactors_json.json', diff --git a/modules/nf-core/spaceranger/count/tests/main.nf.test.snap b/modules/nf-core/spaceranger/count/tests/main.nf.test.snap index 7a49d45..dbfaadf 100644 --- a/modules/nf-core/spaceranger/count/tests/main.nf.test.snap +++ b/modules/nf-core/spaceranger/count/tests/main.nf.test.snap @@ -1,25 +1,21 @@ { "spaceranger v1 (stub) - homo_sapiens - fasta - gtf - fastq - tif - csv": { "content": [ - { - "SPACERANGER_COUNT": { - "spaceranger": "3.1.2" - } - } + [ + "versions.yml:md5,4abe169f33d7f99d5d9876b189060aae" + ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.1" + "nf-test": "0.9.1", + "nextflow": "24.10.4" }, - "timestamp": "2024-11-26T01:48:31.348979531" + "timestamp": "2025-02-13T09:02:47.710975472" }, "spaceranger v2 - homo_sapiens - fasta - gtf - fastq - tif - csv": { "content": [ - { - "SPACERANGER_COUNT": { - "spaceranger": "3.1.2" - } - }, + [ + "versions.yml:md5,4abe169f33d7f99d5d9876b189060aae" + ], [ "clusters.csv:md5,221a4554e62ea94b0df8dbf637d2c13c", "clusters.csv:md5,53ee76645943b5562392aac51d2d9f3f", @@ -48,10 +44,10 @@ "variance.csv:md5,4159711ab5d64e97737fad9d75d945b3", "projection.csv:md5,ce729f7e237df4570ac3e4a79251df24", "projection.csv:md5,fa7bdefa8424b233fe6461129ab76d57", - "filtered_feature_bc_matrix.h5:md5,f625d7e2c063c8c079ccc35a853b356d", + "filtered_feature_bc_matrix.h5:md5,704256e5150522d9cf2e75e7e47221b6", "metrics_summary.csv:md5,5ece84f5f8e08839749b1c8f2bff6701", "probe_set.csv:md5,5bfb8f12319be1b2b6c14142537c3804", - "raw_feature_bc_matrix.h5:md5,90575715eb252f0b652c9d36a1f5628e", + "raw_feature_bc_matrix.h5:md5,ac24486662643ea68562c1a51cbbb2bd", "raw_probe_bc_matrix.h5:md5,8ab08437814506f98e3f10107cfc38ac", "aligned_fiducials.jpg:md5,51dcc3a32d3d5ca4704f664c8ede81ef", "cytassist_image.tiff:md5,0fb04a55e5658f4d158d986a334b034d", @@ -63,23 +59,21 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.1" + "nf-test": "0.9.1", + "nextflow": "24.10.4" }, - "timestamp": "2024-11-26T01:58:16.555517048" + "timestamp": "2025-02-12T11:24:51.984883864" }, "spaceranger v1 - homo_sapiens - fasta - gtf - fastq - tif - csv": { "content": [ - { - "SPACERANGER_COUNT": { - "spaceranger": "3.1.2" - } - }, [ - "filtered_feature_bc_matrix.h5:md5,a756f6dda550f52f9fb3e347207a2c6c", + "versions.yml:md5,4abe169f33d7f99d5d9876b189060aae" + ], + [ + "filtered_feature_bc_matrix.h5:md5,649ac955bcb372b0b767013071cca72c", "metrics_summary.csv:md5,38774fc5f54873d711b4898a2dd50e72", - "molecule_info.h5:md5,9e6393dbbccdfe58edf9e92181261f88", - "raw_feature_bc_matrix.h5:md5,860702876f936f89fdcec2b5f599a7d2", + "molecule_info.h5:md5,88bb948a426041165b2cc5fe8b180c21", + "raw_feature_bc_matrix.h5:md5,63324ae38fbf28bcc2114f170e0fde5d", "aligned_fiducials.jpg:md5,f6217ddd707bb189e665f56b130c3da8", "detected_tissue_image.jpg:md5,c1c7e8741701a576c1ec103c1aaf98ea", "tissue_hires_image.png:md5,d91f8f176ae35ab824ede87117ac0889", @@ -88,9 +82,9 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.1" + "nf-test": "0.9.1", + "nextflow": "24.10.4" }, - "timestamp": "2024-11-26T01:48:13.569651476" + "timestamp": "2025-02-12T11:08:30.165324139" } } \ No newline at end of file From f61c7fda8f625ced29b04cc9d5631156c4ec58bf Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 10 Jul 2025 10:11:50 +0200 Subject: [PATCH 099/227] use relative path for tests --- .gitignore | 2 ++ tests/samplesheet.csv | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index cf06435..abaf004 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ null/ sandbox samplesheets lint_* +.nf-test* +*nf.test* diff --git a/tests/samplesheet.csv b/tests/samplesheet.csv index 10e7f31..73f269f 100644 --- a/tests/samplesheet.csv +++ b/tests/samplesheet.csv @@ -1,2 +1,2 @@ data_path -tests/sample1 +../../../tests/sample1 From 6c95feab9d6d5fbc4e2f5c48d822d8f4e2038141 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 10 Jul 2025 11:25:52 +0200 Subject: [PATCH 100/227] less lint warnings --- modules.json | 8 ++++---- modules/nf-core/untar/meta.yml | 19 ++++++++++++------- subworkflows/local/baysor/main.nf | 2 +- subworkflows/local/cellpose/main.nf | 2 +- subworkflows/local/proseg/main.nf | 2 +- subworkflows/local/stardist/main.nf | 2 +- .../utils_nextflow_pipeline/tests/tags.yml | 2 -- .../utils_nfcore_pipeline/tests/tags.yml | 2 -- .../tests/nextflow.config | 2 +- workflows/sopa.nf | 16 ++++++++-------- 10 files changed, 29 insertions(+), 28 deletions(-) delete mode 100644 subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml delete mode 100644 subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml diff --git a/modules.json b/modules.json index d60ea67..43f1034 100644 --- a/modules.json +++ b/modules.json @@ -12,7 +12,7 @@ }, "untar": { "branch": "master", - "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", + "git_sha": "41dfa3f7c0ffabb96a6a813fe321c6d1cc5b6e46", "installed_by": ["modules"] } } @@ -21,17 +21,17 @@ "nf-core": { "utils_nextflow_pipeline": { "branch": "master", - "git_sha": "c2b22d85f30a706a3073387f30380704fcae013b", + "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", "installed_by": ["subworkflows"] }, "utils_nfcore_pipeline": { "branch": "master", - "git_sha": "51ae5406a030d4da1e49e4dab49756844fdd6c7a", + "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", "installed_by": ["subworkflows"] }, "utils_nfschema_plugin": { "branch": "master", - "git_sha": "2fd2cd6d0e7b273747f32e465fdc6bcc3ae0814e", + "git_sha": "dcd088f483cede0c3df4034d405126f05a764cc7", "installed_by": ["subworkflows"] } } diff --git a/modules/nf-core/untar/meta.yml b/modules/nf-core/untar/meta.yml index 3a37bb3..1b6bf49 100644 --- a/modules/nf-core/untar/meta.yml +++ b/modules/nf-core/untar/meta.yml @@ -21,9 +21,12 @@ input: type: file description: File to be untar pattern: "*.{tar}.{gz}" + ontologies: + - edam: http://edamontology.org/format_3981 # TAR format + - edam: http://edamontology.org/format_3989 # GZIP format output: - - untar: - - meta: + untar: + - - meta: type: map description: | Groovy Map containing sample information @@ -35,11 +38,13 @@ output: Groovy Map containing sample information e.g. [ id:'test', single_end:false ] pattern: "*/" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@joseespinosa" - "@drpatelh" diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index 9e600cb..b719925 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -1,6 +1,6 @@ include { ArgsCLI } from '../../../modules/local/utils' -workflow baysor { +workflow BAYSOR { take: ch_patches config diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index c4586f6..f7c38d4 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -1,6 +1,6 @@ include { ArgsCLI } from '../../../modules/local/utils' -workflow cellpose { +workflow CELLPOSE { take: ch_patches config diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index c8400ff..035582b 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -1,6 +1,6 @@ include { ArgsCLI } from '../../../modules/local/utils' -workflow proseg { +workflow PROSEG { take: ch_patches config diff --git a/subworkflows/local/stardist/main.nf b/subworkflows/local/stardist/main.nf index 2340a59..c67f481 100644 --- a/subworkflows/local/stardist/main.nf +++ b/subworkflows/local/stardist/main.nf @@ -1,6 +1,6 @@ include { ArgsCLI } from '../../../modules/local/utils' -workflow stardist { +workflow STARDIST { take: ch_patches config diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml b/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml deleted file mode 100644 index f847611..0000000 --- a/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -subworkflows/utils_nextflow_pipeline: - - subworkflows/nf-core/utils_nextflow_pipeline/** diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml b/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml deleted file mode 100644 index ac8523c..0000000 --- a/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -subworkflows/utils_nfcore_pipeline: - - subworkflows/nf-core/utils_nfcore_pipeline/** diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config index 09ef842..443e828 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config @@ -5,4 +5,4 @@ plugins { validation { parametersSchema = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" monochromeLogs = true -} \ No newline at end of file +} diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 6ee9e3a..590d137 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -6,10 +6,10 @@ include { paramsSummaryMap } from 'plugin/nf-schema' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_sopa_pipeline' -include { cellpose } from '../subworkflows/local/cellpose' -include { stardist } from '../subworkflows/local/stardist' -include { baysor } from '../subworkflows/local/baysor' -include { proseg } from '../subworkflows/local/proseg' +include { CELLPOSE } from '../subworkflows/local/cellpose' +include { STARDIST } from '../subworkflows/local/stardist' +include { BAYSOR } from '../subworkflows/local/baysor' +include { PROSEG } from '../subworkflows/local/proseg' include { readConfigFile } from '../modules/local/utils' include { ArgsCLI } from '../modules/local/utils' include { ArgsReaderCLI } from '../modules/local/utils' @@ -54,26 +54,26 @@ workflow SOPA { if (config.segmentation.cellpose) { (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) - ch_resolved = cellpose(ch_image_patches, config) + ch_resolved = CELLPOSE(ch_image_patches, config) } if (config.segmentation.stardist) { (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) - ch_resolved = stardist(ch_image_patches, config) + ch_resolved = STARDIST(ch_image_patches, config) } if (config.segmentation.baysor) { ch_input_baysor = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg ch_transcripts_patches = makeTranscriptPatches(ch_input_baysor, transcriptPatchesArgs(config, "baysor")) - ch_resolved = baysor(ch_transcripts_patches, config) + ch_resolved = BAYSOR(ch_transcripts_patches, config) } if (config.segmentation.proseg) { ch_input_proseg = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg ch_proseg_patches = makeTranscriptPatches(ch_input_proseg, transcriptPatchesArgs(config, "proseg")) - ch_resolved = proseg(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, config) + ch_resolved = PROSEG(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, config) } (ch_aggregated, _out) = aggregate(ch_resolved, ArgsCLI(config.aggregate)) From 6ee7ce5e5ca36932833be2c02460ee3a233fb380 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 10 Jul 2025 11:38:36 +0200 Subject: [PATCH 101/227] test with proseg --- conf/test.config | 2 +- conf/test_vhd.config | 30 ------------------------------ 2 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 conf/test_vhd.config diff --git a/conf/test.config b/conf/test.config index 2f11d39..5a75102 100644 --- a/conf/test.config +++ b/conf/test.config @@ -24,5 +24,5 @@ params { // Input data input = "${baseDir}/tests/samplesheet.csv" - configfile = "${baseDir}/tests/config/cellpose.yaml" + configfile = "https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/toy/proseg.yaml" } diff --git a/conf/test_vhd.config b/conf/test_vhd.config deleted file mode 100644 index 1f3daf8..0000000 --- a/conf/test_vhd.config +++ /dev/null @@ -1,30 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Nextflow config file for running minimal tests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Defines input files and everything required to run a fast and simple pipeline test. - - Use as follows: - nextflow run nf-core/sopa -profile test, --outdir - ----------------------------------------------------------------------------------------- -*/ - -process { - resourceLimits = [ - cpus: 4, - memory: '15.GB', - time: '1.h', - ] -} - -params { - config_profile_name = 'Test profile for Visium HD data' - config_profile_description = 'Minimal test dataset to check pipeline function' - - // Input data - input = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/samplesheet_spaceranger.csv" - spaceranger_probeset = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/human-brain-cancer-11-mm-capture-area-ffpe-2-standard_v2_ffpe_cytassist/outs/probe_set.csv" - spaceranger_reference = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialvi/testdata/homo_sapiens_chr22_reference.tar.gz" - configfile = "${baseDir}/toy/vhd_stardist.yaml" -} From cc8b74e4574a3d8081ca2e27c88d19aac2e25f86 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 10 Jul 2025 12:05:41 +0200 Subject: [PATCH 102/227] remove unused configs and add citations --- .../local/utils_nfcore_sopa_pipeline/main.nf | 32 +++++----- tests/config/baysor.yaml | 53 ---------------- tests/config/baysor_overlaps.yaml | 53 ---------------- tests/config/baysor_vizgen.yaml | 57 ------------------ tests/config/cellpose.yaml | 34 ----------- tests/config/cellpose_baysor.yaml | 60 ------------------- tests/config/cellpose_comseg.yaml | 52 ---------------- tests/config/comseg.yaml | 46 -------------- tests/config/proseg.yaml | 30 ---------- tests/config/tissue_cellpose.yaml | 37 ------------ tests/config/vhd_stardist.yaml | 18 ------ tests/config/xenium_proseg.yaml | 22 ------- 12 files changed, 17 insertions(+), 477 deletions(-) delete mode 100644 tests/config/baysor.yaml delete mode 100644 tests/config/baysor_overlaps.yaml delete mode 100644 tests/config/baysor_vizgen.yaml delete mode 100644 tests/config/cellpose.yaml delete mode 100644 tests/config/cellpose_baysor.yaml delete mode 100644 tests/config/cellpose_comseg.yaml delete mode 100644 tests/config/comseg.yaml delete mode 100644 tests/config/proseg.yaml delete mode 100644 tests/config/tissue_cellpose.yaml delete mode 100644 tests/config/vhd_stardist.yaml delete mode 100644 tests/config/xenium_proseg.yaml diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index 1e449dd..e62c2d2 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -66,8 +66,7 @@ workflow PIPELINE_INITIALISATION { // Create channel from input file provided through params.input // - Channel - .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + Channel.fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) .map { meta, data_path -> if (!meta.fastq_dir) { if (!data_path) { @@ -168,22 +167,29 @@ def validateInputSamplesheet(input) { // Generate methods description for MultiQC // def toolCitationText() { - // TODO nf-core: Optionally add in-text citation tools to this list. - // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "Tool (Foo et al. 2023)" : "", - // Uncomment function in methodsDescriptionText to render in MultiQC report def citation_text = [ "Tools used in the workflow included:", - ".", + "Sopa (Blampey et al. 2024),", + "AnnData (Virshup et al. 2021),", + "Scanpy (Wolf et al. 2018),", + "Space Ranger (10x Genomics)", + "SpatialData (Marconato et al. 2023) and", ].join(' ').trim() return citation_text } def toolBibliographyText() { - // TODO nf-core: Optionally add bibliographic entries to this list. - // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "
  • Author (2023) Pub name, Journal, DOI
  • " : "", - // Uncomment function in methodsDescriptionText to render in MultiQC report def reference_text = [ + '
  • Di Tommaso, P., Chatzou, M., Floden, E. W., Barja, P. P., Palumbo, E., & Notredame, C. (2017). Nextflow enables reproducible computational workflows. Nature Biotechnology, 35(4), 316-319. doi: 10.1038/nbt.3820
  • ', + '
  • Ewels, P. A., Peltzer, A., Fillinger, S., Patel, H., Alneberg, J., Wilm, A., Garcia, M. U., Di Tommaso, P., & Nahnsen, S. (2020). The nf-core framework for community-curated bioinformatics pipelines. Nature Biotechnology, 38(3), 276-278. doi: 10.1038/s41587-020-0439-x
  • ', + '
  • Grüning, B., Dale, R., Sjödin, A., Chapman, B. A., Rowe, J., Tomkins-Tinch, C. H., Valieris, R., Köster, J., & Bioconda Team. (2018). Bioconda: sustainable and comprehensive software distribution for the life sciences. Nature Methods, 15(7), 475–476. doi: 10.1038/s41592-018-0046-7
  • ', + '
  • da Veiga Leprevost, F., Grüning, B. A., Alves Aflitos, S., Röst, H. L., Uszkoreit, J., Barsnes, H., Vaudel, M., Moreno, P., Gatto, L., Weber, J., Bai, M., Jimenez, R. C., Sachsenberg, T., Pfeuffer, J., Vera Alvarez, R., Griss, J., Nesvizhskii, A. I., & Perez-Riverol, Y. (2017). BioContainers: an open-source and community-driven framework for software standardization. Bioinformatics (Oxford, England), 33(16), 2580–2582. doi: 10.1093/bioinformatics/btx192
  • ', + '
  • Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice André, Florent Ginhoux & Paul-Henry Cournède. Sopa: a technology-invariant pipeline for analyses of image-based spatial omics. Nat Commun 2024 June 11. doi: 10.1038/s41587-020-0439-x
  • ', + '
  • Virshup I, Rybakov S, Theis FJ, Angerer P, Wolf FA. bioRxiv 2021.12.16.473007. doi: 10.1101/2021.12.16.473007
  • ', + '
  • Wolf F, Angerer P, Theis F. SCANPY: large-scale single-cell gene expression data analysis. Genome Biol 19, 15 (2018). doi: 10.1186/s13059-017-1382-0
  • ', + '
  • 10x Genomics Space Ranger 2.1.0 [Online]: 10xgenomics.com/support/software/space-ranger
  • ', + '
  • Marconato L, Palla G, Yamauchi K, Virshup I, Heidari E, Treis T, Toth M, Shrestha R, Vöhringer H, Huber W, Gerstung M, Moore J, Theis F, Stegle O. SpatialData: an open and universal data framework for spatial omics. bioRxiv 2023.05.05.539647; doi: 10.1101/2023.05.05.539647
  • ', ].join(' ').trim() return reference_text @@ -213,12 +219,8 @@ def methodsDescriptionText(mqc_methods_yaml) { meta["nodoi_text"] = meta.manifest_map.doi ? "" : "
  • If available, make sure to update the text to include the Zenodo DOI of version of the pipeline used.
  • " // Tool references - meta["tool_citations"] = "" - meta["tool_bibliography"] = "" - - // TODO nf-core: Only uncomment below if logic in toolCitationText/toolBibliographyText has been filled! - // meta["tool_citations"] = toolCitationText().replaceAll(", \\.", ".").replaceAll("\\. \\.", ".").replaceAll(", \\.", ".") - // meta["tool_bibliography"] = toolBibliographyText() + meta["tool_citations"] = toolCitationText().replaceAll(", \\.", ".").replaceAll("\\. \\.", ".").replaceAll(", \\.", ".") + meta["tool_bibliography"] = toolBibliographyText() def methods_text = mqc_methods_yaml.text diff --git a/tests/config/baysor.yaml b/tests/config/baysor.yaml deleted file mode 100644 index 36c3727..0000000 --- a/tests/config/baysor.yaml +++ /dev/null @@ -1,53 +0,0 @@ -# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml -read: - technology: toy_dataset - -patchify: - patch_width_pixel: 1200 - patch_overlap_pixel: 50 - patch_width_microns: 400 - patch_overlap_microns: 20 - -segmentation: - baysor: - min_area: 10 - - config: - data: - force_2d: true - min_molecules_per_cell: 10 - x: "x" - y: "y" - z: "z" - gene: "genes" - min_molecules_per_gene: 0 - min_molecules_per_segment: 3 - confidence_nn_id: 6 - - segmentation: - scale: 3 # typical cell radius in microns - scale_std: "25%" # cell radius standard deviation - prior_segmentation_confidence: 0 - estimate_scale_from_centers: false - n_clusters: 4 - iters: 500 - n_cells_init: 0 - nuclei_genes: "" - cyto_genes: "" - -aggregate: - average_intensities: true - min_transcripts: 5 # [optional] cells whose transcript count is below that this threshold are filtered - -annotation: - method: fluorescence - args: - marker_cell_dict: - CK: Tumoral cell - CD3: T cell - CD20: B cell - -explorer: - gene_column: "genes" - ram_threshold_gb: 4 - pixel_size: 0.1 diff --git a/tests/config/baysor_overlaps.yaml b/tests/config/baysor_overlaps.yaml deleted file mode 100644 index 1fc7049..0000000 --- a/tests/config/baysor_overlaps.yaml +++ /dev/null @@ -1,53 +0,0 @@ -# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml -read: - technology: toy_dataset - -patchify: - patch_width_pixel: 1200 - patch_overlap_pixel: 50 - patch_width_microns: 150 - patch_overlap_microns: 10 - -segmentation: - baysor: - min_area: 10 - - config: - data: - force_2d: true - min_molecules_per_cell: 10 - x: "x" - y: "y" - z: "z" - gene: "genes" - min_molecules_per_gene: 0 - min_molecules_per_segment: 3 - confidence_nn_id: 6 - - segmentation: - scale: 3 # typical cell radius in microns - scale_std: "25%" # cell radius standard deviation - prior_segmentation_confidence: 0 - estimate_scale_from_centers: false - n_clusters: 4 - iters: 500 - n_cells_init: 0 - nuclei_genes: "" - cyto_genes: "" - -aggregate: - average_intensities: true - min_transcripts: 5 # [optional] cells whose transcript count is below that this threshold are filtered - -annotation: - method: fluorescence - args: - marker_cell_dict: - CK: Tumoral cell - CD3: T cell - CD20: B cell - -explorer: - gene_column: "genes" - ram_threshold_gb: 4 - pixel_size: 0.1 diff --git a/tests/config/baysor_vizgen.yaml b/tests/config/baysor_vizgen.yaml deleted file mode 100644 index 819e727..0000000 --- a/tests/config/baysor_vizgen.yaml +++ /dev/null @@ -1,57 +0,0 @@ -# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml -read: - technology: toy_dataset - kwargs: - transcript_cell_id_as_merscope: true - -patchify: - patch_width_pixel: 1200 - patch_overlap_pixel: 50 - patch_width_microns: 400 - patch_overlap_microns: 20 - -segmentation: - baysor: - min_area: 10 - prior_shapes_key: "cell_id" - unassigned_value: -1 - - config: - data: - force_2d: true - min_molecules_per_cell: 10 - x: "x" - y: "y" - z: "z" - gene: "genes" - min_molecules_per_gene: 0 - min_molecules_per_segment: 3 - confidence_nn_id: 6 - - segmentation: - scale: 3 # typical cell radius in microns - scale_std: "25%" # cell radius standard deviation - prior_segmentation_confidence: 1 - estimate_scale_from_centers: false - n_clusters: 4 - iters: 500 - n_cells_init: 0 - nuclei_genes: "" - cyto_genes: "" - -aggregate: - average_intensities: true - min_transcripts: 5 # [optional] cells whose transcript count is below that this threshold are filtered - -annotation: - method: fluorescence - args: - marker_cell_dict: - CK: Tumoral cell - CD3: T cell - CD20: B cell - -explorer: - gene_column: "genes" - ram_threshold_gb: 4 - pixel_size: 0.1 diff --git a/tests/config/cellpose.yaml b/tests/config/cellpose.yaml deleted file mode 100644 index 517d582..0000000 --- a/tests/config/cellpose.yaml +++ /dev/null @@ -1,34 +0,0 @@ -# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml -read: - technology: toy_dataset - -patchify: - patch_width_pixel: 1200 - patch_overlap_pixel: 50 - patch_width_microns: 3000 - patch_overlap_microns: 40 - -segmentation: - cellpose: - diameter: 35 - channels: ["DAPI"] - flow_threshold: 2 - cellprob_threshold: -6 - min_area: 2500 - -aggregate: - average_intensities: true - gene_column: genes - -annotation: - method: fluorescence - args: - marker_cell_dict: - CK: Tumoral cell - CD3: T cell - CD20: B cell - -explorer: - gene_column: "genes" - ram_threshold_gb: 4 - pixel_size: 1 diff --git a/tests/config/cellpose_baysor.yaml b/tests/config/cellpose_baysor.yaml deleted file mode 100644 index 32fb7f8..0000000 --- a/tests/config/cellpose_baysor.yaml +++ /dev/null @@ -1,60 +0,0 @@ -# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml -read: - technology: toy_dataset - -patchify: - patch_width_pixel: 1200 - patch_overlap_pixel: 50 - patch_width_microns: 400 - patch_overlap_microns: 20 - -segmentation: - cellpose: - diameter: 35 - channels: ["DAPI"] - flow_threshold: 2 - cellprob_threshold: -6 - min_area: 2500 - - baysor: - min_area: 10 - - config: - data: - force_2d: true - min_molecules_per_cell: 10 - x: "x" - y: "y" - z: "z" - gene: "genes" - min_molecules_per_gene: 0 - min_molecules_per_segment: 3 - confidence_nn_id: 6 - - segmentation: - scale: 3 # typical cell radius in microns - scale_std: "25%" # cell radius standard deviation - prior_segmentation_confidence: 0 - estimate_scale_from_centers: false - n_clusters: 4 - iters: 500 - n_cells_init: 0 - nuclei_genes: "" - cyto_genes: "" - -aggregate: - average_intensities: true - min_transcripts: 5 # [optional] cells whose transcript count is below that this threshold are filtered - -annotation: - method: fluorescence - args: - marker_cell_dict: - CK: Tumoral cell - CD3: T cell - CD20: B cell - -explorer: - gene_column: "genes" - ram_threshold_gb: 4 - pixel_size: 0.1 diff --git a/tests/config/cellpose_comseg.yaml b/tests/config/cellpose_comseg.yaml deleted file mode 100644 index e63c683..0000000 --- a/tests/config/cellpose_comseg.yaml +++ /dev/null @@ -1,52 +0,0 @@ -# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml -read: - technology: toy_dataset - kwargs: - add_nan_gene_name: false - -patchify: - patch_width_pixel: 1200 - patch_overlap_pixel: 50 - patch_width_microns: 3000 - patch_overlap_microns: 40 - -segmentation: - cellpose: - diameter: 35 - channels: ["DAPI"] - flow_threshold: 2 - cellprob_threshold: -6 - min_area: 2500 - - comseg: - min_area: 10 - - config: - dict_scale: - x: 1 - y: 1 - z: 1 - mean_cell_diameter: 15 - max_cell_radius: 25 - allow_disconnected_polygon: false - alpha: 0.5 - min_rna_per_cell: 5 - gene_column: "genes" - norm_vector: false # [optional] requires exeternal R package '"sctransform"' "feather" and "arrow" to be installed, otherwise set to false - -aggregate: - average_intensities: true - gene_column: genes - -annotation: - method: fluorescence - args: - marker_cell_dict: - CK: Tumoral cell - CD3: T cell - CD20: B cell - -explorer: - gene_column: "genes" - ram_threshold_gb: 4 - pixel_size: 1 diff --git a/tests/config/comseg.yaml b/tests/config/comseg.yaml deleted file mode 100644 index 071a625..0000000 --- a/tests/config/comseg.yaml +++ /dev/null @@ -1,46 +0,0 @@ -# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml -read: - technology: toy_dataset - kwargs: - add_nan_gene_name: false - -patchify: - patch_width_pixel: 1200 - patch_overlap_pixel: 50 - patch_width_microns: 3000 - patch_overlap_microns: 40 - -segmentation: - comseg: - min_area: 10 - prior_shapes_key: cells - - config: - dict_scale: - x: 1 - y: 1 - z: 1 - mean_cell_diameter: 15 - max_cell_radius: 25 - allow_disconnected_polygon: false - alpha: 0.5 - min_rna_per_cell: 5 - gene_column: "genes" - norm_vector: false # [optional] requires exeternal R package '"sctransform"' "feather" and "arrow" to be installed, otherwise set to false - -aggregate: - average_intensities: true - gene_column: genes - -annotation: - method: fluorescence - args: - marker_cell_dict: - CK: Tumoral cell - CD3: T cell - CD20: B cell - -explorer: - gene_column: "genes" - ram_threshold_gb: 4 - pixel_size: 1 diff --git a/tests/config/proseg.yaml b/tests/config/proseg.yaml deleted file mode 100644 index c94e99b..0000000 --- a/tests/config/proseg.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml -read: - technology: toy_dataset - kwargs: - genes: 500 - -patchify: - patch_width_microns: -1 - patch_overlap_microns: 0 - -segmentation: - proseg: - prior_shapes_key: "cells" - -aggregate: - average_intensities: true - min_transcripts: 5 # [optional] cells whose transcript count is below that this threshold are filtered - -annotation: - method: fluorescence - args: - marker_cell_dict: - CK: Tumoral cell - CD3: T cell - CD20: B cell - -explorer: - gene_column: "genes" - ram_threshold_gb: 4 - pixel_size: 0.1 diff --git a/tests/config/tissue_cellpose.yaml b/tests/config/tissue_cellpose.yaml deleted file mode 100644 index 91b7b2c..0000000 --- a/tests/config/tissue_cellpose.yaml +++ /dev/null @@ -1,37 +0,0 @@ -# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml -read: - technology: toy_dataset - -patchify: - patch_width_pixel: 1200 - patch_overlap_pixel: 50 - patch_width_microns: 3000 - patch_overlap_microns: 40 - -segmentation: - tissue: - mode: saturation - - cellpose: - diameter: 35 - channels: ["DAPI"] - flow_threshold: 2 - cellprob_threshold: -6 - min_area: 2500 - -aggregate: - average_intensities: true - gene_column: genes - -annotation: - method: fluorescence - args: - marker_cell_dict: - CK: Tumoral cell - CD3: T cell - CD20: B cell - -explorer: - gene_column: "genes" - ram_threshold_gb: 4 - pixel_size: 1 diff --git a/tests/config/vhd_stardist.yaml b/tests/config/vhd_stardist.yaml deleted file mode 100644 index 115fa6d..0000000 --- a/tests/config/vhd_stardist.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml -read: - technology: visium_hd - -patchify: - patch_width_pixel: 2000 - patch_overlap_pixel: 50 - -segmentation: - stardist: - min_area: 30 - -aggregate: - aggregate_channels: true - min_transcripts: 10 # [optional] cells whose transcript count is below that this threshold are filtered - -explorer: - ram_threshold_gb: 4 diff --git a/tests/config/xenium_proseg.yaml b/tests/config/xenium_proseg.yaml deleted file mode 100644 index 6097bab..0000000 --- a/tests/config/xenium_proseg.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Using the 10X Genomics multi-channel segmentation as a prior for Proseg. - -# For parameters details, see this commented example: https://github.com/gustaveroussy/sopa/blob/master/workflow/config/example_commented.yaml -read: - technology: xenium - -patchify: - patch_width_microns: -1 - patch_overlap_microns: 20 - -segmentation: - proseg: - prior_shapes_key: cell_id # this allows to use the prior segmentation performed by 10X Genomics - unassigned_value: UNASSIGNED - -aggregate: - average_intensities: true - min_transcripts: 10 # [optional] cells whose transcript count is below that this threshold are filtered - -explorer: - gene_column: "feature_name" - ram_threshold_gb: 4 From 8c298bf282b0ef1772c3d0482056943b98449536 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 11 Jul 2025 09:16:35 +0200 Subject: [PATCH 103/227] use mqc version output and try fix vhd --- workflows/sopa.nf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 590d137..47552d1 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -33,7 +33,7 @@ workflow SOPA { if (config.read.technology == "visium_hd") { (ch_input_spatialdata, versions) = SPACERANGER(ch_samplesheet) - ch_input_spatialdata = ch_input_spatialdata.map { meta, out -> [meta, [out, meta.image]] } + ch_input_spatialdata = ch_input_spatialdata.map { meta, out -> [meta, [out.toString().replaceFirst(/(.*?outs).*/, '$1'), meta.image]] } ch_versions = ch_versions.mix(versions) } @@ -89,7 +89,7 @@ workflow SOPA { // softwareVersionsToYAML(ch_versions).collectFile( storeDir: "${params.outdir}/pipeline_info", - name: 'nf_core_sopa_software_versions.yml', + name: 'nf_core_sopa_software_mqc_versions.yml', sort: true, newLine: true, ) From fb9dbaaf7ae81b30c3a2334f8f5c1e0a13b25513 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 11 Jul 2025 10:36:19 +0200 Subject: [PATCH 104/227] add test snap file --- .gitignore | 1 - tests/default.nf.test.snap | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tests/default.nf.test.snap diff --git a/.gitignore b/.gitignore index abaf004..d75d93b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,3 @@ sandbox samplesheets lint_* .nf-test* -*nf.test* diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap new file mode 100644 index 0000000..461a5d9 --- /dev/null +++ b/tests/default.nf.test.snap @@ -0,0 +1,19 @@ +{ + "-profile test": { + "content": [ + 0, + null, + [ + + ], + [ + + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.3" + }, + "timestamp": "2025-07-10T10:05:15.66595" + } +} \ No newline at end of file From ff51f0d04e30a4133bb8708b30c57df46f8b183c Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 11 Jul 2025 10:47:33 +0200 Subject: [PATCH 105/227] local test snap --- tests/default.nf.test.snap | 493 ++++++++++++++++++++++++++++++++++++- 1 file changed, 487 insertions(+), 6 deletions(-) diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 461a5d9..c8bdac3 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -1,19 +1,500 @@ { "-profile test": { "content": [ - 0, - null, + 8, + { + "Workflow": { + "nf-core/sopa": "v1.0.0dev" + } + }, [ - + "pipeline_info", + "pipeline_info/nf_core_sopa_software_mqc_versions.yml", + "sample1.explorer", + "sample1.explorer/adata.h5ad", + "sample1.explorer/analysis.zarr.zip", + "sample1.explorer/analysis_summary.html", + "sample1.explorer/cell_feature_matrix.zarr.zip", + "sample1.explorer/cells.zarr.zip", + "sample1.explorer/experiment.xenium", + "sample1.explorer/morphology.ome.tif", + "sample1.explorer/transcripts.zarr.zip", + "sample1.zarr", + "sample1.zarr/.sopa_cache", + "sample1.zarr/.sopa_cache/patches_file_transcripts", + "sample1.zarr/.sopa_cache/transcript_patches", + "sample1.zarr/.zattrs", + "sample1.zarr/.zgroup", + "sample1.zarr/images", + "sample1.zarr/images/.zgroup", + "sample1.zarr/images/he_image", + "sample1.zarr/images/he_image/.zattrs", + "sample1.zarr/images/he_image/.zgroup", + "sample1.zarr/images/he_image/0", + "sample1.zarr/images/he_image/0/.zarray", + "sample1.zarr/images/he_image/0/0", + "sample1.zarr/images/he_image/0/0/0", + "sample1.zarr/images/he_image/0/0/0/0", + "sample1.zarr/images/he_image/0/0/0/1", + "sample1.zarr/images/he_image/0/0/0/2", + "sample1.zarr/images/he_image/0/0/0/3", + "sample1.zarr/images/he_image/0/0/1", + "sample1.zarr/images/he_image/0/0/1/0", + "sample1.zarr/images/he_image/0/0/1/1", + "sample1.zarr/images/he_image/0/0/1/2", + "sample1.zarr/images/he_image/0/0/1/3", + "sample1.zarr/images/he_image/0/0/2", + "sample1.zarr/images/he_image/0/0/2/0", + "sample1.zarr/images/he_image/0/0/2/1", + "sample1.zarr/images/he_image/0/0/2/2", + "sample1.zarr/images/he_image/0/0/2/3", + "sample1.zarr/images/he_image/0/0/3", + "sample1.zarr/images/he_image/0/0/3/0", + "sample1.zarr/images/he_image/0/0/3/1", + "sample1.zarr/images/he_image/0/0/3/2", + "sample1.zarr/images/he_image/0/0/3/3", + "sample1.zarr/images/he_image/1", + "sample1.zarr/images/he_image/1/.zarray", + "sample1.zarr/images/he_image/1/0", + "sample1.zarr/images/he_image/1/0/0", + "sample1.zarr/images/he_image/1/0/0/0", + "sample1.zarr/images/he_image/1/0/0/1", + "sample1.zarr/images/he_image/1/0/1", + "sample1.zarr/images/he_image/1/0/1/0", + "sample1.zarr/images/he_image/1/0/1/1", + "sample1.zarr/images/he_image/2", + "sample1.zarr/images/he_image/2/.zarray", + "sample1.zarr/images/he_image/2/0", + "sample1.zarr/images/he_image/2/0/0", + "sample1.zarr/images/he_image/2/0/0/0", + "sample1.zarr/images/image", + "sample1.zarr/images/image/.zattrs", + "sample1.zarr/images/image/.zgroup", + "sample1.zarr/images/image/0", + "sample1.zarr/images/image/0/.zarray", + "sample1.zarr/images/image/0/0", + "sample1.zarr/images/image/0/0/0", + "sample1.zarr/images/image/0/0/0/0", + "sample1.zarr/images/image/0/0/0/1", + "sample1.zarr/images/image/0/0/1", + "sample1.zarr/images/image/0/0/1/0", + "sample1.zarr/images/image/0/0/1/1", + "sample1.zarr/images/image/0/1", + "sample1.zarr/images/image/0/1/0", + "sample1.zarr/images/image/0/1/0/0", + "sample1.zarr/images/image/0/1/0/1", + "sample1.zarr/images/image/0/1/1", + "sample1.zarr/images/image/0/1/1/0", + "sample1.zarr/images/image/0/1/1/1", + "sample1.zarr/images/image/0/2", + "sample1.zarr/images/image/0/2/0", + "sample1.zarr/images/image/0/2/0/0", + "sample1.zarr/images/image/0/2/0/1", + "sample1.zarr/images/image/0/2/1", + "sample1.zarr/images/image/0/2/1/0", + "sample1.zarr/images/image/0/2/1/1", + "sample1.zarr/images/image/0/3", + "sample1.zarr/images/image/0/3/0", + "sample1.zarr/images/image/0/3/0/0", + "sample1.zarr/images/image/0/3/0/1", + "sample1.zarr/images/image/0/3/1", + "sample1.zarr/images/image/0/3/1/0", + "sample1.zarr/images/image/0/3/1/1", + "sample1.zarr/points", + "sample1.zarr/points/.zgroup", + "sample1.zarr/points/misc", + "sample1.zarr/points/misc/.zattrs", + "sample1.zarr/points/misc/.zgroup", + "sample1.zarr/points/misc/points.parquet", + "sample1.zarr/points/misc/points.parquet/part.0.parquet", + "sample1.zarr/points/transcripts", + "sample1.zarr/points/transcripts/.zattrs", + "sample1.zarr/points/transcripts/.zgroup", + "sample1.zarr/points/transcripts/points.parquet", + "sample1.zarr/points/transcripts/points.parquet/part.0.parquet", + "sample1.zarr/shapes", + "sample1.zarr/shapes/.zgroup", + "sample1.zarr/shapes/cells", + "sample1.zarr/shapes/cells/.zattrs", + "sample1.zarr/shapes/cells/.zgroup", + "sample1.zarr/shapes/cells/shapes.parquet", + "sample1.zarr/shapes/proseg_boundaries", + "sample1.zarr/shapes/proseg_boundaries/.zattrs", + "sample1.zarr/shapes/proseg_boundaries/.zgroup", + "sample1.zarr/shapes/proseg_boundaries/shapes.parquet", + "sample1.zarr/shapes/transcripts_patches", + "sample1.zarr/shapes/transcripts_patches/.zattrs", + "sample1.zarr/shapes/transcripts_patches/.zgroup", + "sample1.zarr/shapes/transcripts_patches/shapes.parquet", + "sample1.zarr/tables", + "sample1.zarr/tables/.zgroup", + "sample1.zarr/tables/table", + "sample1.zarr/tables/table/.zattrs", + "sample1.zarr/tables/table/.zgroup", + "sample1.zarr/tables/table/X", + "sample1.zarr/tables/table/X/.zarray", + "sample1.zarr/tables/table/X/.zattrs", + "sample1.zarr/tables/table/X/0", + "sample1.zarr/tables/table/X/0/0", + "sample1.zarr/tables/table/X/0/1", + "sample1.zarr/tables/table/X/1", + "sample1.zarr/tables/table/X/1/0", + "sample1.zarr/tables/table/X/1/1", + "sample1.zarr/tables/table/layers", + "sample1.zarr/tables/table/layers/.zattrs", + "sample1.zarr/tables/table/layers/.zgroup", + "sample1.zarr/tables/table/obs", + "sample1.zarr/tables/table/obs/.zattrs", + "sample1.zarr/tables/table/obs/.zgroup", + "sample1.zarr/tables/table/obs/_index", + "sample1.zarr/tables/table/obs/_index/.zarray", + "sample1.zarr/tables/table/obs/_index/.zattrs", + "sample1.zarr/tables/table/obs/_index/0", + "sample1.zarr/tables/table/obs/area", + "sample1.zarr/tables/table/obs/area/.zarray", + "sample1.zarr/tables/table/obs/area/.zattrs", + "sample1.zarr/tables/table/obs/area/0", + "sample1.zarr/tables/table/obs/cell", + "sample1.zarr/tables/table/obs/cell/.zarray", + "sample1.zarr/tables/table/obs/cell/.zattrs", + "sample1.zarr/tables/table/obs/cell/0", + "sample1.zarr/tables/table/obs/cell_id", + "sample1.zarr/tables/table/obs/cell_id/.zarray", + "sample1.zarr/tables/table/obs/cell_id/.zattrs", + "sample1.zarr/tables/table/obs/cell_id/0", + "sample1.zarr/tables/table/obs/centroid_x", + "sample1.zarr/tables/table/obs/centroid_x/.zarray", + "sample1.zarr/tables/table/obs/centroid_x/.zattrs", + "sample1.zarr/tables/table/obs/centroid_x/0", + "sample1.zarr/tables/table/obs/centroid_y", + "sample1.zarr/tables/table/obs/centroid_y/.zarray", + "sample1.zarr/tables/table/obs/centroid_y/.zattrs", + "sample1.zarr/tables/table/obs/centroid_y/0", + "sample1.zarr/tables/table/obs/centroid_z", + "sample1.zarr/tables/table/obs/centroid_z/.zarray", + "sample1.zarr/tables/table/obs/centroid_z/.zattrs", + "sample1.zarr/tables/table/obs/centroid_z/0", + "sample1.zarr/tables/table/obs/cluster", + "sample1.zarr/tables/table/obs/cluster/.zarray", + "sample1.zarr/tables/table/obs/cluster/.zattrs", + "sample1.zarr/tables/table/obs/cluster/0", + "sample1.zarr/tables/table/obs/fov", + "sample1.zarr/tables/table/obs/fov/.zarray", + "sample1.zarr/tables/table/obs/fov/.zattrs", + "sample1.zarr/tables/table/obs/fov/0", + "sample1.zarr/tables/table/obs/population", + "sample1.zarr/tables/table/obs/population/.zarray", + "sample1.zarr/tables/table/obs/population/.zattrs", + "sample1.zarr/tables/table/obs/population/0", + "sample1.zarr/tables/table/obs/region", + "sample1.zarr/tables/table/obs/region/.zattrs", + "sample1.zarr/tables/table/obs/region/.zgroup", + "sample1.zarr/tables/table/obs/region/categories", + "sample1.zarr/tables/table/obs/region/categories/.zarray", + "sample1.zarr/tables/table/obs/region/categories/.zattrs", + "sample1.zarr/tables/table/obs/region/categories/0", + "sample1.zarr/tables/table/obs/region/codes", + "sample1.zarr/tables/table/obs/region/codes/.zarray", + "sample1.zarr/tables/table/obs/region/codes/.zattrs", + "sample1.zarr/tables/table/obs/region/codes/0", + "sample1.zarr/tables/table/obs/scale", + "sample1.zarr/tables/table/obs/scale/.zarray", + "sample1.zarr/tables/table/obs/scale/.zattrs", + "sample1.zarr/tables/table/obs/scale/0", + "sample1.zarr/tables/table/obs/slide", + "sample1.zarr/tables/table/obs/slide/.zattrs", + "sample1.zarr/tables/table/obs/slide/.zgroup", + "sample1.zarr/tables/table/obs/slide/categories", + "sample1.zarr/tables/table/obs/slide/categories/.zarray", + "sample1.zarr/tables/table/obs/slide/categories/.zattrs", + "sample1.zarr/tables/table/obs/slide/categories/0", + "sample1.zarr/tables/table/obs/slide/codes", + "sample1.zarr/tables/table/obs/slide/codes/.zarray", + "sample1.zarr/tables/table/obs/slide/codes/.zattrs", + "sample1.zarr/tables/table/obs/slide/codes/0", + "sample1.zarr/tables/table/obs/volume", + "sample1.zarr/tables/table/obs/volume/.zarray", + "sample1.zarr/tables/table/obs/volume/.zattrs", + "sample1.zarr/tables/table/obs/volume/0", + "sample1.zarr/tables/table/obsm", + "sample1.zarr/tables/table/obsm/.zattrs", + "sample1.zarr/tables/table/obsm/.zgroup", + "sample1.zarr/tables/table/obsm/intensities", + "sample1.zarr/tables/table/obsm/intensities/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/.zgroup", + "sample1.zarr/tables/table/obsm/intensities/CD20", + "sample1.zarr/tables/table/obsm/intensities/CD20/.zarray", + "sample1.zarr/tables/table/obsm/intensities/CD20/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/CD20/0", + "sample1.zarr/tables/table/obsm/intensities/CD3", + "sample1.zarr/tables/table/obsm/intensities/CD3/.zarray", + "sample1.zarr/tables/table/obsm/intensities/CD3/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/CD3/0", + "sample1.zarr/tables/table/obsm/intensities/CK", + "sample1.zarr/tables/table/obsm/intensities/CK/.zarray", + "sample1.zarr/tables/table/obsm/intensities/CK/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/CK/0", + "sample1.zarr/tables/table/obsm/intensities/DAPI", + "sample1.zarr/tables/table/obsm/intensities/DAPI/.zarray", + "sample1.zarr/tables/table/obsm/intensities/DAPI/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/DAPI/0", + "sample1.zarr/tables/table/obsm/intensities/_index", + "sample1.zarr/tables/table/obsm/intensities/_index/.zarray", + "sample1.zarr/tables/table/obsm/intensities/_index/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/_index/0", + "sample1.zarr/tables/table/obsm/spatial", + "sample1.zarr/tables/table/obsm/spatial/.zarray", + "sample1.zarr/tables/table/obsm/spatial/.zattrs", + "sample1.zarr/tables/table/obsm/spatial/0", + "sample1.zarr/tables/table/obsm/spatial/0/0", + "sample1.zarr/tables/table/obsp", + "sample1.zarr/tables/table/obsp/.zattrs", + "sample1.zarr/tables/table/obsp/.zgroup", + "sample1.zarr/tables/table/uns", + "sample1.zarr/tables/table/uns/.zattrs", + "sample1.zarr/tables/table/uns/.zgroup", + "sample1.zarr/tables/table/uns/sopa_attrs", + "sample1.zarr/tables/table/uns/sopa_attrs/.zattrs", + "sample1.zarr/tables/table/uns/sopa_attrs/.zgroup", + "sample1.zarr/tables/table/uns/sopa_attrs/intensities", + "sample1.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", + "sample1.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", + "sample1.zarr/tables/table/uns/sopa_attrs/intensities/0", + "sample1.zarr/tables/table/uns/sopa_attrs/transcripts", + "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", + "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", + "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/0", + "sample1.zarr/tables/table/uns/spatialdata_attrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/.zattrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/.zgroup", + "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key", + "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", + "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region/0", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/0", + "sample1.zarr/tables/table/var", + "sample1.zarr/tables/table/var/.zattrs", + "sample1.zarr/tables/table/var/.zgroup", + "sample1.zarr/tables/table/var/_index", + "sample1.zarr/tables/table/var/_index/.zarray", + "sample1.zarr/tables/table/var/_index/.zattrs", + "sample1.zarr/tables/table/var/_index/0", + "sample1.zarr/tables/table/varm", + "sample1.zarr/tables/table/varm/.zattrs", + "sample1.zarr/tables/table/varm/.zgroup", + "sample1.zarr/tables/table/varp", + "sample1.zarr/tables/table/varp/.zattrs", + "sample1.zarr/tables/table/varp/.zgroup", + "sample1.zarr/zmetadata" ], [ - + "adata.h5ad:md5,e02d557250798bac753adf55d0dd395b", + "analysis.zarr.zip:md5,461e78668e554521b6acd9364c921b7a", + "analysis_summary.html:md5,7ef4fbd9ae3cbe631ea2ccd185e20c4a", + "cell_feature_matrix.zarr.zip:md5,5b33f506173cee4419a6b15c8f237564", + "cells.zarr.zip:md5,1e7f4ce6118d4315bc477bf7ce3c10ce", + "experiment.xenium:md5,6c3f964cb1eb2d2104a34e1a1ca17a99", + "morphology.ome.tif:md5,6c5cf48d71e8d7fbc45146b3494ffe2e", + "transcripts.zarr.zip:md5,91716cd5f5bd2e5525cda801ad409a42", + "patches_file_transcripts:md5,897316929176464ebc9ad085f31e7284", + ".zattrs:md5,468d8bdc77d7e7f172d4b4fe83b57aec", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zattrs:md5,5b3c6f476c3c21982958e18271dd834b", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zarray:md5,721b4e50f69cf172cded07c10e1d932d", + "0:md5,94d082c5dbba1860c82e14ceafab82d9", + "1:md5,de228035c7935e884b4a1af8dc4903ac", + "2:md5,5af87bde48de5aa97ab6c5e3c779d3ed", + "3:md5,290456bdd4f13f815684d7df2bc8beb1", + "0:md5,cba8f18aee7db1db6e0337f829f38966", + "1:md5,59bf54f6f8a70534ccb107f989a359e8", + "2:md5,563f4d52c2a274ee07b1c2e903c8e053", + "3:md5,5dc4e93210483696e4b8ccd261b59ea4", + "0:md5,1d3cb0e10d08bb661f9bba1e9539b3d0", + "1:md5,6c497854befbd0fbc27df2f15dd6620a", + "2:md5,5acfcfc8b05f5937b96dc5e330f00241", + "3:md5,59af25140054c5fa5659295c0810adbc", + "0:md5,232acc572558367ff84e63299d4e2890", + "1:md5,604ec2d55485b819025f15d6cb25c3d1", + "2:md5,db580bfe58001e49f7a7f5e75748bc69", + "3:md5,b00f1bb37e6ebf8ef0a70cf5e8c8f023", + ".zarray:md5,1d79c377c95e96c290e57dcc65615d81", + "0:md5,d432d2bc0120c7cf91718b4f24f040c5", + "1:md5,7095884e5e1e9baac3a24d15ba0c1f7b", + "0:md5,af3a01b79d9633b67415a78b472a5ff2", + "1:md5,d5b194a88cfcc4939f402d1e06fb6b7d", + ".zarray:md5,b5fe837c88ee52d35dbee2ec3a30cf17", + "0:md5,0328d110d9c6fac7bc5e091ab14e32e1", + ".zattrs:md5,cc30adb0bbb0e6f2be88d24170817966", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zarray:md5,c3de494758677af82d809ca2e4763c63", + "0:md5,d17ebfa93d74471f6ff65aa9c0504025", + "1:md5,2338504a672e7656bdb5300d60f7353a", + "0:md5,09a64f9aa09225e293d8d0c85d40abb0", + "1:md5,12ab66f310ab8ebffc2a178a9008523e", + "0:md5,8de482cb5a33656da5bac20dfb38b0fb", + "1:md5,2716f328ef2e4ae7bdd2aebece4cc81a", + "0:md5,a68ca3a7c3d5ccea0df3edc682672538", + "1:md5,e18bcf5aa4b9aa00b724efe4b7fc9a08", + "0:md5,fb949cda7000fc864a1c371655d73e67", + "1:md5,228aed44f36d6c96e0ae385cfdbf59d7", + "0:md5,278c4ece169c3fe37444f22acb704640", + "1:md5,320dae82e5e926f94c26ca0c496a94be", + "0:md5,a8495ec0ddbadd638100cc09925ff060", + "1:md5,5e1f8a06ee1b586ed10d84e51695f34d", + "0:md5,063c83056f4b951a13a719326fb7d61a", + "1:md5,0e9f2432ab893f8fac56226edbb7243c", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zattrs:md5,441f7caee25d9885acd5cc2c1d93a5a2", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "part.0.parquet:md5,c9c4d7276a3c94db134f483387d07a46", + ".zattrs:md5,ee46fa68c2832b7ec6e1914b53d5514e", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "part.0.parquet:md5,d732fd3e5aa49d5f7a2f4f897411583c", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zattrs:md5,37c0eabf77e69009a9f0c878e69ea262", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "shapes.parquet:md5,ef7522c0a19ea52dbdb2b326d17920ef", + ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "shapes.parquet:md5,3fbaba00a1a4436b188188a0f277ba3c", + ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "shapes.parquet:md5,314f608f2f6b9678f0c3f68fb3828054", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zattrs:md5,647bd8e1d56f5a72302479f55dfccbdc", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zarray:md5,aa18046c95f5083a85adc0323edcf55c", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,6d240ec299b386f892926f654d8443a0", + "1:md5,176bbe41b19ab2f4faf4018f7ecca911", + "0:md5,e42dbdf14018e21cda80856c34942a14", + "1:md5,d3766240b3ca99f4c7667a88e1710cfa", + ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zattrs:md5,ac8e849d1e63089d9d84e4c890051dba", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zarray:md5,0b196b48bdda7c9ed5332884606d07e8", + ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", + "0:md5,929ffef2d0f259579f507c811510cfc1", + ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,25e63065e64b3d9cc1c9db0c3c2b0af8", + ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,93d1c4d922586df90447c036c58b41de", + ".zarray:md5,0b196b48bdda7c9ed5332884606d07e8", + ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", + "0:md5,929ffef2d0f259579f507c811510cfc1", + ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,2844c9fc1e175f2596605eb0d7b509e6", + ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,161fc2cbb0eb5ddca5e79743e94ad104", + ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,bd2fa6abd22959136d57036fc63ce420", + ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,1414e8e43d0260bd79802ed167b2563d", + ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,a6ad4acf12cec31b6e0072925561c288", + ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,9606085f2eeeb74375f0a50e5cb1d90f", + ".zattrs:md5,ee9e2561ffa06a8a5b93ea6c0eff7377", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zarray:md5,8b7c1d3908cae5d4c2eddfc0369a608d", + ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", + "0:md5,4f9409e8cba55576452886824fe380ec", + ".zarray:md5,21c68f0c19a88515b451183e711d237a", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,e28d06462f249c654260c35e068b41ee", + ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,74624d5561d57890123dc7bfb122ba78", + ".zattrs:md5,ee9e2561ffa06a8a5b93ea6c0eff7377", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zarray:md5,8b7c1d3908cae5d4c2eddfc0369a608d", + ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", + "0:md5,32b134819930c1668568f00fe06b1f3f", + ".zarray:md5,21c68f0c19a88515b451183e711d237a", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,e28d06462f249c654260c35e068b41ee", + ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,158b780651e19c1f4b523c1938b6d863", + ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zattrs:md5,6a687a49c45c3c33dc209f5ba155f570", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,517b6e875be7a386b7e9180d62273688", + ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,076be963512f9330bbf5902e55b444d5", + ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,1948a8636e54e30ed5c0e7fb7c9962a7", + ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,7f9c0c6c4a749982495ac2994c0349ab", + ".zarray:md5,0b196b48bdda7c9ed5332884606d07e8", + ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", + "0:md5,929ffef2d0f259579f507c811510cfc1", + ".zarray:md5,66affee14626fc80349b052373fd8061", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,af8a6a17844c335bc9033feb0e9fe5aa", + ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zarray:md5,288aba90e17cb1a4b685961c18909db1", + ".zattrs:md5,1c65af9c8d0b8dd51a848664c302b40d", + "0:md5,55a54008ad1ba589aa210d2629c1df41", + ".zarray:md5,288aba90e17cb1a4b685961c18909db1", + ".zattrs:md5,1c65af9c8d0b8dd51a848664c302b40d", + "0:md5,55a54008ad1ba589aa210d2629c1df41", + ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zarray:md5,d36903528917a9947829b4c7d5b0b7a6", + ".zattrs:md5,1a7eb7e8b68cabba6dac4016c39515b8", + "0:md5,b89bade7bc089319a4e8242aad70f400", + ".zarray:md5,4ee0db9305c15160aebaf22522f71168", + ".zattrs:md5,1a7eb7e8b68cabba6dac4016c39515b8", + "0:md5,820086fcb71c01574b9101f5c7da6332", + ".zarray:md5,8fc125cd69697992f7c1a452d6a2100c", + ".zattrs:md5,1a7eb7e8b68cabba6dac4016c39515b8", + "0:md5,db5579ad8d3db867ffbb022212fd396f", + ".zattrs:md5,8ff613dda1c9f16e3156002416a3004c", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zarray:md5,a3b9b777672d072057168950b9babe72", + ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", + "0:md5,17613992d46768c1521a0a4ef8169910", + ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "zmetadata:md5,31ef3a80efaf858f9f3147a11f8218d6" ] ], "meta": { "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nextflow": "25.04.6" }, - "timestamp": "2025-07-10T10:05:15.66595" + "timestamp": "2025-07-11T10:45:36.309196" } } \ No newline at end of file From 2b24f1c6e5d324b0a6478465da7c62af9e4dee42 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 11 Jul 2025 11:33:50 +0200 Subject: [PATCH 106/227] update proseg version --- modules/local/utils.nf | 59 +++++++++++++++++++++++++++++------- tests/default.nf.test.snap | 61 +++++++++++++++++++++----------------- 2 files changed, 83 insertions(+), 37 deletions(-) diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 99f9927..1a582ec 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -76,16 +76,7 @@ def readConfigFile(String configfile) { def config = new groovy.yaml.YamlSlurper().parse(reader) - if (config.segmentation.baysor) { - if (config.segmentation.cellpose) { - config.segmentation.baysor.prior_shapes_key = "cellpose_boundaries" - } - else if (config.segmentation.baysor.cell_key) { - println("Config argument 'cell_key' is deprecated. Use 'prior_shapes_key' instead.") - config.segmentation.baysor.prior_shapes_key = config.segmentation.baysor.cell_key - } - } - return config + return validate(config) } def deepCopyCollection(object) { @@ -103,3 +94,51 @@ def deepCopyCollection(object) { object } } + + +def validate(Map cfg) { + def TRANSCRIPT_BASED_METHODS = ['proseg', 'baysor', 'comseg'] + def STAINING_BASED_METHODS = ['stardist', 'cellpose'] + + def backwardCompatibility = { Map c -> + TRANSCRIPT_BASED_METHODS.each { m -> + if (c.segmentation?.get(m)?.containsKey('cell_key')) { + println("Deprecated 'cell_key' → using 'prior_shapes_key' instead.") + c.segmentation[m].prior_shapes_key = c.segmentation[m].cell_key + c.segmentation[m].remove('cell_key') + } + } + if (c.aggregate?.containsKey('average_intensities')) { + println("Deprecated 'average_intensities' → using 'aggregate_channels' instead.") + c.aggregate.aggregate_channels = c.aggregate.average_intensities + c.aggregate.remove('average_intensities') + } + } + + def checkSegmentationMethods = { Map c -> + assert c.segmentation && c.segmentation : "Provide at least one segmentation method" + assert TRANSCRIPT_BASED_METHODS.count { c.segmentation.containsKey(it) } <= 1 : "Only one of ${TRANSCRIPT_BASED_METHODS} may be used" + assert STAINING_BASED_METHODS.count { c.segmentation.containsKey(it) } <= 1 : "Only one of ${STAINING_BASED_METHODS} may be used" + if (c.segmentation.containsKey('stardist')) { + assert TRANSCRIPT_BASED_METHODS.every { !c.segmentation.containsKey(it) } : "'stardist' cannot be combined with transcript-based methods" + } + } + + def checkPriorShapesKey = { Map c -> + TRANSCRIPT_BASED_METHODS.each { m -> + if (c.segmentation.containsKey(m) && c.segmentation.containsKey('cellpose')) { + c.segmentation[m].prior_shapes_key = 'cellpose_boundaries' + } + } + } + + /* ───────── top-level checks ───────── */ + assert cfg.read instanceof Map && cfg.read.containsKey('technology') : "Provide a 'read.technology' key" + assert cfg.containsKey('segmentation') : "Provide a 'segmentation' section" + + backwardCompatibility(cfg) + checkSegmentationMethods(cfg) + checkPriorShapesKey(cfg) + + return cfg +} diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index c8bdac3..c9e4ce4 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -182,6 +182,10 @@ "sample1.zarr/tables/table/obs/fov/.zarray", "sample1.zarr/tables/table/obs/fov/.zattrs", "sample1.zarr/tables/table/obs/fov/0", + "sample1.zarr/tables/table/obs/original_cell_id", + "sample1.zarr/tables/table/obs/original_cell_id/.zarray", + "sample1.zarr/tables/table/obs/original_cell_id/.zattrs", + "sample1.zarr/tables/table/obs/original_cell_id/0", "sample1.zarr/tables/table/obs/population", "sample1.zarr/tables/table/obs/population/.zarray", "sample1.zarr/tables/table/obs/population/.zattrs", @@ -295,14 +299,14 @@ "sample1.zarr/zmetadata" ], [ - "adata.h5ad:md5,e02d557250798bac753adf55d0dd395b", - "analysis.zarr.zip:md5,461e78668e554521b6acd9364c921b7a", - "analysis_summary.html:md5,7ef4fbd9ae3cbe631ea2ccd185e20c4a", - "cell_feature_matrix.zarr.zip:md5,5b33f506173cee4419a6b15c8f237564", - "cells.zarr.zip:md5,1e7f4ce6118d4315bc477bf7ce3c10ce", + "adata.h5ad:md5,6c7e637b069126abcefa0d01a65273f4", + "analysis.zarr.zip:md5,c2ad13290e387183338dae39aaaf6554", + "analysis_summary.html:md5,9b9b50f5f3d4554a1e130e9ec8a16c32", + "cell_feature_matrix.zarr.zip:md5,8edef48ce9fbd96e84a68161aef039ac", + "cells.zarr.zip:md5,339c8b962b7313f6f0c4c6e55c764369", "experiment.xenium:md5,6c3f964cb1eb2d2104a34e1a1ca17a99", - "morphology.ome.tif:md5,6c5cf48d71e8d7fbc45146b3494ffe2e", - "transcripts.zarr.zip:md5,91716cd5f5bd2e5525cda801ad409a42", + "morphology.ome.tif:md5,015445c80e4cfee1d67f966690fefac2", + "transcripts.zarr.zip:md5,a6c540db50e7eb58a6a5c51d7509743f", "patches_file_transcripts:md5,897316929176464ebc9ad085f31e7284", ".zattrs:md5,468d8bdc77d7e7f172d4b4fe83b57aec", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", @@ -365,29 +369,29 @@ "shapes.parquet:md5,ef7522c0a19ea52dbdb2b326d17920ef", ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "shapes.parquet:md5,3fbaba00a1a4436b188188a0f277ba3c", + "shapes.parquet:md5,c0fbaeb941c597ccbf54b392c4f51c5b", ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "shapes.parquet:md5,314f608f2f6b9678f0c3f68fb3828054", + "shapes.parquet:md5,b5bb672cc15bcc53881218fc4b5cf4de", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,647bd8e1d56f5a72302479f55dfccbdc", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zarray:md5,aa18046c95f5083a85adc0323edcf55c", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,6d240ec299b386f892926f654d8443a0", - "1:md5,176bbe41b19ab2f4faf4018f7ecca911", - "0:md5,e42dbdf14018e21cda80856c34942a14", - "1:md5,d3766240b3ca99f4c7667a88e1710cfa", + "0:md5,340327e4658c115126929c4aad413a31", + "1:md5,e43b7810c69a614af5d1a5ea40349af6", + "0:md5,8978278a7826f69a827462b6b6482bd5", + "1:md5,72c95db61dcdace533063420279e2f88", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,ac8e849d1e63089d9d84e4c890051dba", + ".zattrs:md5,7d0ecab87d4ceae4daf84acc75e71ee4", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zarray:md5,0b196b48bdda7c9ed5332884606d07e8", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", "0:md5,929ffef2d0f259579f507c811510cfc1", ".zarray:md5,1644e79931988150c2dcfabfaa34860c", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,25e63065e64b3d9cc1c9db0c3c2b0af8", + "0:md5,51f30e1d2c3fdd7cf89bdada6642b2c1", ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", "0:md5,93d1c4d922586df90447c036c58b41de", @@ -396,22 +400,25 @@ "0:md5,929ffef2d0f259579f507c811510cfc1", ".zarray:md5,1644e79931988150c2dcfabfaa34860c", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,2844c9fc1e175f2596605eb0d7b509e6", + "0:md5,d78b1453d7b7df7ca933d72abe77c3d3", ".zarray:md5,1644e79931988150c2dcfabfaa34860c", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,161fc2cbb0eb5ddca5e79743e94ad104", + "0:md5,80825309fc69c89297bd9735a36187c7", ".zarray:md5,1644e79931988150c2dcfabfaa34860c", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,bd2fa6abd22959136d57036fc63ce420", + "0:md5,595a3b388753986ab9f48302a3ef6699", ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,1414e8e43d0260bd79802ed167b2563d", + "0:md5,8b064ab59549eb712b89f4c11efc3f2f", ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", "0:md5,a6ad4acf12cec31b6e0072925561c288", ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,9606085f2eeeb74375f0a50e5cb1d90f", + "0:md5,c8389702ef14ae841490a1eb911e541d", + ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,7b3ba357cb7dfd678091563caf868cf1", ".zattrs:md5,ee9e2561ffa06a8a5b93ea6c0eff7377", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zarray:md5,8b7c1d3908cae5d4c2eddfc0369a608d", @@ -433,29 +440,29 @@ "0:md5,e28d06462f249c654260c35e068b41ee", ".zarray:md5,1644e79931988150c2dcfabfaa34860c", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,158b780651e19c1f4b523c1938b6d863", + "0:md5,3ae7a59d0e4c4f74486ac905c3c9e8de", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,6a687a49c45c3c33dc209f5ba155f570", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zarray:md5,1644e79931988150c2dcfabfaa34860c", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,517b6e875be7a386b7e9180d62273688", + "0:md5,3f9de170008e103c37cf282d1f159ba1", ".zarray:md5,1644e79931988150c2dcfabfaa34860c", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,076be963512f9330bbf5902e55b444d5", + "0:md5,4f77877b43a2e60d342df3a71f55f484", ".zarray:md5,1644e79931988150c2dcfabfaa34860c", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,1948a8636e54e30ed5c0e7fb7c9962a7", + "0:md5,ad7b508a4e1444e1c96c0bcbc3aacf31", ".zarray:md5,1644e79931988150c2dcfabfaa34860c", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,7f9c0c6c4a749982495ac2994c0349ab", + "0:md5,2b88a5d1482549fb30deffb99fa40f20", ".zarray:md5,0b196b48bdda7c9ed5332884606d07e8", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", "0:md5,929ffef2d0f259579f507c811510cfc1", ".zarray:md5,66affee14626fc80349b052373fd8061", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,af8a6a17844c335bc9033feb0e9fe5aa", + "0:md5,2a140b06a1b9d9d505544fb95c975805", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", @@ -495,6 +502,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-11T10:45:36.309196" + "timestamp": "2025-07-11T11:07:41.831422" } } \ No newline at end of file From 595e34876fb7c335087c1d211e37e917185afa35 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 11 Jul 2025 11:54:10 +0200 Subject: [PATCH 107/227] add config validation + test with baysor --- conf/test.config | 2 +- modules/local/utils.nf | 60 ++++----- tests/default.nf.test.snap | 259 +++++++++++++++++++------------------ 3 files changed, 163 insertions(+), 158 deletions(-) diff --git a/conf/test.config b/conf/test.config index 5a75102..70e1697 100644 --- a/conf/test.config +++ b/conf/test.config @@ -24,5 +24,5 @@ params { // Input data input = "${baseDir}/tests/samplesheet.csv" - configfile = "https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/toy/proseg.yaml" + configfile = "https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/toy/baysor.yaml" } diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 1a582ec..d72f437 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -96,49 +96,43 @@ def deepCopyCollection(object) { } -def validate(Map cfg) { +def validate(Map config) { def TRANSCRIPT_BASED_METHODS = ['proseg', 'baysor', 'comseg'] def STAINING_BASED_METHODS = ['stardist', 'cellpose'] - def backwardCompatibility = { Map c -> - TRANSCRIPT_BASED_METHODS.each { m -> - if (c.segmentation?.get(m)?.containsKey('cell_key')) { - println("Deprecated 'cell_key' → using 'prior_shapes_key' instead.") - c.segmentation[m].prior_shapes_key = c.segmentation[m].cell_key - c.segmentation[m].remove('cell_key') - } - } - if (c.aggregate?.containsKey('average_intensities')) { - println("Deprecated 'average_intensities' → using 'aggregate_channels' instead.") - c.aggregate.aggregate_channels = c.aggregate.average_intensities - c.aggregate.remove('average_intensities') + // top-level checks + assert config.read instanceof Map && config.read.containsKey('technology') : "Provide a 'read.technology' key" + assert config.containsKey('segmentation') : "Provide a 'segmentation' section" + + // backward compatibility + TRANSCRIPT_BASED_METHODS.each { m -> + if (config.segmentation?.get(m)?.containsKey('cell_key')) { + println("Deprecated 'cell_key' → using 'prior_shapes_key' instead.") + config.segmentation[m].prior_shapes_key = config.segmentation[m].cell_key + config.segmentation[m].remove('cell_key') } } + if (config.aggregate?.containsKey('average_intensities')) { + println("Deprecated 'average_intensities' → using 'aggregate_channels' instead.") + config.aggregate.aggregate_channels = config.aggregate.average_intensities + config.aggregate.remove('average_intensities') + } - def checkSegmentationMethods = { Map c -> - assert c.segmentation && c.segmentation : "Provide at least one segmentation method" - assert TRANSCRIPT_BASED_METHODS.count { c.segmentation.containsKey(it) } <= 1 : "Only one of ${TRANSCRIPT_BASED_METHODS} may be used" - assert STAINING_BASED_METHODS.count { c.segmentation.containsKey(it) } <= 1 : "Only one of ${STAINING_BASED_METHODS} may be used" - if (c.segmentation.containsKey('stardist')) { - assert TRANSCRIPT_BASED_METHODS.every { !c.segmentation.containsKey(it) } : "'stardist' cannot be combined with transcript-based methods" - } + // check segmentation methods + assert config.segmentation : "Provide at least one segmentation method" + assert TRANSCRIPT_BASED_METHODS.count { config.segmentation.containsKey(it) } <= 1 : "Only one of ${TRANSCRIPT_BASED_METHODS} may be used" + assert STAINING_BASED_METHODS.count { config.segmentation.containsKey(it) } <= 1 : "Only one of ${STAINING_BASED_METHODS} may be used" + if (config.segmentation.containsKey('stardist')) { + assert TRANSCRIPT_BASED_METHODS.every { !config.segmentation.containsKey(it) } : "'stardist' cannot be combined with transcript-based methods" } - def checkPriorShapesKey = { Map c -> - TRANSCRIPT_BASED_METHODS.each { m -> - if (c.segmentation.containsKey(m) && c.segmentation.containsKey('cellpose')) { - c.segmentation[m].prior_shapes_key = 'cellpose_boundaries' - } + // check prior shapes key + TRANSCRIPT_BASED_METHODS.each { m -> + if (config.segmentation.containsKey(m) && config.segmentation.containsKey('cellpose')) { + config.segmentation[m].prior_shapes_key = 'cellpose_boundaries' } } - /* ───────── top-level checks ───────── */ - assert cfg.read instanceof Map && cfg.read.containsKey('technology') : "Provide a 'read.technology' key" - assert cfg.containsKey('segmentation') : "Provide a 'segmentation' section" - - backwardCompatibility(cfg) - checkSegmentationMethods(cfg) - checkPriorShapesKey(cfg) - return cfg + return config } diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index c9e4ce4..e0be869 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -1,7 +1,7 @@ { "-profile test": { "content": [ - 8, + 9, { "Workflow": { "nf-core/sopa": "v1.0.0dev" @@ -22,7 +22,6 @@ "sample1.zarr", "sample1.zarr/.sopa_cache", "sample1.zarr/.sopa_cache/patches_file_transcripts", - "sample1.zarr/.sopa_cache/transcript_patches", "sample1.zarr/.zattrs", "sample1.zarr/.zgroup", "sample1.zarr/images", @@ -114,14 +113,14 @@ "sample1.zarr/points/transcripts/points.parquet/part.0.parquet", "sample1.zarr/shapes", "sample1.zarr/shapes/.zgroup", + "sample1.zarr/shapes/baysor_boundaries", + "sample1.zarr/shapes/baysor_boundaries/.zattrs", + "sample1.zarr/shapes/baysor_boundaries/.zgroup", + "sample1.zarr/shapes/baysor_boundaries/shapes.parquet", "sample1.zarr/shapes/cells", "sample1.zarr/shapes/cells/.zattrs", "sample1.zarr/shapes/cells/.zgroup", "sample1.zarr/shapes/cells/shapes.parquet", - "sample1.zarr/shapes/proseg_boundaries", - "sample1.zarr/shapes/proseg_boundaries/.zattrs", - "sample1.zarr/shapes/proseg_boundaries/.zgroup", - "sample1.zarr/shapes/proseg_boundaries/shapes.parquet", "sample1.zarr/shapes/transcripts_patches", "sample1.zarr/shapes/transcripts_patches/.zattrs", "sample1.zarr/shapes/transcripts_patches/.zgroup", @@ -132,14 +131,17 @@ "sample1.zarr/tables/table/.zattrs", "sample1.zarr/tables/table/.zgroup", "sample1.zarr/tables/table/X", - "sample1.zarr/tables/table/X/.zarray", "sample1.zarr/tables/table/X/.zattrs", - "sample1.zarr/tables/table/X/0", - "sample1.zarr/tables/table/X/0/0", - "sample1.zarr/tables/table/X/0/1", - "sample1.zarr/tables/table/X/1", - "sample1.zarr/tables/table/X/1/0", - "sample1.zarr/tables/table/X/1/1", + "sample1.zarr/tables/table/X/.zgroup", + "sample1.zarr/tables/table/X/data", + "sample1.zarr/tables/table/X/data/.zarray", + "sample1.zarr/tables/table/X/data/0", + "sample1.zarr/tables/table/X/indices", + "sample1.zarr/tables/table/X/indices/.zarray", + "sample1.zarr/tables/table/X/indices/0", + "sample1.zarr/tables/table/X/indptr", + "sample1.zarr/tables/table/X/indptr/.zarray", + "sample1.zarr/tables/table/X/indptr/0", "sample1.zarr/tables/table/layers", "sample1.zarr/tables/table/layers/.zattrs", "sample1.zarr/tables/table/layers/.zgroup", @@ -154,42 +156,46 @@ "sample1.zarr/tables/table/obs/area/.zarray", "sample1.zarr/tables/table/obs/area/.zattrs", "sample1.zarr/tables/table/obs/area/0", - "sample1.zarr/tables/table/obs/cell", - "sample1.zarr/tables/table/obs/cell/.zarray", - "sample1.zarr/tables/table/obs/cell/.zattrs", - "sample1.zarr/tables/table/obs/cell/0", + "sample1.zarr/tables/table/obs/avg_assignment_confidence", + "sample1.zarr/tables/table/obs/avg_assignment_confidence/.zarray", + "sample1.zarr/tables/table/obs/avg_assignment_confidence/.zattrs", + "sample1.zarr/tables/table/obs/avg_assignment_confidence/0", + "sample1.zarr/tables/table/obs/avg_confidence", + "sample1.zarr/tables/table/obs/avg_confidence/.zarray", + "sample1.zarr/tables/table/obs/avg_confidence/.zattrs", + "sample1.zarr/tables/table/obs/avg_confidence/0", + "sample1.zarr/tables/table/obs/baysor_area", + "sample1.zarr/tables/table/obs/baysor_area/.zarray", + "sample1.zarr/tables/table/obs/baysor_area/.zattrs", + "sample1.zarr/tables/table/obs/baysor_area/0", "sample1.zarr/tables/table/obs/cell_id", "sample1.zarr/tables/table/obs/cell_id/.zarray", "sample1.zarr/tables/table/obs/cell_id/.zattrs", "sample1.zarr/tables/table/obs/cell_id/0", - "sample1.zarr/tables/table/obs/centroid_x", - "sample1.zarr/tables/table/obs/centroid_x/.zarray", - "sample1.zarr/tables/table/obs/centroid_x/.zattrs", - "sample1.zarr/tables/table/obs/centroid_x/0", - "sample1.zarr/tables/table/obs/centroid_y", - "sample1.zarr/tables/table/obs/centroid_y/.zarray", - "sample1.zarr/tables/table/obs/centroid_y/.zattrs", - "sample1.zarr/tables/table/obs/centroid_y/0", - "sample1.zarr/tables/table/obs/centroid_z", - "sample1.zarr/tables/table/obs/centroid_z/.zarray", - "sample1.zarr/tables/table/obs/centroid_z/.zattrs", - "sample1.zarr/tables/table/obs/centroid_z/0", "sample1.zarr/tables/table/obs/cluster", "sample1.zarr/tables/table/obs/cluster/.zarray", "sample1.zarr/tables/table/obs/cluster/.zattrs", "sample1.zarr/tables/table/obs/cluster/0", - "sample1.zarr/tables/table/obs/fov", - "sample1.zarr/tables/table/obs/fov/.zarray", - "sample1.zarr/tables/table/obs/fov/.zattrs", - "sample1.zarr/tables/table/obs/fov/0", - "sample1.zarr/tables/table/obs/original_cell_id", - "sample1.zarr/tables/table/obs/original_cell_id/.zarray", - "sample1.zarr/tables/table/obs/original_cell_id/.zattrs", - "sample1.zarr/tables/table/obs/original_cell_id/0", - "sample1.zarr/tables/table/obs/population", - "sample1.zarr/tables/table/obs/population/.zarray", - "sample1.zarr/tables/table/obs/population/.zattrs", - "sample1.zarr/tables/table/obs/population/0", + "sample1.zarr/tables/table/obs/density", + "sample1.zarr/tables/table/obs/density/.zarray", + "sample1.zarr/tables/table/obs/density/.zattrs", + "sample1.zarr/tables/table/obs/density/0", + "sample1.zarr/tables/table/obs/elongation", + "sample1.zarr/tables/table/obs/elongation/.zarray", + "sample1.zarr/tables/table/obs/elongation/.zattrs", + "sample1.zarr/tables/table/obs/elongation/0", + "sample1.zarr/tables/table/obs/lifespan", + "sample1.zarr/tables/table/obs/lifespan/.zarray", + "sample1.zarr/tables/table/obs/lifespan/.zattrs", + "sample1.zarr/tables/table/obs/lifespan/0", + "sample1.zarr/tables/table/obs/max_cluster_frac", + "sample1.zarr/tables/table/obs/max_cluster_frac/.zarray", + "sample1.zarr/tables/table/obs/max_cluster_frac/.zattrs", + "sample1.zarr/tables/table/obs/max_cluster_frac/0", + "sample1.zarr/tables/table/obs/n_transcripts", + "sample1.zarr/tables/table/obs/n_transcripts/.zarray", + "sample1.zarr/tables/table/obs/n_transcripts/.zattrs", + "sample1.zarr/tables/table/obs/n_transcripts/0", "sample1.zarr/tables/table/obs/region", "sample1.zarr/tables/table/obs/region/.zattrs", "sample1.zarr/tables/table/obs/region/.zgroup", @@ -201,10 +207,6 @@ "sample1.zarr/tables/table/obs/region/codes/.zarray", "sample1.zarr/tables/table/obs/region/codes/.zattrs", "sample1.zarr/tables/table/obs/region/codes/0", - "sample1.zarr/tables/table/obs/scale", - "sample1.zarr/tables/table/obs/scale/.zarray", - "sample1.zarr/tables/table/obs/scale/.zattrs", - "sample1.zarr/tables/table/obs/scale/0", "sample1.zarr/tables/table/obs/slide", "sample1.zarr/tables/table/obs/slide/.zattrs", "sample1.zarr/tables/table/obs/slide/.zgroup", @@ -216,10 +218,14 @@ "sample1.zarr/tables/table/obs/slide/codes/.zarray", "sample1.zarr/tables/table/obs/slide/codes/.zattrs", "sample1.zarr/tables/table/obs/slide/codes/0", - "sample1.zarr/tables/table/obs/volume", - "sample1.zarr/tables/table/obs/volume/.zarray", - "sample1.zarr/tables/table/obs/volume/.zattrs", - "sample1.zarr/tables/table/obs/volume/0", + "sample1.zarr/tables/table/obs/x", + "sample1.zarr/tables/table/obs/x/.zarray", + "sample1.zarr/tables/table/obs/x/.zattrs", + "sample1.zarr/tables/table/obs/x/0", + "sample1.zarr/tables/table/obs/y", + "sample1.zarr/tables/table/obs/y/.zarray", + "sample1.zarr/tables/table/obs/y/.zattrs", + "sample1.zarr/tables/table/obs/y/0", "sample1.zarr/tables/table/obsm", "sample1.zarr/tables/table/obsm/.zattrs", "sample1.zarr/tables/table/obsm/.zgroup", @@ -286,10 +292,10 @@ "sample1.zarr/tables/table/var", "sample1.zarr/tables/table/var/.zattrs", "sample1.zarr/tables/table/var/.zgroup", - "sample1.zarr/tables/table/var/_index", - "sample1.zarr/tables/table/var/_index/.zarray", - "sample1.zarr/tables/table/var/_index/.zattrs", - "sample1.zarr/tables/table/var/_index/0", + "sample1.zarr/tables/table/var/Name", + "sample1.zarr/tables/table/var/Name/.zarray", + "sample1.zarr/tables/table/var/Name/.zattrs", + "sample1.zarr/tables/table/var/Name/0", "sample1.zarr/tables/table/varm", "sample1.zarr/tables/table/varm/.zattrs", "sample1.zarr/tables/table/varm/.zgroup", @@ -299,14 +305,14 @@ "sample1.zarr/zmetadata" ], [ - "adata.h5ad:md5,6c7e637b069126abcefa0d01a65273f4", - "analysis.zarr.zip:md5,c2ad13290e387183338dae39aaaf6554", - "analysis_summary.html:md5,9b9b50f5f3d4554a1e130e9ec8a16c32", - "cell_feature_matrix.zarr.zip:md5,8edef48ce9fbd96e84a68161aef039ac", - "cells.zarr.zip:md5,339c8b962b7313f6f0c4c6e55c764369", - "experiment.xenium:md5,6c3f964cb1eb2d2104a34e1a1ca17a99", - "morphology.ome.tif:md5,015445c80e4cfee1d67f966690fefac2", - "transcripts.zarr.zip:md5,a6c540db50e7eb58a6a5c51d7509743f", + "adata.h5ad:md5,6e99850a6780ca4ca184da6bdec6d406", + "analysis.zarr.zip:md5,3fb73c7d06e136965eab61e022d5e962", + "analysis_summary.html:md5,dacd035a666c28fa108938731a76c295", + "cell_feature_matrix.zarr.zip:md5,451d7174dc7da1cb86af32e0852ff2f8", + "cells.zarr.zip:md5,e8903ac247fedfea9b5558830d83871b", + "experiment.xenium:md5,348e5b7f2aaea83eb00acba0c748046a", + "morphology.ome.tif:md5,00bd32e18f5f571d77a1722577cd58b7", + "transcripts.zarr.zip:md5,695b7836b50f5548bc32a22edfda2d4d", "patches_file_transcripts:md5,897316929176464ebc9ad085f31e7284", ".zattrs:md5,468d8bdc77d7e7f172d4b4fe83b57aec", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", @@ -362,107 +368,112 @@ "part.0.parquet:md5,c9c4d7276a3c94db134f483387d07a46", ".zattrs:md5,ee46fa68c2832b7ec6e1914b53d5514e", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "part.0.parquet:md5,d732fd3e5aa49d5f7a2f4f897411583c", + "part.0.parquet:md5,3f65a56c60088849fad3eb9fac81dccf", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "shapes.parquet:md5,934e883744c782b9708e4ec59fb5b6d9", ".zattrs:md5,37c0eabf77e69009a9f0c878e69ea262", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", "shapes.parquet:md5,ef7522c0a19ea52dbdb2b326d17920ef", ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "shapes.parquet:md5,c0fbaeb941c597ccbf54b392c4f51c5b", - ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", + "shapes.parquet:md5,f1a1b9f1b15eaaa86701cf3ebb24f1c8", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "shapes.parquet:md5,b5bb672cc15bcc53881218fc4b5cf4de", + ".zattrs:md5,3c1153c408aa65830c7bcb1e1d8bb95c", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,647bd8e1d56f5a72302479f55dfccbdc", + ".zattrs:md5,b31620a308da4db0b7cc044dbb6df2a2", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,aa18046c95f5083a85adc0323edcf55c", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,340327e4658c115126929c4aad413a31", - "1:md5,e43b7810c69a614af5d1a5ea40349af6", - "0:md5,8978278a7826f69a827462b6b6482bd5", - "1:md5,72c95db61dcdace533063420279e2f88", + ".zarray:md5,2e01568c17b24b9a22ada8df6ad85f97", + "0:md5,a92a618248254e52cfc3654445084c4f", + ".zarray:md5,abcf55156add6712830021c645404ec7", + "0:md5,be3162e2d234c019aec4c70704ef5827", + ".zarray:md5,fb274cb1af1b7c06262151cc6c7ef3b6", + "0:md5,068175b80dadf520f0ff12539603899e", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,7d0ecab87d4ceae4daf84acc75e71ee4", + ".zattrs:md5,92f87df8db38b72048b57c1ee79efc8b", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,0b196b48bdda7c9ed5332884606d07e8", + ".zarray:md5,c3ae58d1d2c34d6c797c7913c8ee5e5d", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,929ffef2d0f259579f507c811510cfc1", - ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + "0:md5,49b34b416b38f19d714a339bbc3942e8", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,51f30e1d2c3fdd7cf89bdada6642b2c1", - ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", + "0:md5,ad194c69dc15a3ac1a640f177e1ac57b", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,93d1c4d922586df90447c036c58b41de", - ".zarray:md5,0b196b48bdda7c9ed5332884606d07e8", - ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,929ffef2d0f259579f507c811510cfc1", - ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + "0:md5,32f3dacd3f3c7ac39275320ac8988061", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,d78b1453d7b7df7ca933d72abe77c3d3", - ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + "0:md5,8db625ee6c307bdd28be4e0d16e3caa5", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,80825309fc69c89297bd9735a36187c7", - ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + "0:md5,4d4f99dcb681dd25361542392cb60f38", + ".zarray:md5,c3ae58d1d2c34d6c797c7913c8ee5e5d", + ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", + "0:md5,49b34b416b38f19d714a339bbc3942e8", + ".zarray:md5,e21b2665d5ad7da0f4f0f41dd37b92b2", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,243e038d0a9a080c2a4f324078bf837d", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,595a3b388753986ab9f48302a3ef6699", - ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", + "0:md5,7a6c2da4ef7c9d68bfc51c22c93d2fe1", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,8b064ab59549eb712b89f4c11efc3f2f", - ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", + "0:md5,5fc2750f3c0be4f68801dd8db04ac44b", + ".zarray:md5,e21b2665d5ad7da0f4f0f41dd37b92b2", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,a6ad4acf12cec31b6e0072925561c288", - ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", + "0:md5,b000aecf705cab96eca224ae636770bc", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,c8389702ef14ae841490a1eb911e541d", - ".zarray:md5,f9d408acbca280c3278e0575be4ba35f", + "0:md5,27f62f4312d1c7f436afa1a27a3f7a19", + ".zarray:md5,e21b2665d5ad7da0f4f0f41dd37b92b2", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,7b3ba357cb7dfd678091563caf868cf1", + "0:md5,3b0bfb8337159af021f5e5c375cb6ff4", ".zattrs:md5,ee9e2561ffa06a8a5b93ea6c0eff7377", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zarray:md5,8b7c1d3908cae5d4c2eddfc0369a608d", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,4f9409e8cba55576452886824fe380ec", - ".zarray:md5,21c68f0c19a88515b451183e711d237a", + "0:md5,100a15803cb99808902bb1a08782fcde", + ".zarray:md5,4c3a7bcb2a913c864c5f71df554fea87", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,e28d06462f249c654260c35e068b41ee", - ".zarray:md5,1644e79931988150c2dcfabfaa34860c", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,74624d5561d57890123dc7bfb122ba78", + "0:md5,ef7ee5eb8ade63cd1d7e48a2c2c2f0bb", ".zattrs:md5,ee9e2561ffa06a8a5b93ea6c0eff7377", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zarray:md5,8b7c1d3908cae5d4c2eddfc0369a608d", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", "0:md5,32b134819930c1668568f00fe06b1f3f", - ".zarray:md5,21c68f0c19a88515b451183e711d237a", + ".zarray:md5,4c3a7bcb2a913c864c5f71df554fea87", + ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", + "0:md5,ef7ee5eb8ade63cd1d7e48a2c2c2f0bb", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,e28d06462f249c654260c35e068b41ee", - ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + "0:md5,b5228aebe5d3f2e530923621298a067e", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,3ae7a59d0e4c4f74486ac905c3c9e8de", + "0:md5,4a444a043ff3c84c0739a9ae487e97c2", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,6a687a49c45c3c33dc209f5ba155f570", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,3f9de170008e103c37cf282d1f159ba1", - ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + "0:md5,5cee1dfa416dba3382f1ea1b484f3d3c", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,4f77877b43a2e60d342df3a71f55f484", - ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + "0:md5,41c698a2d2161f87323d6d81834551fa", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,ad7b508a4e1444e1c96c0bcbc3aacf31", - ".zarray:md5,1644e79931988150c2dcfabfaa34860c", + "0:md5,b8a48f54eb46ba04796844ed5c4d7223", + ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,2b88a5d1482549fb30deffb99fa40f20", - ".zarray:md5,0b196b48bdda7c9ed5332884606d07e8", + "0:md5,37cc1a733368cec15814f79a30386fa5", + ".zarray:md5,c3ae58d1d2c34d6c797c7913c8ee5e5d", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,929ffef2d0f259579f507c811510cfc1", - ".zarray:md5,66affee14626fc80349b052373fd8061", + "0:md5,49b34b416b38f19d714a339bbc3942e8", + ".zarray:md5,429be7ea59471311ee9a1457c6f4f6f8", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,2a140b06a1b9d9d505544fb95c975805", + "0:md5,80d4439891af6a09ccc74c0f5d826a6a", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", @@ -482,26 +493,26 @@ "0:md5,b89bade7bc089319a4e8242aad70f400", ".zarray:md5,4ee0db9305c15160aebaf22522f71168", ".zattrs:md5,1a7eb7e8b68cabba6dac4016c39515b8", - "0:md5,820086fcb71c01574b9101f5c7da6332", + "0:md5,bfa256e795018a86db00dd0c33da88cb", ".zarray:md5,8fc125cd69697992f7c1a452d6a2100c", ".zattrs:md5,1a7eb7e8b68cabba6dac4016c39515b8", "0:md5,db5579ad8d3db867ffbb022212fd396f", - ".zattrs:md5,8ff613dda1c9f16e3156002416a3004c", + ".zattrs:md5,f48d2e14ce3dc64acbd124ad18536369", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,a3b9b777672d072057168950b9babe72", + ".zarray:md5,3d6614c23dc86ac26d2c09fc6c73f57b", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,17613992d46768c1521a0a4ef8169910", + "0:md5,2dd7044a9f867f9fe479c01709dd76d5", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "zmetadata:md5,31ef3a80efaf858f9f3147a11f8218d6" + "zmetadata:md5,e50f7a50b909b3dc4650609f1c05480b" ] ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-11T11:07:41.831422" + "timestamp": "2025-07-11T11:52:21.890807" } } \ No newline at end of file From e683181fd5d30f31c22c7500b2890fdf70463373 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 11 Jul 2025 13:51:00 +0200 Subject: [PATCH 108/227] remove sopa cache --- tests/default.nf.test.snap | 127 ++++++++++++++++++------------------- workflows/sopa.nf | 6 +- 2 files changed, 67 insertions(+), 66 deletions(-) diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index e0be869..00daf00 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -20,8 +20,6 @@ "sample1.explorer/morphology.ome.tif", "sample1.explorer/transcripts.zarr.zip", "sample1.zarr", - "sample1.zarr/.sopa_cache", - "sample1.zarr/.sopa_cache/patches_file_transcripts", "sample1.zarr/.zattrs", "sample1.zarr/.zgroup", "sample1.zarr/images", @@ -305,15 +303,14 @@ "sample1.zarr/zmetadata" ], [ - "adata.h5ad:md5,6e99850a6780ca4ca184da6bdec6d406", - "analysis.zarr.zip:md5,3fb73c7d06e136965eab61e022d5e962", - "analysis_summary.html:md5,dacd035a666c28fa108938731a76c295", - "cell_feature_matrix.zarr.zip:md5,451d7174dc7da1cb86af32e0852ff2f8", - "cells.zarr.zip:md5,e8903ac247fedfea9b5558830d83871b", - "experiment.xenium:md5,348e5b7f2aaea83eb00acba0c748046a", - "morphology.ome.tif:md5,00bd32e18f5f571d77a1722577cd58b7", - "transcripts.zarr.zip:md5,695b7836b50f5548bc32a22edfda2d4d", - "patches_file_transcripts:md5,897316929176464ebc9ad085f31e7284", + "adata.h5ad:md5,b99fb116c855dd567dfb1a9db78e630d", + "analysis.zarr.zip:md5,2b571c412cbab1b3f21eb698ab1fa2bb", + "analysis_summary.html:md5,b91531236f90975706b5cb4da5658e45", + "cell_feature_matrix.zarr.zip:md5,5c4336ac64ca2b6e97ba13bc2bc806e4", + "cells.zarr.zip:md5,b9103195f416a8517a5363d770e8fb64", + "experiment.xenium:md5,930e1ffd92856368d030108998aa6bcf", + "morphology.ome.tif:md5,dbb0ecd47ddb7268826590a9c7d2b6e2", + "transcripts.zarr.zip:md5,69daf25eefcdfd0acf33b139b8af1ff4", ".zattrs:md5,468d8bdc77d7e7f172d4b4fe83b57aec", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", @@ -372,108 +369,108 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "shapes.parquet:md5,934e883744c782b9708e4ec59fb5b6d9", + "shapes.parquet:md5,c38e97ebb6cd99a5b82d896a509ef44d", ".zattrs:md5,37c0eabf77e69009a9f0c878e69ea262", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", "shapes.parquet:md5,ef7522c0a19ea52dbdb2b326d17920ef", ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "shapes.parquet:md5,f1a1b9f1b15eaaa86701cf3ebb24f1c8", + "shapes.parquet:md5,b34bef8f7cbfa4afde6248fd9b583e17", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,3c1153c408aa65830c7bcb1e1d8bb95c", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,b31620a308da4db0b7cc044dbb6df2a2", + ".zattrs:md5,e911a77b89028968997e31ef4ae8f3fd", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,2e01568c17b24b9a22ada8df6ad85f97", - "0:md5,a92a618248254e52cfc3654445084c4f", - ".zarray:md5,abcf55156add6712830021c645404ec7", - "0:md5,be3162e2d234c019aec4c70704ef5827", - ".zarray:md5,fb274cb1af1b7c06262151cc6c7ef3b6", - "0:md5,068175b80dadf520f0ff12539603899e", + ".zarray:md5,d97fa6aac3c1e31ac8f063cfa6ef45ed", + "0:md5,2edcf911ffae955e8af206c676e46176", + ".zarray:md5,f35f756335ecca127805892acb3446ac", + "0:md5,658447ab7083c9abe08a0aa4877430b2", + ".zarray:md5,3cb811d2bca83f0476e967a5da170b32", + "0:md5,43bcaf0de534ea35e6b3d43033bf3ecb", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,92f87df8db38b72048b57c1ee79efc8b", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,c3ae58d1d2c34d6c797c7913c8ee5e5d", + ".zarray:md5,bb87fb4a6945a5a359042f5324176561", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,49b34b416b38f19d714a339bbc3942e8", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + "0:md5,69b1e70f0b030acb7485ebbf46192af8", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,ad194c69dc15a3ac1a640f177e1ac57b", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + "0:md5,d39ce6a12540d904be1d6f93394a6f44", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,32f3dacd3f3c7ac39275320ac8988061", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + "0:md5,e810810afebb4d1c81c5b477d2671ba6", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,8db625ee6c307bdd28be4e0d16e3caa5", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + "0:md5,4b661f9e4ecbd857a8c39fd63f98a65d", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,4d4f99dcb681dd25361542392cb60f38", - ".zarray:md5,c3ae58d1d2c34d6c797c7913c8ee5e5d", + "0:md5,d73333540eff16046b4c9a72a2381d0b", + ".zarray:md5,bb87fb4a6945a5a359042f5324176561", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,49b34b416b38f19d714a339bbc3942e8", - ".zarray:md5,e21b2665d5ad7da0f4f0f41dd37b92b2", + "0:md5,69b1e70f0b030acb7485ebbf46192af8", + ".zarray:md5,b065dc1a1b6475d54f860b38242df2a5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,243e038d0a9a080c2a4f324078bf837d", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + "0:md5,1a3295a6b607fa49a9a807c469c51db6", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,7a6c2da4ef7c9d68bfc51c22c93d2fe1", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + "0:md5,ed9631257270e7d26e4ba2a40be44ab8", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,5fc2750f3c0be4f68801dd8db04ac44b", - ".zarray:md5,e21b2665d5ad7da0f4f0f41dd37b92b2", + "0:md5,b16ed13afed41b40c01b48d33c34580d", + ".zarray:md5,b065dc1a1b6475d54f860b38242df2a5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,b000aecf705cab96eca224ae636770bc", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + "0:md5,26df974c870e751314547e56b3edf7cf", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,27f62f4312d1c7f436afa1a27a3f7a19", - ".zarray:md5,e21b2665d5ad7da0f4f0f41dd37b92b2", + "0:md5,1866e8900fdd247568c7b2eeda5d2f0b", + ".zarray:md5,b065dc1a1b6475d54f860b38242df2a5", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,3b0bfb8337159af021f5e5c375cb6ff4", + "0:md5,e3ca9a3f912e0744b0b20ffa6d68ba8c", ".zattrs:md5,ee9e2561ffa06a8a5b93ea6c0eff7377", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zarray:md5,8b7c1d3908cae5d4c2eddfc0369a608d", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", "0:md5,100a15803cb99808902bb1a08782fcde", - ".zarray:md5,4c3a7bcb2a913c864c5f71df554fea87", + ".zarray:md5,9d9cf1604114bd639534be1fa4670a6a", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,ef7ee5eb8ade63cd1d7e48a2c2c2f0bb", + "0:md5,d1162df124e951ef17e5ceb745229c7f", ".zattrs:md5,ee9e2561ffa06a8a5b93ea6c0eff7377", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zarray:md5,8b7c1d3908cae5d4c2eddfc0369a608d", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", "0:md5,32b134819930c1668568f00fe06b1f3f", - ".zarray:md5,4c3a7bcb2a913c864c5f71df554fea87", + ".zarray:md5,9d9cf1604114bd639534be1fa4670a6a", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,ef7ee5eb8ade63cd1d7e48a2c2c2f0bb", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + "0:md5,d1162df124e951ef17e5ceb745229c7f", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,b5228aebe5d3f2e530923621298a067e", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + "0:md5,d6b42ee3824f92681738328913741405", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,4a444a043ff3c84c0739a9ae487e97c2", + "0:md5,e0cf3e6d4da7d726f829398bb4c8377b", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,6a687a49c45c3c33dc209f5ba155f570", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,5cee1dfa416dba3382f1ea1b484f3d3c", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + "0:md5,d472efc1af6c079e4d56c58f3f9151a7", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,41c698a2d2161f87323d6d81834551fa", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + "0:md5,355225de3e754a7b7271ffd228a11ede", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,b8a48f54eb46ba04796844ed5c4d7223", - ".zarray:md5,99bbfd038174cf14f2a7736798f563d5", + "0:md5,160434d5ab436de0632690d3b8d27fa0", + ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,37cc1a733368cec15814f79a30386fa5", - ".zarray:md5,c3ae58d1d2c34d6c797c7913c8ee5e5d", + "0:md5,9493aa4b5595b92bda096e4488bf8164", + ".zarray:md5,bb87fb4a6945a5a359042f5324176561", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,49b34b416b38f19d714a339bbc3942e8", - ".zarray:md5,429be7ea59471311ee9a1457c6f4f6f8", + "0:md5,69b1e70f0b030acb7485ebbf46192af8", + ".zarray:md5,75b96529271bc3bea0ea858a2d806af6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,80d4439891af6a09ccc74c0f5d826a6a", + "0:md5,70c5c61b59c3c256b45fa3ad19d6811c", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", @@ -513,6 +510,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-11T11:52:21.890807" + "timestamp": "2025-07-11T13:34:58.295593" } } \ No newline at end of file diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 47552d1..9c461a1 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -284,7 +284,9 @@ process report { process publish { label "process_single" - publishDir "${params.outdir}", mode: params.publish_dir_mode + publishDir "${params.outdir}", mode: params.publish_dir_mode, saveAs: { fname -> + fname.contains('sopa_cache') ? null : fname + } input: path sdata_path @@ -294,6 +296,8 @@ process publish { script: """ + rm -r ${sdata_path}/.sopa_cache + echo "Publishing ${sdata_path}" """ } From 11c80fb55d26b657104e6009b016929e4ac1feb5 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 11 Jul 2025 14:01:50 +0200 Subject: [PATCH 109/227] try ignoring files --- tests/.nftignore | 10 ++++ tests/default.nf.test.snap | 120 ++++++++++++++++++------------------- 2 files changed, 68 insertions(+), 62 deletions(-) diff --git a/tests/.nftignore b/tests/.nftignore index 73eb92f..1a006a8 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -1,2 +1,12 @@ .DS_Store pipeline_info/*.{html,json,txt,yml} +part.** +**.zarr.zip +adata.h5ad +analysis_summary.html +experiment.xenium +morphology.ome.tif +.zattrs +.zarray +0 +shapes.parquet diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 00daf00..e6f260d 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -303,14 +303,10 @@ "sample1.zarr/zmetadata" ], [ - "adata.h5ad:md5,b99fb116c855dd567dfb1a9db78e630d", - "analysis.zarr.zip:md5,2b571c412cbab1b3f21eb698ab1fa2bb", - "analysis_summary.html:md5,b91531236f90975706b5cb4da5658e45", - "cell_feature_matrix.zarr.zip:md5,5c4336ac64ca2b6e97ba13bc2bc806e4", - "cells.zarr.zip:md5,b9103195f416a8517a5363d770e8fb64", - "experiment.xenium:md5,930e1ffd92856368d030108998aa6bcf", - "morphology.ome.tif:md5,dbb0ecd47ddb7268826590a9c7d2b6e2", - "transcripts.zarr.zip:md5,69daf25eefcdfd0acf33b139b8af1ff4", + "adata.h5ad:md5,62673c01e286855c68bee022da66bfd7", + "analysis_summary.html:md5,e74ade1458b40df29588f9fc3a080de2", + "experiment.xenium:md5,6e7a64ad1c207a2836ff2f15e5da8b5c", + "morphology.ome.tif:md5,de1aee29bb4273b7116bbbd0e4dc911a", ".zattrs:md5,468d8bdc77d7e7f172d4b4fe83b57aec", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", @@ -369,108 +365,108 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "shapes.parquet:md5,c38e97ebb6cd99a5b82d896a509ef44d", + "shapes.parquet:md5,32d82cb98fe013a79e635a8efe368e3f", ".zattrs:md5,37c0eabf77e69009a9f0c878e69ea262", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", "shapes.parquet:md5,ef7522c0a19ea52dbdb2b326d17920ef", ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "shapes.parquet:md5,b34bef8f7cbfa4afde6248fd9b583e17", + "shapes.parquet:md5,e2b944085dab453baaea38c2f54e745d", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,3c1153c408aa65830c7bcb1e1d8bb95c", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,e911a77b89028968997e31ef4ae8f3fd", + ".zattrs:md5,56805cd6fc1e9e845e9a8d6f279b4533", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,d97fa6aac3c1e31ac8f063cfa6ef45ed", - "0:md5,2edcf911ffae955e8af206c676e46176", - ".zarray:md5,f35f756335ecca127805892acb3446ac", - "0:md5,658447ab7083c9abe08a0aa4877430b2", - ".zarray:md5,3cb811d2bca83f0476e967a5da170b32", - "0:md5,43bcaf0de534ea35e6b3d43033bf3ecb", + ".zarray:md5,6f77e741e3e0347f4e22d005f9ac9d1e", + "0:md5,6decf40a58d7ae851511e5987fdfda23", + ".zarray:md5,43aad52cc6e542c48fab7c2441093184", + "0:md5,429904e634562911d9885968fcd2090d", + ".zarray:md5,704fda43972fd9e0c4de3b53dc080cf1", + "0:md5,65959a7c7d631de624a0c8179a7e510d", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,92f87df8db38b72048b57c1ee79efc8b", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,bb87fb4a6945a5a359042f5324176561", + ".zarray:md5,046175f94a68676f25545c82f8037ca7", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,69b1e70f0b030acb7485ebbf46192af8", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + "0:md5,cd885eb6b3cffd3532cfefd7687d5a39", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,d39ce6a12540d904be1d6f93394a6f44", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + "0:md5,fb68253c5cb0a8467efc0e66f7d45f24", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,e810810afebb4d1c81c5b477d2671ba6", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + "0:md5,7487b509075c0e7785350e5f0cf301b1", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,4b661f9e4ecbd857a8c39fd63f98a65d", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + "0:md5,bf9dfe6dc4aa9595ec25eb919da739d2", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,d73333540eff16046b4c9a72a2381d0b", - ".zarray:md5,bb87fb4a6945a5a359042f5324176561", + "0:md5,a5f4cd8051f082f18dcaf85db609f658", + ".zarray:md5,046175f94a68676f25545c82f8037ca7", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,69b1e70f0b030acb7485ebbf46192af8", - ".zarray:md5,b065dc1a1b6475d54f860b38242df2a5", + "0:md5,cd885eb6b3cffd3532cfefd7687d5a39", + ".zarray:md5,8712ba77c4347b6db17f5099aeb118b6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,1a3295a6b607fa49a9a807c469c51db6", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + "0:md5,968f716325abd3a951a481e54b368dea", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,ed9631257270e7d26e4ba2a40be44ab8", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + "0:md5,7f33e5410eee9f46bf746504d45cd4e4", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,b16ed13afed41b40c01b48d33c34580d", - ".zarray:md5,b065dc1a1b6475d54f860b38242df2a5", + "0:md5,3f355108fef30024ff68c0fcf81f4846", + ".zarray:md5,8712ba77c4347b6db17f5099aeb118b6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,26df974c870e751314547e56b3edf7cf", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + "0:md5,1d6cb57598547cafdb29c7a6cff1a6a8", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,1866e8900fdd247568c7b2eeda5d2f0b", - ".zarray:md5,b065dc1a1b6475d54f860b38242df2a5", + "0:md5,86b2de9e739c83fb3f47833bc9a0c24d", + ".zarray:md5,8712ba77c4347b6db17f5099aeb118b6", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,e3ca9a3f912e0744b0b20ffa6d68ba8c", + "0:md5,a4365c2049c818eac1db0afd0a782249", ".zattrs:md5,ee9e2561ffa06a8a5b93ea6c0eff7377", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zarray:md5,8b7c1d3908cae5d4c2eddfc0369a608d", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", "0:md5,100a15803cb99808902bb1a08782fcde", - ".zarray:md5,9d9cf1604114bd639534be1fa4670a6a", + ".zarray:md5,047569d248975786380f47c5ac128e10", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,d1162df124e951ef17e5ceb745229c7f", + "0:md5,e88e0812de77c3401f820249e0b8f892", ".zattrs:md5,ee9e2561ffa06a8a5b93ea6c0eff7377", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zarray:md5,8b7c1d3908cae5d4c2eddfc0369a608d", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", "0:md5,32b134819930c1668568f00fe06b1f3f", - ".zarray:md5,9d9cf1604114bd639534be1fa4670a6a", + ".zarray:md5,047569d248975786380f47c5ac128e10", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,d1162df124e951ef17e5ceb745229c7f", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + "0:md5,e88e0812de77c3401f820249e0b8f892", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,d6b42ee3824f92681738328913741405", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + "0:md5,16e8f9b2a59585b191d95801bddbaaea", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,e0cf3e6d4da7d726f829398bb4c8377b", + "0:md5,b11050d30e982a29a2fe5b8bdb17d17d", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,6a687a49c45c3c33dc209f5ba155f570", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,d472efc1af6c079e4d56c58f3f9151a7", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + "0:md5,f7f9d7415f04f2cffdd4c45862ba9efd", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,355225de3e754a7b7271ffd228a11ede", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + "0:md5,3de62390dfe6b0886c774e6a90fc6064", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,160434d5ab436de0632690d3b8d27fa0", - ".zarray:md5,01fcf7ad459df92750a0b20bbee3b1f6", + "0:md5,943b47a3807cdc925bbab9686268d030", + ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,9493aa4b5595b92bda096e4488bf8164", - ".zarray:md5,bb87fb4a6945a5a359042f5324176561", + "0:md5,819630c7dfedee4f35ce7621f68568a0", + ".zarray:md5,046175f94a68676f25545c82f8037ca7", ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,69b1e70f0b030acb7485ebbf46192af8", - ".zarray:md5,75b96529271bc3bea0ea858a2d806af6", + "0:md5,cd885eb6b3cffd3532cfefd7687d5a39", + ".zarray:md5,6da9bca598418e1c0b042a7050423b72", ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,70c5c61b59c3c256b45fa3ad19d6811c", + "0:md5,2202e4d0db231b9d840ff1db2513eecc", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", @@ -510,6 +506,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-11T13:34:58.295593" + "timestamp": "2025-07-11T14:01:10.628163" } } \ No newline at end of file From a11592727afe01326712dc044363e630b28f29b7 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 11 Jul 2025 14:15:10 +0200 Subject: [PATCH 110/227] try again with nfignore --- tests/.nftignore | 18 ++--- tests/default.nf.test.snap | 149 +------------------------------------ 2 files changed, 10 insertions(+), 157 deletions(-) diff --git a/tests/.nftignore b/tests/.nftignore index 1a006a8..b42f4c6 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -1,12 +1,12 @@ .DS_Store pipeline_info/*.{html,json,txt,yml} -part.** +**/part.** **.zarr.zip -adata.h5ad -analysis_summary.html -experiment.xenium -morphology.ome.tif -.zattrs -.zarray -0 -shapes.parquet +**/adata.h5ad +**/analysis_summary.html +**/experiment.xenium +**/morphology.ome.tif +**/shapes.parquet +**/.zattrs +**/.zarray +**/0 diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index e6f260d..f719fce 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -303,201 +303,54 @@ "sample1.zarr/zmetadata" ], [ - "adata.h5ad:md5,62673c01e286855c68bee022da66bfd7", - "analysis_summary.html:md5,e74ade1458b40df29588f9fc3a080de2", - "experiment.xenium:md5,6e7a64ad1c207a2836ff2f15e5da8b5c", - "morphology.ome.tif:md5,de1aee29bb4273b7116bbbd0e4dc911a", - ".zattrs:md5,468d8bdc77d7e7f172d4b4fe83b57aec", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,5b3c6f476c3c21982958e18271dd834b", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,721b4e50f69cf172cded07c10e1d932d", - "0:md5,94d082c5dbba1860c82e14ceafab82d9", "1:md5,de228035c7935e884b4a1af8dc4903ac", "2:md5,5af87bde48de5aa97ab6c5e3c779d3ed", "3:md5,290456bdd4f13f815684d7df2bc8beb1", - "0:md5,cba8f18aee7db1db6e0337f829f38966", "1:md5,59bf54f6f8a70534ccb107f989a359e8", "2:md5,563f4d52c2a274ee07b1c2e903c8e053", "3:md5,5dc4e93210483696e4b8ccd261b59ea4", - "0:md5,1d3cb0e10d08bb661f9bba1e9539b3d0", "1:md5,6c497854befbd0fbc27df2f15dd6620a", "2:md5,5acfcfc8b05f5937b96dc5e330f00241", "3:md5,59af25140054c5fa5659295c0810adbc", - "0:md5,232acc572558367ff84e63299d4e2890", "1:md5,604ec2d55485b819025f15d6cb25c3d1", "2:md5,db580bfe58001e49f7a7f5e75748bc69", "3:md5,b00f1bb37e6ebf8ef0a70cf5e8c8f023", - ".zarray:md5,1d79c377c95e96c290e57dcc65615d81", - "0:md5,d432d2bc0120c7cf91718b4f24f040c5", "1:md5,7095884e5e1e9baac3a24d15ba0c1f7b", - "0:md5,af3a01b79d9633b67415a78b472a5ff2", "1:md5,d5b194a88cfcc4939f402d1e06fb6b7d", - ".zarray:md5,b5fe837c88ee52d35dbee2ec3a30cf17", - "0:md5,0328d110d9c6fac7bc5e091ab14e32e1", - ".zattrs:md5,cc30adb0bbb0e6f2be88d24170817966", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,c3de494758677af82d809ca2e4763c63", - "0:md5,d17ebfa93d74471f6ff65aa9c0504025", "1:md5,2338504a672e7656bdb5300d60f7353a", - "0:md5,09a64f9aa09225e293d8d0c85d40abb0", "1:md5,12ab66f310ab8ebffc2a178a9008523e", - "0:md5,8de482cb5a33656da5bac20dfb38b0fb", "1:md5,2716f328ef2e4ae7bdd2aebece4cc81a", - "0:md5,a68ca3a7c3d5ccea0df3edc682672538", "1:md5,e18bcf5aa4b9aa00b724efe4b7fc9a08", - "0:md5,fb949cda7000fc864a1c371655d73e67", "1:md5,228aed44f36d6c96e0ae385cfdbf59d7", - "0:md5,278c4ece169c3fe37444f22acb704640", "1:md5,320dae82e5e926f94c26ca0c496a94be", - "0:md5,a8495ec0ddbadd638100cc09925ff060", "1:md5,5e1f8a06ee1b586ed10d84e51695f34d", - "0:md5,063c83056f4b951a13a719326fb7d61a", "1:md5,0e9f2432ab893f8fac56226edbb7243c", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,441f7caee25d9885acd5cc2c1d93a5a2", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "part.0.parquet:md5,c9c4d7276a3c94db134f483387d07a46", - ".zattrs:md5,ee46fa68c2832b7ec6e1914b53d5514e", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "part.0.parquet:md5,3f65a56c60088849fad3eb9fac81dccf", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "shapes.parquet:md5,32d82cb98fe013a79e635a8efe368e3f", - ".zattrs:md5,37c0eabf77e69009a9f0c878e69ea262", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "shapes.parquet:md5,ef7522c0a19ea52dbdb2b326d17920ef", - ".zattrs:md5,8aa5c75ed9d029182869f7373c6ecf64", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "shapes.parquet:md5,e2b944085dab453baaea38c2f54e745d", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,3c1153c408aa65830c7bcb1e1d8bb95c", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,56805cd6fc1e9e845e9a8d6f279b4533", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,6f77e741e3e0347f4e22d005f9ac9d1e", - "0:md5,6decf40a58d7ae851511e5987fdfda23", - ".zarray:md5,43aad52cc6e542c48fab7c2441093184", - "0:md5,429904e634562911d9885968fcd2090d", - ".zarray:md5,704fda43972fd9e0c4de3b53dc080cf1", - "0:md5,65959a7c7d631de624a0c8179a7e510d", - ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,92f87df8db38b72048b57c1ee79efc8b", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,046175f94a68676f25545c82f8037ca7", - ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,cd885eb6b3cffd3532cfefd7687d5a39", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,fb68253c5cb0a8467efc0e66f7d45f24", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,7487b509075c0e7785350e5f0cf301b1", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,bf9dfe6dc4aa9595ec25eb919da739d2", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,a5f4cd8051f082f18dcaf85db609f658", - ".zarray:md5,046175f94a68676f25545c82f8037ca7", - ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,cd885eb6b3cffd3532cfefd7687d5a39", - ".zarray:md5,8712ba77c4347b6db17f5099aeb118b6", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,968f716325abd3a951a481e54b368dea", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,7f33e5410eee9f46bf746504d45cd4e4", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,3f355108fef30024ff68c0fcf81f4846", - ".zarray:md5,8712ba77c4347b6db17f5099aeb118b6", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,1d6cb57598547cafdb29c7a6cff1a6a8", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,86b2de9e739c83fb3f47833bc9a0c24d", - ".zarray:md5,8712ba77c4347b6db17f5099aeb118b6", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,a4365c2049c818eac1db0afd0a782249", - ".zattrs:md5,ee9e2561ffa06a8a5b93ea6c0eff7377", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,8b7c1d3908cae5d4c2eddfc0369a608d", - ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,100a15803cb99808902bb1a08782fcde", - ".zarray:md5,047569d248975786380f47c5ac128e10", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,e88e0812de77c3401f820249e0b8f892", - ".zattrs:md5,ee9e2561ffa06a8a5b93ea6c0eff7377", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,8b7c1d3908cae5d4c2eddfc0369a608d", - ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,32b134819930c1668568f00fe06b1f3f", - ".zarray:md5,047569d248975786380f47c5ac128e10", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,e88e0812de77c3401f820249e0b8f892", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,16e8f9b2a59585b191d95801bddbaaea", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,b11050d30e982a29a2fe5b8bdb17d17d", - ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,6a687a49c45c3c33dc209f5ba155f570", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,f7f9d7415f04f2cffdd4c45862ba9efd", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,3de62390dfe6b0886c774e6a90fc6064", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,943b47a3807cdc925bbab9686268d030", - ".zarray:md5,55ac4582ab84b9d7193055daae02d8aa", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,819630c7dfedee4f35ce7621f68568a0", - ".zarray:md5,046175f94a68676f25545c82f8037ca7", - ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,cd885eb6b3cffd3532cfefd7687d5a39", - ".zarray:md5,6da9bca598418e1c0b042a7050423b72", - ".zattrs:md5,a5993752ffd33ab722d89eb624a05434", - "0:md5,2202e4d0db231b9d840ff1db2513eecc", - ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,288aba90e17cb1a4b685961c18909db1", - ".zattrs:md5,1c65af9c8d0b8dd51a848664c302b40d", - "0:md5,55a54008ad1ba589aa210d2629c1df41", - ".zarray:md5,288aba90e17cb1a4b685961c18909db1", - ".zattrs:md5,1c65af9c8d0b8dd51a848664c302b40d", - "0:md5,55a54008ad1ba589aa210d2629c1df41", - ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,d36903528917a9947829b4c7d5b0b7a6", - ".zattrs:md5,1a7eb7e8b68cabba6dac4016c39515b8", - "0:md5,b89bade7bc089319a4e8242aad70f400", - ".zarray:md5,4ee0db9305c15160aebaf22522f71168", - ".zattrs:md5,1a7eb7e8b68cabba6dac4016c39515b8", - "0:md5,bfa256e795018a86db00dd0c33da88cb", - ".zarray:md5,8fc125cd69697992f7c1a452d6a2100c", - ".zattrs:md5,1a7eb7e8b68cabba6dac4016c39515b8", - "0:md5,db5579ad8d3db867ffbb022212fd396f", - ".zattrs:md5,f48d2e14ce3dc64acbd124ad18536369", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zarray:md5,3d6614c23dc86ac26d2c09fc6c73f57b", - ".zattrs:md5,c6759c37f5968bbe26a24623923e9002", - "0:md5,2dd7044a9f867f9fe479c01709dd76d5", - ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zattrs:md5,8d5893138e4f007b40857e2a95bbc5f1", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", "zmetadata:md5,e50f7a50b909b3dc4650609f1c05480b" ] @@ -506,6 +359,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-11T14:01:10.628163" + "timestamp": "2025-07-11T14:12:44.947434" } } \ No newline at end of file From 2e23857b16ff04c9a1a902f5746c9f4175779cb6 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 11 Jul 2025 15:39:21 +0200 Subject: [PATCH 111/227] improve doc --- README.md | 5 +++- docs/output.md | 3 ++- docs/usage.md | 63 ++++++++++++++++++++++++++----------------------- tests/README.md | 6 +++++ 4 files changed, 45 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 372ff81..9821af5 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,10 @@ SAMPLE1,/path/to/one/merscope_directory SAMPLE2,/path/to/one/merscope_directory ``` -Then, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config). Follow the README instructions of the latter link to get your `--configfile`. +> [!WARNING] +> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters). + +Then, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `--configfile` argument. Now, you can run the pipeline using: diff --git a/docs/output.md b/docs/output.md index f69d5cd..79a343e 100644 --- a/docs/output.md +++ b/docs/output.md @@ -7,7 +7,8 @@ This document describes the output produced by the pipeline. The directories listed below will be created in the results directory after the pipeline has finished. All paths are relative to the top-level results directory. 1. A `{sample}.zarr` directory containing a [SpatialData](https://spatialdata.scverse.org/en/stable/) object, where the `sample` name is either (i) specified by the samplesheet, or (ii) based on the name of the corresponding input directory. Refer to the [SpatialData docs](https://spatialdata.scverse.org/en/stable/) for usage details. If you are not familiar with `SpatialData`, you can also use directly the extracted `AnnData` object (see below). -2. A Xenium Explorer directory named `{sample}.explorer`. It contains a `report.html` with Sopa quality controls, `adata.h5ad` the AnnData object (extracted from the above SpatialData object), and `experiment.xenium` (double-click on it to open it on the Xenium Explorer ; you can download the software [here](https://www.10xgenomics.com/support/software/xenium-explorer/downloads)). The other files are data files related and required by the Xenium Explorer. +2. A `{sample}.explorer` for visualization and quick analysis. It contains a `report.html` with Sopa quality controls, `adata.h5ad` the AnnData object (extracted from the above SpatialData object), and `experiment.xenium` (double-click on it to open it on the Xenium Explorer ; you can download the software [here](https://www.10xgenomics.com/support/software/xenium-explorer/downloads)). The other files are data files related and required by the Xenium Explorer. +3. **(Only for Visium HD)** a `{sample}_spaceranger/outs` directory with the outputs of Space Ranger. ## Pipeline overview diff --git a/docs/usage.md b/docs/usage.md index c98e5d2..96e7140 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -4,62 +4,65 @@ > _Documentation of pipeline parameters is generated automatically from the pipeline schema and can no longer be found in markdown files._ -## Introduction - - - ## Samplesheet input -You will need to create a samplesheet with information about the samples you would like to analyse before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row as shown in the examples below. +You will need to create a samplesheet with information about the samples you would like to analyse before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 2 columns, and a header row as shown in the examples below. ```bash --input '[path to samplesheet file]' ``` -### Multiple runs of the same sample +### Main technologies + +For most technologies (i.e., all technologies supported by Sopa except Visium HD), the samplesheet lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example: -The `sample` identifiers have to be the same when you have re-sequenced the same sample more than once e.g. to increase sequencing depth. The pipeline will concatenate the raw reads before performing any downstream analysis. Below is an example for the same sample sequenced across 3 lanes: +`samplesheet.csv`: ```csv title="samplesheet.csv" -sample,fastq_1,fastq_2 -CONTROL_REP1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz -CONTROL_REP1,AEG588A1_S1_L003_R1_001.fastq.gz,AEG588A1_S1_L003_R2_001.fastq.gz -CONTROL_REP1,AEG588A1_S1_L004_R1_001.fastq.gz,AEG588A1_S1_L004_R2_001.fastq.gz +sample,data_path +SAMPLE1,/path/to/one/merscope_directory +SAMPLE2,/path/to/one/merscope_directory ``` -### Full samplesheet +### Visium HD -The pipeline will auto-detect whether a sample is single- or paired-end using the information provided in the samplesheet. The samplesheet can have as many columns as you desire, however, there is a strict requirement for the first 3 columns to match those defined in the table below. +Some extra columns need to be provided specifically for Visium HD. This is because we need to run [Space Ranger](https://www.10xgenomics.com/support/software/space-ranger/latest) before running Sopa. -A final samplesheet file consisting of both single- and paired-end data may look something like the one below. This is for 6 samples, where `TREATMENT_REP3` has been sequenced twice. +For each row, you'll need a `sample` name, its corresponding `fastq_dir`, `image`, `cytaimage`, `slide`, and `area`. Note that the `image` is the full-resolution microscopy image (not the cytassist image) and is **required** by Sopa as we'll run cell segmentation on the H&E full-resolution slide. +For more details, see the [`spaceranger-count` arguments](https://nf-co.re/modules/spaceranger_count). ```csv title="samplesheet.csv" -sample,fastq_1,fastq_2 -CONTROL_REP1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz -CONTROL_REP2,AEG588A2_S2_L002_R1_001.fastq.gz,AEG588A2_S2_L002_R2_001.fastq.gz -CONTROL_REP3,AEG588A3_S3_L002_R1_001.fastq.gz,AEG588A3_S3_L002_R2_001.fastq.gz -TREATMENT_REP1,AEG588A4_S4_L003_R1_001.fastq.gz, -TREATMENT_REP2,AEG588A5_S5_L003_R1_001.fastq.gz, -TREATMENT_REP3,AEG588A6_S6_L003_R1_001.fastq.gz, -TREATMENT_REP3,AEG588A6_S6_L004_R1_001.fastq.gz, +sample,fastq_dir,image,cytaimage,slide,area +Visium_HD_Human_Lung_Cancer_Fixed_Frozen,Visium_HD_Human_Lung_Cancer_Fixed_Frozen_fastqs,Visium_HD_Human_Lung_Cancer_Fixed_Frozen_tissue_image.btf,Visium_HD_Human_Lung_Cancer_Fixed_Frozen_image.tif,H1-TY834G7,D1 ``` -| Column | Description | -| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `sample` | Custom sample name. This entry will be identical for multiple sequencing libraries/runs from the same sample. Spaces in sample names are automatically converted to underscores (`_`). | -| `fastq_1` | Full path to FastQ file for Illumina short reads 1. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". | -| `fastq_2` | Full path to FastQ file for Illumina short reads 2. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". | +The above samplesheet is made for [this public sample](https://www.10xgenomics.com/datasets/visium-hd-cytassist-gene-expression-human-lung-cancer-fixed-frozen) (download all the "Input files" and untar the `fastq` zip file). + +## Sopa config file + +You'll also need to choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `--configfile` argument. -An [example samplesheet](../assets/samplesheet.csv) has been provided with the pipeline. +For instance, if you have Xenium data and want to run Sopa with `proseg`, you can use: + +``` +--configfile https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/xenium/proseg.yaml +``` ## Running the pipeline -The typical command for running the pipeline is as follows: +Once you have defined your samplesheet and `configfile`, you'll be able to run `nf-core/sopa`. The typical command for running the pipeline is as follows: ```bash -nextflow run nf-core/sopa --input ./samplesheet.csv --outdir ./results -profile docker +nextflow run nf-core/sopa --configfile --input ./samplesheet.csv --outdir ./results -profile docker ``` +> [!NOTE] +> For Visium HD data, you may also need to provide a `--spaceranger_probeset` argument with an official 10X Genomics probe set (see [here](https://www.10xgenomics.com/support/software/space-ranger/downloads)). For instance, you can use: +> +> ``` +> --spaceranger_probeset https://cf.10xgenomics.com/supp/spatial-exp/probeset/Visium_Human_Transcriptome_Probe_Set_v2.0_GRCh38-2020-A.csv +> ``` + This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles. Note that the pipeline will create the following files in your working directory: diff --git a/tests/README.md b/tests/README.md index 2d6842e..38c9473 100644 --- a/tests/README.md +++ b/tests/README.md @@ -22,3 +22,9 @@ curl -O https://cf.10xgenomics.com/samples/spatial-exp/3.1.1/Visium_HD_Human_Lun # untar FASTQs tar xvf Visium_HD_Human_Lung_Cancer_Fixed_Frozen_fastqs.tar ``` + +You can download the official 10X Genomics probe sets [here](https://www.10xgenomics.com/support/software/space-ranger/downloads). + +``` +https://cf.10xgenomics.com/supp/spatial-exp/probeset/Visium_Human_Transcriptome_Probe_Set_v2.0_GRCh38-2020-A.csv +``` From 933bcde392471c19aed7cdb302facb45d2922365 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 11 Jul 2025 15:39:44 +0200 Subject: [PATCH 112/227] fix ro-crate --- ro-crate-metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index c42f549..4228306 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "InProgress", "datePublished": "2025-07-09T19:52:43+00:00", - "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n

    \n \"sopa_overview\"\n

    \n\n\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\nThen, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config). Follow the README instructions of the latter link to get your `--configfile`.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n --configfile \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n

    \n \"sopa_overview\"\n

    \n\n\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `--configfile` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n --configfile \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" From adca8bdab56daaf3b074deac2ad36f184e648729 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 11 Jul 2025 15:58:19 +0200 Subject: [PATCH 113/227] fix vhd usage --- subworkflows/local/spaceranger.nf | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/subworkflows/local/spaceranger.nf b/subworkflows/local/spaceranger.nf index 91a77fd..d5c06f7 100644 --- a/subworkflows/local/spaceranger.nf +++ b/subworkflows/local/spaceranger.nf @@ -93,6 +93,8 @@ def create_channel_spaceranger(LinkedHashMap meta) { return v ? file(v) : [] } + def slide = meta.remove("slide") + def area = meta.remove("area") def fastq_dir = meta.remove("fastq_dir") def fastq_files = file("${fastq_dir}/${meta['id']}*.fastq.gz") def manual_alignment = get_file_from_meta("manual_alignment") @@ -106,15 +108,25 @@ def create_channel_spaceranger(LinkedHashMap meta) { error("No `fastq_dir` specified or no samples found in folder.") } - def check_optional_files = [["manual_alignment", manual_alignment], ["slidefile", slidefile], ["image", image], ["cytaimage", cytaimage], ["colorizedimage", colorizedimage], ["darkimage", darkimage]] - check_optional_files.each { name, value -> - if (value && !file(value).exists()) { - error("File for `${name}` is specified, but does not exist: ${value}.") + // Check for existance of optional files + def optional_files = [ + 'manual_alignment': manual_alignment, + 'slidefile': slidefile, + 'image': image, + 'cytaimage': cytaimage, + 'colorizedimage': colorizedimage, + 'darkimage': darkimage, + ] + optional_files.each { k, f -> + if (f && !f.exists()) { + error("File for `${k}` is specified, but does not exist: ${f}.") } } + + // Check that at least one type of image is specified if (!(image || cytaimage || colorizedimage || darkimage)) { error("Need to specify at least one of 'image', 'cytaimage', 'colorizedimage', or 'darkimage' in the samplesheet") } - return [meta, fastq_files, image, cytaimage, darkimage, colorizedimage, manual_alignment, slidefile] + return [meta, fastq_files, image, slide, area, cytaimage, darkimage, colorizedimage, manual_alignment, slidefile] } From 4bd39bde3fdbe82d112e67aff4409f50a06f1d15 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 15 Jul 2025 09:04:31 +0200 Subject: [PATCH 114/227] fix spaceranger output --- workflows/sopa.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 9c461a1..a070c1f 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -33,7 +33,7 @@ workflow SOPA { if (config.read.technology == "visium_hd") { (ch_input_spatialdata, versions) = SPACERANGER(ch_samplesheet) - ch_input_spatialdata = ch_input_spatialdata.map { meta, out -> [meta, [out.toString().replaceFirst(/(.*?outs).*/, '$1'), meta.image]] } + ch_input_spatialdata = ch_input_spatialdata.map { meta, out -> [meta, [out[0].toString().replaceFirst(/(.*?outs).*/, '$1'), meta.image]] } ch_versions = ch_versions.mix(versions) } From 528dd34f76de9d5ff4ad7e2c13dee0956d3803d6 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 15 Jul 2025 09:08:14 +0200 Subject: [PATCH 115/227] remove useless println --- modules/local/utils.nf | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/local/utils.nf b/modules/local/utils.nf index d72f437..2512ddf 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -54,8 +54,6 @@ def ArgsReaderCLI(Map args, Map meta) { args.kwargs["dataset_id"] = meta.id } - println("meta: ${meta}") - if (meta.image) { args.kwargs["fullres_image_file"] = meta.image } From 215d6d879e69c2d528c44247667871300fab7004 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 15 Jul 2025 09:26:36 +0200 Subject: [PATCH 116/227] remove TODO and readme update --- README.md | 12 +++++++++--- conf/base.config | 9 --------- docs/output.md | 2 +- tests/nextflow.config | 4 +--- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 9821af5..c867895 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,15 @@ sopa_overview

    - +0. (Visium HD only) Raw data processing with Space Ranger +1. (Optional) Tissue segmentation +2. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ... +3. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells +4. (Optional) Cell-type annotation **_- coming soon_** +5. User-friendly output creation for visualization and quick analysis +6. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory + +After running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://gustaveroussy.github.io/sopa/). ## Usage @@ -88,8 +96,6 @@ For further information or help, don't hesitate to get in touch on the [Slack `# - - An extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file. You can cite the `sopa` publication as follows: diff --git a/conf/base.config b/conf/base.config index e53b97c..cf6c183 100644 --- a/conf/base.config +++ b/conf/base.config @@ -9,8 +9,6 @@ */ process { - - // TODO nf-core: Check the defaults for all processes cpus = { 1 * task.attempt } memory = { 6.GB * task.attempt } time = { 4.h * task.attempt } @@ -19,13 +17,6 @@ process { maxRetries = 1 maxErrors = '-1' - // Process-specific resource requirements - // NOTE - Please try and reuse the labels below as much as possible. - // These labels are used and recognised by default in DSL2 files hosted on nf-core/modules. - // If possible, it would be nice to keep the same label naming convention when - // adding in your local modules too. - // TODO nf-core: Customise requirements for specific processes. - // See https://www.nextflow.io/docs/latest/config.html#config-process-selectors withLabel:process_single { cpus = { 1 } memory = { 6.GB * task.attempt } diff --git a/docs/output.md b/docs/output.md index 79a343e..a1099b8 100644 --- a/docs/output.md +++ b/docs/output.md @@ -6,7 +6,7 @@ This document describes the output produced by the pipeline. The directories listed below will be created in the results directory after the pipeline has finished. All paths are relative to the top-level results directory. -1. A `{sample}.zarr` directory containing a [SpatialData](https://spatialdata.scverse.org/en/stable/) object, where the `sample` name is either (i) specified by the samplesheet, or (ii) based on the name of the corresponding input directory. Refer to the [SpatialData docs](https://spatialdata.scverse.org/en/stable/) for usage details. If you are not familiar with `SpatialData`, you can also use directly the extracted `AnnData` object (see below). +1. A `{sample}.zarr` directory containing a [SpatialData](https://spatialdata.scverse.org/en/stable/) object, where the `sample` name is either (i) specified by the samplesheet, or (ii) based on the name of the corresponding input directory. Refer to the [SpatialData docs](https://spatialdata.scverse.org/en/stable/) for usage details, or to the [documentation of `sopa` as a Python package](https://gustaveroussy.github.io/sopa/). If you are not familiar with `SpatialData`, you can also use directly the extracted `AnnData` object (see below). 2. A `{sample}.explorer` for visualization and quick analysis. It contains a `report.html` with Sopa quality controls, `adata.h5ad` the AnnData object (extracted from the above SpatialData object), and `experiment.xenium` (double-click on it to open it on the Xenium Explorer ; you can download the software [here](https://www.10xgenomics.com/support/software/xenium-explorer/downloads)). The other files are data files related and required by the Xenium Explorer. 3. **(Only for Visium HD)** a `{sample}_spaceranger/outs` directory with the outputs of Space Ranger. diff --git a/tests/nextflow.config b/tests/nextflow.config index acd0dbf..9c78692 100644 --- a/tests/nextflow.config +++ b/tests/nextflow.config @@ -4,11 +4,9 @@ ======================================================================================== */ -// TODO nf-core: Specify any additional parameters here -// Or any resources requirements params { modules_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/sopa' } -aws.client.anonymous = true // fixes S3 access issues on self-hosted runners +aws.client.anonymous = true From 4dfd7ef128b26e1aab0f8a739fa7f8ae8ca56407 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 15 Jul 2025 15:58:40 +0200 Subject: [PATCH 117/227] update patchSegmentationCellpose containerOptions --- conf/modules.config | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/conf/modules.config b/conf/modules.config index 8f67c34..b8f18f9 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -19,4 +19,8 @@ process { saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } + + withName: patchSegmentationCellpose { + containerOptions = '' + } } From 07c45e4f4f73737efbcdbaa0a9ccb485c8b30ab7 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 16 Jul 2025 09:43:02 +0200 Subject: [PATCH 118/227] add more configs for nf-test --- conf/test_cellpose.config | 28 +++ conf/test_proseg.config | 28 +++ nextflow.config | 6 +- tests/cellpose.nf.test | 35 ++++ tests/cellpose.nf.test.snap | 364 ++++++++++++++++++++++++++++++++++++ tests/proseg.nf.test | 35 ++++ tests/proseg.nf.test.snap | 364 ++++++++++++++++++++++++++++++++++++ 7 files changed, 858 insertions(+), 2 deletions(-) create mode 100644 conf/test_cellpose.config create mode 100644 conf/test_proseg.config create mode 100644 tests/cellpose.nf.test create mode 100644 tests/cellpose.nf.test.snap create mode 100644 tests/proseg.nf.test create mode 100644 tests/proseg.nf.test.snap diff --git a/conf/test_cellpose.config b/conf/test_cellpose.config new file mode 100644 index 0000000..1d9f71e --- /dev/null +++ b/conf/test_cellpose.config @@ -0,0 +1,28 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/sopa -profile test, --outdir + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h', + ] +} + +params { + config_profile_name = 'Test profile with Cellpose' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Input data + input = "${baseDir}/tests/samplesheet.csv" + configfile = "https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/toy/cellpose.yaml" +} diff --git a/conf/test_proseg.config b/conf/test_proseg.config new file mode 100644 index 0000000..fd5c7d7 --- /dev/null +++ b/conf/test_proseg.config @@ -0,0 +1,28 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/sopa -profile test, --outdir + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h', + ] +} + +params { + config_profile_name = 'Test profile with Proseg' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Input data + input = "${baseDir}/tests/samplesheet.csv" + configfile = "https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/toy/proseg.yaml" +} diff --git a/nextflow.config b/nextflow.config index 0ad4791..2882902 100644 --- a/nextflow.config +++ b/nextflow.config @@ -157,8 +157,10 @@ profiles { apptainer.runOptions = '--nv' singularity.runOptions = '--nv' } - test { includeConfig 'conf/test.config' } - test_full { includeConfig 'conf/test_full.config' } + test { includeConfig 'conf/test.config' } + test_proseg { includeConfig 'conf/test_proseg.config' } + test_cellpose { includeConfig 'conf/test_cellpose.config' } + test_full { includeConfig 'conf/test_full.config' } } // Load nf-core custom profiles from different institutions diff --git a/tests/cellpose.nf.test b/tests/cellpose.nf.test new file mode 100644 index 0000000..f428bc1 --- /dev/null +++ b/tests/cellpose.nf.test @@ -0,0 +1,35 @@ +nextflow_pipeline { + + name "Test pipeline" + script "../main.nf" + tag "pipeline" + + test("-profile test") { + + when { + params { + outdir = "$outputDir" + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we test pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + stable_path + ).match() } + ) + } + } +} diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap new file mode 100644 index 0000000..aa88e26 --- /dev/null +++ b/tests/cellpose.nf.test.snap @@ -0,0 +1,364 @@ +{ + "-profile test": { + "content": [ + 9, + { + "Workflow": { + "nf-core/sopa": "v1.0.0dev" + } + }, + [ + "pipeline_info", + "pipeline_info/nf_core_sopa_software_mqc_versions.yml", + "sample1.explorer", + "sample1.explorer/adata.h5ad", + "sample1.explorer/analysis.zarr.zip", + "sample1.explorer/analysis_summary.html", + "sample1.explorer/cell_feature_matrix.zarr.zip", + "sample1.explorer/cells.zarr.zip", + "sample1.explorer/experiment.xenium", + "sample1.explorer/morphology.ome.tif", + "sample1.explorer/transcripts.zarr.zip", + "sample1.zarr", + "sample1.zarr/.zattrs", + "sample1.zarr/.zgroup", + "sample1.zarr/images", + "sample1.zarr/images/.zgroup", + "sample1.zarr/images/he_image", + "sample1.zarr/images/he_image/.zattrs", + "sample1.zarr/images/he_image/.zgroup", + "sample1.zarr/images/he_image/0", + "sample1.zarr/images/he_image/0/.zarray", + "sample1.zarr/images/he_image/0/0", + "sample1.zarr/images/he_image/0/0/0", + "sample1.zarr/images/he_image/0/0/0/0", + "sample1.zarr/images/he_image/0/0/0/1", + "sample1.zarr/images/he_image/0/0/0/2", + "sample1.zarr/images/he_image/0/0/0/3", + "sample1.zarr/images/he_image/0/0/1", + "sample1.zarr/images/he_image/0/0/1/0", + "sample1.zarr/images/he_image/0/0/1/1", + "sample1.zarr/images/he_image/0/0/1/2", + "sample1.zarr/images/he_image/0/0/1/3", + "sample1.zarr/images/he_image/0/0/2", + "sample1.zarr/images/he_image/0/0/2/0", + "sample1.zarr/images/he_image/0/0/2/1", + "sample1.zarr/images/he_image/0/0/2/2", + "sample1.zarr/images/he_image/0/0/2/3", + "sample1.zarr/images/he_image/0/0/3", + "sample1.zarr/images/he_image/0/0/3/0", + "sample1.zarr/images/he_image/0/0/3/1", + "sample1.zarr/images/he_image/0/0/3/2", + "sample1.zarr/images/he_image/0/0/3/3", + "sample1.zarr/images/he_image/1", + "sample1.zarr/images/he_image/1/.zarray", + "sample1.zarr/images/he_image/1/0", + "sample1.zarr/images/he_image/1/0/0", + "sample1.zarr/images/he_image/1/0/0/0", + "sample1.zarr/images/he_image/1/0/0/1", + "sample1.zarr/images/he_image/1/0/1", + "sample1.zarr/images/he_image/1/0/1/0", + "sample1.zarr/images/he_image/1/0/1/1", + "sample1.zarr/images/he_image/2", + "sample1.zarr/images/he_image/2/.zarray", + "sample1.zarr/images/he_image/2/0", + "sample1.zarr/images/he_image/2/0/0", + "sample1.zarr/images/he_image/2/0/0/0", + "sample1.zarr/images/image", + "sample1.zarr/images/image/.zattrs", + "sample1.zarr/images/image/.zgroup", + "sample1.zarr/images/image/0", + "sample1.zarr/images/image/0/.zarray", + "sample1.zarr/images/image/0/0", + "sample1.zarr/images/image/0/0/0", + "sample1.zarr/images/image/0/0/0/0", + "sample1.zarr/images/image/0/0/0/1", + "sample1.zarr/images/image/0/0/1", + "sample1.zarr/images/image/0/0/1/0", + "sample1.zarr/images/image/0/0/1/1", + "sample1.zarr/images/image/0/1", + "sample1.zarr/images/image/0/1/0", + "sample1.zarr/images/image/0/1/0/0", + "sample1.zarr/images/image/0/1/0/1", + "sample1.zarr/images/image/0/1/1", + "sample1.zarr/images/image/0/1/1/0", + "sample1.zarr/images/image/0/1/1/1", + "sample1.zarr/images/image/0/2", + "sample1.zarr/images/image/0/2/0", + "sample1.zarr/images/image/0/2/0/0", + "sample1.zarr/images/image/0/2/0/1", + "sample1.zarr/images/image/0/2/1", + "sample1.zarr/images/image/0/2/1/0", + "sample1.zarr/images/image/0/2/1/1", + "sample1.zarr/images/image/0/3", + "sample1.zarr/images/image/0/3/0", + "sample1.zarr/images/image/0/3/0/0", + "sample1.zarr/images/image/0/3/0/1", + "sample1.zarr/images/image/0/3/1", + "sample1.zarr/images/image/0/3/1/0", + "sample1.zarr/images/image/0/3/1/1", + "sample1.zarr/points", + "sample1.zarr/points/.zgroup", + "sample1.zarr/points/misc", + "sample1.zarr/points/misc/.zattrs", + "sample1.zarr/points/misc/.zgroup", + "sample1.zarr/points/misc/points.parquet", + "sample1.zarr/points/misc/points.parquet/part.0.parquet", + "sample1.zarr/points/transcripts", + "sample1.zarr/points/transcripts/.zattrs", + "sample1.zarr/points/transcripts/.zgroup", + "sample1.zarr/points/transcripts/points.parquet", + "sample1.zarr/points/transcripts/points.parquet/part.0.parquet", + "sample1.zarr/shapes", + "sample1.zarr/shapes/.zgroup", + "sample1.zarr/shapes/baysor_boundaries", + "sample1.zarr/shapes/baysor_boundaries/.zattrs", + "sample1.zarr/shapes/baysor_boundaries/.zgroup", + "sample1.zarr/shapes/baysor_boundaries/shapes.parquet", + "sample1.zarr/shapes/cells", + "sample1.zarr/shapes/cells/.zattrs", + "sample1.zarr/shapes/cells/.zgroup", + "sample1.zarr/shapes/cells/shapes.parquet", + "sample1.zarr/shapes/transcripts_patches", + "sample1.zarr/shapes/transcripts_patches/.zattrs", + "sample1.zarr/shapes/transcripts_patches/.zgroup", + "sample1.zarr/shapes/transcripts_patches/shapes.parquet", + "sample1.zarr/tables", + "sample1.zarr/tables/.zgroup", + "sample1.zarr/tables/table", + "sample1.zarr/tables/table/.zattrs", + "sample1.zarr/tables/table/.zgroup", + "sample1.zarr/tables/table/X", + "sample1.zarr/tables/table/X/.zattrs", + "sample1.zarr/tables/table/X/.zgroup", + "sample1.zarr/tables/table/X/data", + "sample1.zarr/tables/table/X/data/.zarray", + "sample1.zarr/tables/table/X/data/0", + "sample1.zarr/tables/table/X/indices", + "sample1.zarr/tables/table/X/indices/.zarray", + "sample1.zarr/tables/table/X/indices/0", + "sample1.zarr/tables/table/X/indptr", + "sample1.zarr/tables/table/X/indptr/.zarray", + "sample1.zarr/tables/table/X/indptr/0", + "sample1.zarr/tables/table/layers", + "sample1.zarr/tables/table/layers/.zattrs", + "sample1.zarr/tables/table/layers/.zgroup", + "sample1.zarr/tables/table/obs", + "sample1.zarr/tables/table/obs/.zattrs", + "sample1.zarr/tables/table/obs/.zgroup", + "sample1.zarr/tables/table/obs/_index", + "sample1.zarr/tables/table/obs/_index/.zarray", + "sample1.zarr/tables/table/obs/_index/.zattrs", + "sample1.zarr/tables/table/obs/_index/0", + "sample1.zarr/tables/table/obs/area", + "sample1.zarr/tables/table/obs/area/.zarray", + "sample1.zarr/tables/table/obs/area/.zattrs", + "sample1.zarr/tables/table/obs/area/0", + "sample1.zarr/tables/table/obs/avg_assignment_confidence", + "sample1.zarr/tables/table/obs/avg_assignment_confidence/.zarray", + "sample1.zarr/tables/table/obs/avg_assignment_confidence/.zattrs", + "sample1.zarr/tables/table/obs/avg_assignment_confidence/0", + "sample1.zarr/tables/table/obs/avg_confidence", + "sample1.zarr/tables/table/obs/avg_confidence/.zarray", + "sample1.zarr/tables/table/obs/avg_confidence/.zattrs", + "sample1.zarr/tables/table/obs/avg_confidence/0", + "sample1.zarr/tables/table/obs/baysor_area", + "sample1.zarr/tables/table/obs/baysor_area/.zarray", + "sample1.zarr/tables/table/obs/baysor_area/.zattrs", + "sample1.zarr/tables/table/obs/baysor_area/0", + "sample1.zarr/tables/table/obs/cell_id", + "sample1.zarr/tables/table/obs/cell_id/.zarray", + "sample1.zarr/tables/table/obs/cell_id/.zattrs", + "sample1.zarr/tables/table/obs/cell_id/0", + "sample1.zarr/tables/table/obs/cluster", + "sample1.zarr/tables/table/obs/cluster/.zarray", + "sample1.zarr/tables/table/obs/cluster/.zattrs", + "sample1.zarr/tables/table/obs/cluster/0", + "sample1.zarr/tables/table/obs/density", + "sample1.zarr/tables/table/obs/density/.zarray", + "sample1.zarr/tables/table/obs/density/.zattrs", + "sample1.zarr/tables/table/obs/density/0", + "sample1.zarr/tables/table/obs/elongation", + "sample1.zarr/tables/table/obs/elongation/.zarray", + "sample1.zarr/tables/table/obs/elongation/.zattrs", + "sample1.zarr/tables/table/obs/elongation/0", + "sample1.zarr/tables/table/obs/lifespan", + "sample1.zarr/tables/table/obs/lifespan/.zarray", + "sample1.zarr/tables/table/obs/lifespan/.zattrs", + "sample1.zarr/tables/table/obs/lifespan/0", + "sample1.zarr/tables/table/obs/max_cluster_frac", + "sample1.zarr/tables/table/obs/max_cluster_frac/.zarray", + "sample1.zarr/tables/table/obs/max_cluster_frac/.zattrs", + "sample1.zarr/tables/table/obs/max_cluster_frac/0", + "sample1.zarr/tables/table/obs/n_transcripts", + "sample1.zarr/tables/table/obs/n_transcripts/.zarray", + "sample1.zarr/tables/table/obs/n_transcripts/.zattrs", + "sample1.zarr/tables/table/obs/n_transcripts/0", + "sample1.zarr/tables/table/obs/region", + "sample1.zarr/tables/table/obs/region/.zattrs", + "sample1.zarr/tables/table/obs/region/.zgroup", + "sample1.zarr/tables/table/obs/region/categories", + "sample1.zarr/tables/table/obs/region/categories/.zarray", + "sample1.zarr/tables/table/obs/region/categories/.zattrs", + "sample1.zarr/tables/table/obs/region/categories/0", + "sample1.zarr/tables/table/obs/region/codes", + "sample1.zarr/tables/table/obs/region/codes/.zarray", + "sample1.zarr/tables/table/obs/region/codes/.zattrs", + "sample1.zarr/tables/table/obs/region/codes/0", + "sample1.zarr/tables/table/obs/slide", + "sample1.zarr/tables/table/obs/slide/.zattrs", + "sample1.zarr/tables/table/obs/slide/.zgroup", + "sample1.zarr/tables/table/obs/slide/categories", + "sample1.zarr/tables/table/obs/slide/categories/.zarray", + "sample1.zarr/tables/table/obs/slide/categories/.zattrs", + "sample1.zarr/tables/table/obs/slide/categories/0", + "sample1.zarr/tables/table/obs/slide/codes", + "sample1.zarr/tables/table/obs/slide/codes/.zarray", + "sample1.zarr/tables/table/obs/slide/codes/.zattrs", + "sample1.zarr/tables/table/obs/slide/codes/0", + "sample1.zarr/tables/table/obs/x", + "sample1.zarr/tables/table/obs/x/.zarray", + "sample1.zarr/tables/table/obs/x/.zattrs", + "sample1.zarr/tables/table/obs/x/0", + "sample1.zarr/tables/table/obs/y", + "sample1.zarr/tables/table/obs/y/.zarray", + "sample1.zarr/tables/table/obs/y/.zattrs", + "sample1.zarr/tables/table/obs/y/0", + "sample1.zarr/tables/table/obsm", + "sample1.zarr/tables/table/obsm/.zattrs", + "sample1.zarr/tables/table/obsm/.zgroup", + "sample1.zarr/tables/table/obsm/intensities", + "sample1.zarr/tables/table/obsm/intensities/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/.zgroup", + "sample1.zarr/tables/table/obsm/intensities/CD20", + "sample1.zarr/tables/table/obsm/intensities/CD20/.zarray", + "sample1.zarr/tables/table/obsm/intensities/CD20/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/CD20/0", + "sample1.zarr/tables/table/obsm/intensities/CD3", + "sample1.zarr/tables/table/obsm/intensities/CD3/.zarray", + "sample1.zarr/tables/table/obsm/intensities/CD3/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/CD3/0", + "sample1.zarr/tables/table/obsm/intensities/CK", + "sample1.zarr/tables/table/obsm/intensities/CK/.zarray", + "sample1.zarr/tables/table/obsm/intensities/CK/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/CK/0", + "sample1.zarr/tables/table/obsm/intensities/DAPI", + "sample1.zarr/tables/table/obsm/intensities/DAPI/.zarray", + "sample1.zarr/tables/table/obsm/intensities/DAPI/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/DAPI/0", + "sample1.zarr/tables/table/obsm/intensities/_index", + "sample1.zarr/tables/table/obsm/intensities/_index/.zarray", + "sample1.zarr/tables/table/obsm/intensities/_index/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/_index/0", + "sample1.zarr/tables/table/obsm/spatial", + "sample1.zarr/tables/table/obsm/spatial/.zarray", + "sample1.zarr/tables/table/obsm/spatial/.zattrs", + "sample1.zarr/tables/table/obsm/spatial/0", + "sample1.zarr/tables/table/obsm/spatial/0/0", + "sample1.zarr/tables/table/obsp", + "sample1.zarr/tables/table/obsp/.zattrs", + "sample1.zarr/tables/table/obsp/.zgroup", + "sample1.zarr/tables/table/uns", + "sample1.zarr/tables/table/uns/.zattrs", + "sample1.zarr/tables/table/uns/.zgroup", + "sample1.zarr/tables/table/uns/sopa_attrs", + "sample1.zarr/tables/table/uns/sopa_attrs/.zattrs", + "sample1.zarr/tables/table/uns/sopa_attrs/.zgroup", + "sample1.zarr/tables/table/uns/sopa_attrs/intensities", + "sample1.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", + "sample1.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", + "sample1.zarr/tables/table/uns/sopa_attrs/intensities/0", + "sample1.zarr/tables/table/uns/sopa_attrs/transcripts", + "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", + "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", + "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/0", + "sample1.zarr/tables/table/uns/spatialdata_attrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/.zattrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/.zgroup", + "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key", + "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", + "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region/0", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/0", + "sample1.zarr/tables/table/var", + "sample1.zarr/tables/table/var/.zattrs", + "sample1.zarr/tables/table/var/.zgroup", + "sample1.zarr/tables/table/var/Name", + "sample1.zarr/tables/table/var/Name/.zarray", + "sample1.zarr/tables/table/var/Name/.zattrs", + "sample1.zarr/tables/table/var/Name/0", + "sample1.zarr/tables/table/varm", + "sample1.zarr/tables/table/varm/.zattrs", + "sample1.zarr/tables/table/varm/.zgroup", + "sample1.zarr/tables/table/varp", + "sample1.zarr/tables/table/varp/.zattrs", + "sample1.zarr/tables/table/varp/.zgroup", + "sample1.zarr/zmetadata" + ], + [ + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "1:md5,de228035c7935e884b4a1af8dc4903ac", + "2:md5,5af87bde48de5aa97ab6c5e3c779d3ed", + "3:md5,290456bdd4f13f815684d7df2bc8beb1", + "1:md5,59bf54f6f8a70534ccb107f989a359e8", + "2:md5,563f4d52c2a274ee07b1c2e903c8e053", + "3:md5,5dc4e93210483696e4b8ccd261b59ea4", + "1:md5,6c497854befbd0fbc27df2f15dd6620a", + "2:md5,5acfcfc8b05f5937b96dc5e330f00241", + "3:md5,59af25140054c5fa5659295c0810adbc", + "1:md5,604ec2d55485b819025f15d6cb25c3d1", + "2:md5,db580bfe58001e49f7a7f5e75748bc69", + "3:md5,b00f1bb37e6ebf8ef0a70cf5e8c8f023", + "1:md5,7095884e5e1e9baac3a24d15ba0c1f7b", + "1:md5,d5b194a88cfcc4939f402d1e06fb6b7d", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "1:md5,2338504a672e7656bdb5300d60f7353a", + "1:md5,12ab66f310ab8ebffc2a178a9008523e", + "1:md5,2716f328ef2e4ae7bdd2aebece4cc81a", + "1:md5,e18bcf5aa4b9aa00b724efe4b7fc9a08", + "1:md5,228aed44f36d6c96e0ae385cfdbf59d7", + "1:md5,320dae82e5e926f94c26ca0c496a94be", + "1:md5,5e1f8a06ee1b586ed10d84e51695f34d", + "1:md5,0e9f2432ab893f8fac56226edbb7243c", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "zmetadata:md5,e50f7a50b909b3dc4650609f1c05480b" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-16T09:39:58.753759" + } +} \ No newline at end of file diff --git a/tests/proseg.nf.test b/tests/proseg.nf.test new file mode 100644 index 0000000..f428bc1 --- /dev/null +++ b/tests/proseg.nf.test @@ -0,0 +1,35 @@ +nextflow_pipeline { + + name "Test pipeline" + script "../main.nf" + tag "pipeline" + + test("-profile test") { + + when { + params { + outdir = "$outputDir" + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we test pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + stable_path + ).match() } + ) + } + } +} diff --git a/tests/proseg.nf.test.snap b/tests/proseg.nf.test.snap new file mode 100644 index 0000000..dbf52bc --- /dev/null +++ b/tests/proseg.nf.test.snap @@ -0,0 +1,364 @@ +{ + "-profile test": { + "content": [ + 9, + { + "Workflow": { + "nf-core/sopa": "v1.0.0dev" + } + }, + [ + "pipeline_info", + "pipeline_info/nf_core_sopa_software_mqc_versions.yml", + "sample1.explorer", + "sample1.explorer/adata.h5ad", + "sample1.explorer/analysis.zarr.zip", + "sample1.explorer/analysis_summary.html", + "sample1.explorer/cell_feature_matrix.zarr.zip", + "sample1.explorer/cells.zarr.zip", + "sample1.explorer/experiment.xenium", + "sample1.explorer/morphology.ome.tif", + "sample1.explorer/transcripts.zarr.zip", + "sample1.zarr", + "sample1.zarr/.zattrs", + "sample1.zarr/.zgroup", + "sample1.zarr/images", + "sample1.zarr/images/.zgroup", + "sample1.zarr/images/he_image", + "sample1.zarr/images/he_image/.zattrs", + "sample1.zarr/images/he_image/.zgroup", + "sample1.zarr/images/he_image/0", + "sample1.zarr/images/he_image/0/.zarray", + "sample1.zarr/images/he_image/0/0", + "sample1.zarr/images/he_image/0/0/0", + "sample1.zarr/images/he_image/0/0/0/0", + "sample1.zarr/images/he_image/0/0/0/1", + "sample1.zarr/images/he_image/0/0/0/2", + "sample1.zarr/images/he_image/0/0/0/3", + "sample1.zarr/images/he_image/0/0/1", + "sample1.zarr/images/he_image/0/0/1/0", + "sample1.zarr/images/he_image/0/0/1/1", + "sample1.zarr/images/he_image/0/0/1/2", + "sample1.zarr/images/he_image/0/0/1/3", + "sample1.zarr/images/he_image/0/0/2", + "sample1.zarr/images/he_image/0/0/2/0", + "sample1.zarr/images/he_image/0/0/2/1", + "sample1.zarr/images/he_image/0/0/2/2", + "sample1.zarr/images/he_image/0/0/2/3", + "sample1.zarr/images/he_image/0/0/3", + "sample1.zarr/images/he_image/0/0/3/0", + "sample1.zarr/images/he_image/0/0/3/1", + "sample1.zarr/images/he_image/0/0/3/2", + "sample1.zarr/images/he_image/0/0/3/3", + "sample1.zarr/images/he_image/1", + "sample1.zarr/images/he_image/1/.zarray", + "sample1.zarr/images/he_image/1/0", + "sample1.zarr/images/he_image/1/0/0", + "sample1.zarr/images/he_image/1/0/0/0", + "sample1.zarr/images/he_image/1/0/0/1", + "sample1.zarr/images/he_image/1/0/1", + "sample1.zarr/images/he_image/1/0/1/0", + "sample1.zarr/images/he_image/1/0/1/1", + "sample1.zarr/images/he_image/2", + "sample1.zarr/images/he_image/2/.zarray", + "sample1.zarr/images/he_image/2/0", + "sample1.zarr/images/he_image/2/0/0", + "sample1.zarr/images/he_image/2/0/0/0", + "sample1.zarr/images/image", + "sample1.zarr/images/image/.zattrs", + "sample1.zarr/images/image/.zgroup", + "sample1.zarr/images/image/0", + "sample1.zarr/images/image/0/.zarray", + "sample1.zarr/images/image/0/0", + "sample1.zarr/images/image/0/0/0", + "sample1.zarr/images/image/0/0/0/0", + "sample1.zarr/images/image/0/0/0/1", + "sample1.zarr/images/image/0/0/1", + "sample1.zarr/images/image/0/0/1/0", + "sample1.zarr/images/image/0/0/1/1", + "sample1.zarr/images/image/0/1", + "sample1.zarr/images/image/0/1/0", + "sample1.zarr/images/image/0/1/0/0", + "sample1.zarr/images/image/0/1/0/1", + "sample1.zarr/images/image/0/1/1", + "sample1.zarr/images/image/0/1/1/0", + "sample1.zarr/images/image/0/1/1/1", + "sample1.zarr/images/image/0/2", + "sample1.zarr/images/image/0/2/0", + "sample1.zarr/images/image/0/2/0/0", + "sample1.zarr/images/image/0/2/0/1", + "sample1.zarr/images/image/0/2/1", + "sample1.zarr/images/image/0/2/1/0", + "sample1.zarr/images/image/0/2/1/1", + "sample1.zarr/images/image/0/3", + "sample1.zarr/images/image/0/3/0", + "sample1.zarr/images/image/0/3/0/0", + "sample1.zarr/images/image/0/3/0/1", + "sample1.zarr/images/image/0/3/1", + "sample1.zarr/images/image/0/3/1/0", + "sample1.zarr/images/image/0/3/1/1", + "sample1.zarr/points", + "sample1.zarr/points/.zgroup", + "sample1.zarr/points/misc", + "sample1.zarr/points/misc/.zattrs", + "sample1.zarr/points/misc/.zgroup", + "sample1.zarr/points/misc/points.parquet", + "sample1.zarr/points/misc/points.parquet/part.0.parquet", + "sample1.zarr/points/transcripts", + "sample1.zarr/points/transcripts/.zattrs", + "sample1.zarr/points/transcripts/.zgroup", + "sample1.zarr/points/transcripts/points.parquet", + "sample1.zarr/points/transcripts/points.parquet/part.0.parquet", + "sample1.zarr/shapes", + "sample1.zarr/shapes/.zgroup", + "sample1.zarr/shapes/baysor_boundaries", + "sample1.zarr/shapes/baysor_boundaries/.zattrs", + "sample1.zarr/shapes/baysor_boundaries/.zgroup", + "sample1.zarr/shapes/baysor_boundaries/shapes.parquet", + "sample1.zarr/shapes/cells", + "sample1.zarr/shapes/cells/.zattrs", + "sample1.zarr/shapes/cells/.zgroup", + "sample1.zarr/shapes/cells/shapes.parquet", + "sample1.zarr/shapes/transcripts_patches", + "sample1.zarr/shapes/transcripts_patches/.zattrs", + "sample1.zarr/shapes/transcripts_patches/.zgroup", + "sample1.zarr/shapes/transcripts_patches/shapes.parquet", + "sample1.zarr/tables", + "sample1.zarr/tables/.zgroup", + "sample1.zarr/tables/table", + "sample1.zarr/tables/table/.zattrs", + "sample1.zarr/tables/table/.zgroup", + "sample1.zarr/tables/table/X", + "sample1.zarr/tables/table/X/.zattrs", + "sample1.zarr/tables/table/X/.zgroup", + "sample1.zarr/tables/table/X/data", + "sample1.zarr/tables/table/X/data/.zarray", + "sample1.zarr/tables/table/X/data/0", + "sample1.zarr/tables/table/X/indices", + "sample1.zarr/tables/table/X/indices/.zarray", + "sample1.zarr/tables/table/X/indices/0", + "sample1.zarr/tables/table/X/indptr", + "sample1.zarr/tables/table/X/indptr/.zarray", + "sample1.zarr/tables/table/X/indptr/0", + "sample1.zarr/tables/table/layers", + "sample1.zarr/tables/table/layers/.zattrs", + "sample1.zarr/tables/table/layers/.zgroup", + "sample1.zarr/tables/table/obs", + "sample1.zarr/tables/table/obs/.zattrs", + "sample1.zarr/tables/table/obs/.zgroup", + "sample1.zarr/tables/table/obs/_index", + "sample1.zarr/tables/table/obs/_index/.zarray", + "sample1.zarr/tables/table/obs/_index/.zattrs", + "sample1.zarr/tables/table/obs/_index/0", + "sample1.zarr/tables/table/obs/area", + "sample1.zarr/tables/table/obs/area/.zarray", + "sample1.zarr/tables/table/obs/area/.zattrs", + "sample1.zarr/tables/table/obs/area/0", + "sample1.zarr/tables/table/obs/avg_assignment_confidence", + "sample1.zarr/tables/table/obs/avg_assignment_confidence/.zarray", + "sample1.zarr/tables/table/obs/avg_assignment_confidence/.zattrs", + "sample1.zarr/tables/table/obs/avg_assignment_confidence/0", + "sample1.zarr/tables/table/obs/avg_confidence", + "sample1.zarr/tables/table/obs/avg_confidence/.zarray", + "sample1.zarr/tables/table/obs/avg_confidence/.zattrs", + "sample1.zarr/tables/table/obs/avg_confidence/0", + "sample1.zarr/tables/table/obs/baysor_area", + "sample1.zarr/tables/table/obs/baysor_area/.zarray", + "sample1.zarr/tables/table/obs/baysor_area/.zattrs", + "sample1.zarr/tables/table/obs/baysor_area/0", + "sample1.zarr/tables/table/obs/cell_id", + "sample1.zarr/tables/table/obs/cell_id/.zarray", + "sample1.zarr/tables/table/obs/cell_id/.zattrs", + "sample1.zarr/tables/table/obs/cell_id/0", + "sample1.zarr/tables/table/obs/cluster", + "sample1.zarr/tables/table/obs/cluster/.zarray", + "sample1.zarr/tables/table/obs/cluster/.zattrs", + "sample1.zarr/tables/table/obs/cluster/0", + "sample1.zarr/tables/table/obs/density", + "sample1.zarr/tables/table/obs/density/.zarray", + "sample1.zarr/tables/table/obs/density/.zattrs", + "sample1.zarr/tables/table/obs/density/0", + "sample1.zarr/tables/table/obs/elongation", + "sample1.zarr/tables/table/obs/elongation/.zarray", + "sample1.zarr/tables/table/obs/elongation/.zattrs", + "sample1.zarr/tables/table/obs/elongation/0", + "sample1.zarr/tables/table/obs/lifespan", + "sample1.zarr/tables/table/obs/lifespan/.zarray", + "sample1.zarr/tables/table/obs/lifespan/.zattrs", + "sample1.zarr/tables/table/obs/lifespan/0", + "sample1.zarr/tables/table/obs/max_cluster_frac", + "sample1.zarr/tables/table/obs/max_cluster_frac/.zarray", + "sample1.zarr/tables/table/obs/max_cluster_frac/.zattrs", + "sample1.zarr/tables/table/obs/max_cluster_frac/0", + "sample1.zarr/tables/table/obs/n_transcripts", + "sample1.zarr/tables/table/obs/n_transcripts/.zarray", + "sample1.zarr/tables/table/obs/n_transcripts/.zattrs", + "sample1.zarr/tables/table/obs/n_transcripts/0", + "sample1.zarr/tables/table/obs/region", + "sample1.zarr/tables/table/obs/region/.zattrs", + "sample1.zarr/tables/table/obs/region/.zgroup", + "sample1.zarr/tables/table/obs/region/categories", + "sample1.zarr/tables/table/obs/region/categories/.zarray", + "sample1.zarr/tables/table/obs/region/categories/.zattrs", + "sample1.zarr/tables/table/obs/region/categories/0", + "sample1.zarr/tables/table/obs/region/codes", + "sample1.zarr/tables/table/obs/region/codes/.zarray", + "sample1.zarr/tables/table/obs/region/codes/.zattrs", + "sample1.zarr/tables/table/obs/region/codes/0", + "sample1.zarr/tables/table/obs/slide", + "sample1.zarr/tables/table/obs/slide/.zattrs", + "sample1.zarr/tables/table/obs/slide/.zgroup", + "sample1.zarr/tables/table/obs/slide/categories", + "sample1.zarr/tables/table/obs/slide/categories/.zarray", + "sample1.zarr/tables/table/obs/slide/categories/.zattrs", + "sample1.zarr/tables/table/obs/slide/categories/0", + "sample1.zarr/tables/table/obs/slide/codes", + "sample1.zarr/tables/table/obs/slide/codes/.zarray", + "sample1.zarr/tables/table/obs/slide/codes/.zattrs", + "sample1.zarr/tables/table/obs/slide/codes/0", + "sample1.zarr/tables/table/obs/x", + "sample1.zarr/tables/table/obs/x/.zarray", + "sample1.zarr/tables/table/obs/x/.zattrs", + "sample1.zarr/tables/table/obs/x/0", + "sample1.zarr/tables/table/obs/y", + "sample1.zarr/tables/table/obs/y/.zarray", + "sample1.zarr/tables/table/obs/y/.zattrs", + "sample1.zarr/tables/table/obs/y/0", + "sample1.zarr/tables/table/obsm", + "sample1.zarr/tables/table/obsm/.zattrs", + "sample1.zarr/tables/table/obsm/.zgroup", + "sample1.zarr/tables/table/obsm/intensities", + "sample1.zarr/tables/table/obsm/intensities/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/.zgroup", + "sample1.zarr/tables/table/obsm/intensities/CD20", + "sample1.zarr/tables/table/obsm/intensities/CD20/.zarray", + "sample1.zarr/tables/table/obsm/intensities/CD20/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/CD20/0", + "sample1.zarr/tables/table/obsm/intensities/CD3", + "sample1.zarr/tables/table/obsm/intensities/CD3/.zarray", + "sample1.zarr/tables/table/obsm/intensities/CD3/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/CD3/0", + "sample1.zarr/tables/table/obsm/intensities/CK", + "sample1.zarr/tables/table/obsm/intensities/CK/.zarray", + "sample1.zarr/tables/table/obsm/intensities/CK/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/CK/0", + "sample1.zarr/tables/table/obsm/intensities/DAPI", + "sample1.zarr/tables/table/obsm/intensities/DAPI/.zarray", + "sample1.zarr/tables/table/obsm/intensities/DAPI/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/DAPI/0", + "sample1.zarr/tables/table/obsm/intensities/_index", + "sample1.zarr/tables/table/obsm/intensities/_index/.zarray", + "sample1.zarr/tables/table/obsm/intensities/_index/.zattrs", + "sample1.zarr/tables/table/obsm/intensities/_index/0", + "sample1.zarr/tables/table/obsm/spatial", + "sample1.zarr/tables/table/obsm/spatial/.zarray", + "sample1.zarr/tables/table/obsm/spatial/.zattrs", + "sample1.zarr/tables/table/obsm/spatial/0", + "sample1.zarr/tables/table/obsm/spatial/0/0", + "sample1.zarr/tables/table/obsp", + "sample1.zarr/tables/table/obsp/.zattrs", + "sample1.zarr/tables/table/obsp/.zgroup", + "sample1.zarr/tables/table/uns", + "sample1.zarr/tables/table/uns/.zattrs", + "sample1.zarr/tables/table/uns/.zgroup", + "sample1.zarr/tables/table/uns/sopa_attrs", + "sample1.zarr/tables/table/uns/sopa_attrs/.zattrs", + "sample1.zarr/tables/table/uns/sopa_attrs/.zgroup", + "sample1.zarr/tables/table/uns/sopa_attrs/intensities", + "sample1.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", + "sample1.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", + "sample1.zarr/tables/table/uns/sopa_attrs/intensities/0", + "sample1.zarr/tables/table/uns/sopa_attrs/transcripts", + "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", + "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", + "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/0", + "sample1.zarr/tables/table/uns/spatialdata_attrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/.zattrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/.zgroup", + "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key", + "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", + "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region/0", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", + "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/0", + "sample1.zarr/tables/table/var", + "sample1.zarr/tables/table/var/.zattrs", + "sample1.zarr/tables/table/var/.zgroup", + "sample1.zarr/tables/table/var/Name", + "sample1.zarr/tables/table/var/Name/.zarray", + "sample1.zarr/tables/table/var/Name/.zattrs", + "sample1.zarr/tables/table/var/Name/0", + "sample1.zarr/tables/table/varm", + "sample1.zarr/tables/table/varm/.zattrs", + "sample1.zarr/tables/table/varm/.zgroup", + "sample1.zarr/tables/table/varp", + "sample1.zarr/tables/table/varp/.zattrs", + "sample1.zarr/tables/table/varp/.zgroup", + "sample1.zarr/zmetadata" + ], + [ + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "1:md5,de228035c7935e884b4a1af8dc4903ac", + "2:md5,5af87bde48de5aa97ab6c5e3c779d3ed", + "3:md5,290456bdd4f13f815684d7df2bc8beb1", + "1:md5,59bf54f6f8a70534ccb107f989a359e8", + "2:md5,563f4d52c2a274ee07b1c2e903c8e053", + "3:md5,5dc4e93210483696e4b8ccd261b59ea4", + "1:md5,6c497854befbd0fbc27df2f15dd6620a", + "2:md5,5acfcfc8b05f5937b96dc5e330f00241", + "3:md5,59af25140054c5fa5659295c0810adbc", + "1:md5,604ec2d55485b819025f15d6cb25c3d1", + "2:md5,db580bfe58001e49f7a7f5e75748bc69", + "3:md5,b00f1bb37e6ebf8ef0a70cf5e8c8f023", + "1:md5,7095884e5e1e9baac3a24d15ba0c1f7b", + "1:md5,d5b194a88cfcc4939f402d1e06fb6b7d", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "1:md5,2338504a672e7656bdb5300d60f7353a", + "1:md5,12ab66f310ab8ebffc2a178a9008523e", + "1:md5,2716f328ef2e4ae7bdd2aebece4cc81a", + "1:md5,e18bcf5aa4b9aa00b724efe4b7fc9a08", + "1:md5,228aed44f36d6c96e0ae385cfdbf59d7", + "1:md5,320dae82e5e926f94c26ca0c496a94be", + "1:md5,5e1f8a06ee1b586ed10d84e51695f34d", + "1:md5,0e9f2432ab893f8fac56226edbb7243c", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "zmetadata:md5,e50f7a50b909b3dc4650609f1c05480b" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-16T09:41:58.468979" + } +} \ No newline at end of file From cfecff2438c13c5c24e2c93bc7d1268444a29bc4 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 16 Jul 2025 09:51:51 +0200 Subject: [PATCH 119/227] try sopa latest --- subworkflows/local/baysor/main.nf | 8 ++++---- subworkflows/local/cellpose/main.nf | 8 ++++---- subworkflows/local/proseg/main.nf | 4 ++-- subworkflows/local/stardist/main.nf | 8 ++++---- tests/cellpose.nf.test | 2 +- tests/proseg.nf.test | 2 +- workflows/sopa.nf | 32 ++++++++++++++--------------- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index b719925..aa9bd97 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -27,8 +27,8 @@ process patchSegmentationBaysor { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7-baysor' - : 'docker.io/quentinblampey/sopa:2.0.7-baysor'}" + ? 'docker://quentinblampey/sopa:latest-baysor' + : 'docker.io/quentinblampey/sopa:latest-baysor'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -51,8 +51,8 @@ process resolveBaysor { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7-baysor' - : 'docker.io/quentinblampey/sopa:2.0.7-baysor'}" + ? 'docker://quentinblampey/sopa:latest-baysor' + : 'docker.io/quentinblampey/sopa:latest-baysor'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/cellpose/main.nf b/subworkflows/local/cellpose/main.nf index f7c38d4..64f5f0c 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/subworkflows/local/cellpose/main.nf @@ -27,8 +27,8 @@ process patchSegmentationCellpose { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7-cellpose' - : 'docker.io/quentinblampey/sopa:2.0.7-cellpose'}" + ? 'docker://quentinblampey/sopa:latest-cellpose' + : 'docker.io/quentinblampey/sopa:latest-cellpose'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -47,8 +47,8 @@ process resolveCellpose { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7' - : 'docker.io/quentinblampey/sopa:2.0.7'}" + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/proseg/main.nf b/subworkflows/local/proseg/main.nf index 035582b..c57118a 100644 --- a/subworkflows/local/proseg/main.nf +++ b/subworkflows/local/proseg/main.nf @@ -20,8 +20,8 @@ process patchSegmentationProseg { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7-proseg' - : 'docker.io/quentinblampey/sopa:2.0.7-proseg'}" + ? 'docker://quentinblampey/sopa:latest-proseg' + : 'docker.io/quentinblampey/sopa:latest-proseg'}" input: tuple val(meta), path(sdata_path) diff --git a/subworkflows/local/stardist/main.nf b/subworkflows/local/stardist/main.nf index c67f481..05036be 100644 --- a/subworkflows/local/stardist/main.nf +++ b/subworkflows/local/stardist/main.nf @@ -27,8 +27,8 @@ process patchSegmentationStardist { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7-stardist' - : 'docker.io/quentinblampey/sopa:2.0.7-stardist'}" + ? 'docker://quentinblampey/sopa:latest-stardist' + : 'docker.io/quentinblampey/sopa:latest-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) @@ -47,8 +47,8 @@ process resolveStardist { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7' - : 'docker.io/quentinblampey/sopa:2.0.7'}" + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" input: tuple val(meta), path(sdata_path) diff --git a/tests/cellpose.nf.test b/tests/cellpose.nf.test index f428bc1..cca280a 100644 --- a/tests/cellpose.nf.test +++ b/tests/cellpose.nf.test @@ -4,7 +4,7 @@ nextflow_pipeline { script "../main.nf" tag "pipeline" - test("-profile test") { + test("-profile test_cellpose") { when { params { diff --git a/tests/proseg.nf.test b/tests/proseg.nf.test index f428bc1..f56753e 100644 --- a/tests/proseg.nf.test +++ b/tests/proseg.nf.test @@ -4,7 +4,7 @@ nextflow_pipeline { script "../main.nf" tag "pipeline" - test("-profile test") { + test("-profile test_proseg") { when { params { diff --git a/workflows/sopa.nf b/workflows/sopa.nf index a070c1f..d6b7548 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -103,8 +103,8 @@ process toSpatialData { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7' - : 'docker.io/quentinblampey/sopa:2.0.7'}" + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" input: tuple val(meta), path(input_files) @@ -124,8 +124,8 @@ process tissueSegmentation { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7' - : 'docker.io/quentinblampey/sopa:2.0.7'}" + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" input: tuple val(meta), path(sdata_path) @@ -146,8 +146,8 @@ process makeImagePatches { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7' - : 'docker.io/quentinblampey/sopa:2.0.7'}" + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" input: tuple val(meta), path(sdata_path) @@ -168,8 +168,8 @@ process makeTranscriptPatches { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7' - : 'docker.io/quentinblampey/sopa:2.0.7'}" + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" input: tuple val(meta), path(sdata_path) @@ -189,8 +189,8 @@ process aggregate { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7' - : 'docker.io/quentinblampey/sopa:2.0.7'}" + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" input: tuple val(meta), path(sdata_path) @@ -211,8 +211,8 @@ process explorer_raw { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7' - : 'docker.io/quentinblampey/sopa:2.0.7'}" + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -235,8 +235,8 @@ process explorer { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7' - : 'docker.io/quentinblampey/sopa:2.0.7'}" + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -262,8 +262,8 @@ process report { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.0.7' - : 'docker.io/quentinblampey/sopa:2.0.7'}" + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" publishDir "${params.outdir}", mode: params.publish_dir_mode From 3dda9a65cc124ddef0373795dbd8cc1aa1ba8575 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 16 Jul 2025 09:55:59 +0200 Subject: [PATCH 120/227] update ro crate and run tests --- ro-crate-metadata.json | 2 +- tests/cellpose.nf.test.snap | 4 ++-- tests/proseg.nf.test.snap | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 4228306..b535b07 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "InProgress", "datePublished": "2025-07-09T19:52:43+00:00", - "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n

    \n \"sopa_overview\"\n

    \n\n\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `--configfile` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n --configfile \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n

    \n \"sopa_overview\"\n

    \n\n0. (Visium HD only) Raw data processing with Space Ranger\n1. (Optional) Tissue segmentation\n2. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n3. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n4. (Optional) Cell-type annotation **_- coming soon_**\n5. User-friendly output creation for visualization and quick analysis\n6. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://gustaveroussy.github.io/sopa/).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `--configfile` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n --configfile \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index aa88e26..15f3982 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -1,5 +1,5 @@ { - "-profile test": { + "-profile test_cellpose": { "content": [ 9, { @@ -359,6 +359,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-16T09:39:58.753759" + "timestamp": "2025-07-16T09:53:40.451961" } } \ No newline at end of file diff --git a/tests/proseg.nf.test.snap b/tests/proseg.nf.test.snap index dbf52bc..51ec386 100644 --- a/tests/proseg.nf.test.snap +++ b/tests/proseg.nf.test.snap @@ -1,5 +1,5 @@ { - "-profile test": { + "-profile test_proseg": { "content": [ 9, { @@ -359,6 +359,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-16T09:41:58.468979" + "timestamp": "2025-07-16T09:55:36.595068" } } \ No newline at end of file From ce73246337336810a217395d14548c825ecd7127 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 16 Jul 2025 10:58:30 +0200 Subject: [PATCH 121/227] update snapshots --- tests/.nftignore | 3 +++ tests/cellpose.nf.test.snap | 32 ++------------------------------ tests/default.nf.test.snap | 32 ++------------------------------ tests/proseg.nf.test.snap | 32 ++------------------------------ 4 files changed, 9 insertions(+), 90 deletions(-) diff --git a/tests/.nftignore b/tests/.nftignore index b42f4c6..f7afaf5 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -10,3 +10,6 @@ pipeline_info/*.{html,json,txt,yml} **/.zattrs **/.zarray **/0 +**/1 +**/2 +**/3 diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 15f3982..68ab19f 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -99,11 +99,6 @@ "sample1.zarr/images/image/0/3/1/1", "sample1.zarr/points", "sample1.zarr/points/.zgroup", - "sample1.zarr/points/misc", - "sample1.zarr/points/misc/.zattrs", - "sample1.zarr/points/misc/.zgroup", - "sample1.zarr/points/misc/points.parquet", - "sample1.zarr/points/misc/points.parquet/part.0.parquet", "sample1.zarr/points/transcripts", "sample1.zarr/points/transcripts/.zattrs", "sample1.zarr/points/transcripts/.zgroup", @@ -306,29 +301,7 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "1:md5,de228035c7935e884b4a1af8dc4903ac", - "2:md5,5af87bde48de5aa97ab6c5e3c779d3ed", - "3:md5,290456bdd4f13f815684d7df2bc8beb1", - "1:md5,59bf54f6f8a70534ccb107f989a359e8", - "2:md5,563f4d52c2a274ee07b1c2e903c8e053", - "3:md5,5dc4e93210483696e4b8ccd261b59ea4", - "1:md5,6c497854befbd0fbc27df2f15dd6620a", - "2:md5,5acfcfc8b05f5937b96dc5e330f00241", - "3:md5,59af25140054c5fa5659295c0810adbc", - "1:md5,604ec2d55485b819025f15d6cb25c3d1", - "2:md5,db580bfe58001e49f7a7f5e75748bc69", - "3:md5,b00f1bb37e6ebf8ef0a70cf5e8c8f023", - "1:md5,7095884e5e1e9baac3a24d15ba0c1f7b", - "1:md5,d5b194a88cfcc4939f402d1e06fb6b7d", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "1:md5,2338504a672e7656bdb5300d60f7353a", - "1:md5,12ab66f310ab8ebffc2a178a9008523e", - "1:md5,2716f328ef2e4ae7bdd2aebece4cc81a", - "1:md5,e18bcf5aa4b9aa00b724efe4b7fc9a08", - "1:md5,228aed44f36d6c96e0ae385cfdbf59d7", - "1:md5,320dae82e5e926f94c26ca0c496a94be", - "1:md5,5e1f8a06ee1b586ed10d84e51695f34d", - "1:md5,0e9f2432ab893f8fac56226edbb7243c", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", @@ -351,14 +324,13 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "zmetadata:md5,e50f7a50b909b3dc4650609f1c05480b" + "zmetadata:md5,9d5c0fa793978ffc16fb325d7531da7f" ] ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-16T09:53:40.451961" + "timestamp": "2025-07-16T10:30:21.097962" } } \ No newline at end of file diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index f719fce..c8488ed 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -99,11 +99,6 @@ "sample1.zarr/images/image/0/3/1/1", "sample1.zarr/points", "sample1.zarr/points/.zgroup", - "sample1.zarr/points/misc", - "sample1.zarr/points/misc/.zattrs", - "sample1.zarr/points/misc/.zgroup", - "sample1.zarr/points/misc/points.parquet", - "sample1.zarr/points/misc/points.parquet/part.0.parquet", "sample1.zarr/points/transcripts", "sample1.zarr/points/transcripts/.zattrs", "sample1.zarr/points/transcripts/.zgroup", @@ -306,29 +301,7 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "1:md5,de228035c7935e884b4a1af8dc4903ac", - "2:md5,5af87bde48de5aa97ab6c5e3c779d3ed", - "3:md5,290456bdd4f13f815684d7df2bc8beb1", - "1:md5,59bf54f6f8a70534ccb107f989a359e8", - "2:md5,563f4d52c2a274ee07b1c2e903c8e053", - "3:md5,5dc4e93210483696e4b8ccd261b59ea4", - "1:md5,6c497854befbd0fbc27df2f15dd6620a", - "2:md5,5acfcfc8b05f5937b96dc5e330f00241", - "3:md5,59af25140054c5fa5659295c0810adbc", - "1:md5,604ec2d55485b819025f15d6cb25c3d1", - "2:md5,db580bfe58001e49f7a7f5e75748bc69", - "3:md5,b00f1bb37e6ebf8ef0a70cf5e8c8f023", - "1:md5,7095884e5e1e9baac3a24d15ba0c1f7b", - "1:md5,d5b194a88cfcc4939f402d1e06fb6b7d", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "1:md5,2338504a672e7656bdb5300d60f7353a", - "1:md5,12ab66f310ab8ebffc2a178a9008523e", - "1:md5,2716f328ef2e4ae7bdd2aebece4cc81a", - "1:md5,e18bcf5aa4b9aa00b724efe4b7fc9a08", - "1:md5,228aed44f36d6c96e0ae385cfdbf59d7", - "1:md5,320dae82e5e926f94c26ca0c496a94be", - "1:md5,5e1f8a06ee1b586ed10d84e51695f34d", - "1:md5,0e9f2432ab893f8fac56226edbb7243c", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", @@ -351,14 +324,13 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "zmetadata:md5,e50f7a50b909b3dc4650609f1c05480b" + "zmetadata:md5,9d5c0fa793978ffc16fb325d7531da7f" ] ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-11T14:12:44.947434" + "timestamp": "2025-07-16T10:31:56.790814" } } \ No newline at end of file diff --git a/tests/proseg.nf.test.snap b/tests/proseg.nf.test.snap index 51ec386..a785b94 100644 --- a/tests/proseg.nf.test.snap +++ b/tests/proseg.nf.test.snap @@ -99,11 +99,6 @@ "sample1.zarr/images/image/0/3/1/1", "sample1.zarr/points", "sample1.zarr/points/.zgroup", - "sample1.zarr/points/misc", - "sample1.zarr/points/misc/.zattrs", - "sample1.zarr/points/misc/.zgroup", - "sample1.zarr/points/misc/points.parquet", - "sample1.zarr/points/misc/points.parquet/part.0.parquet", "sample1.zarr/points/transcripts", "sample1.zarr/points/transcripts/.zattrs", "sample1.zarr/points/transcripts/.zgroup", @@ -306,29 +301,7 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "1:md5,de228035c7935e884b4a1af8dc4903ac", - "2:md5,5af87bde48de5aa97ab6c5e3c779d3ed", - "3:md5,290456bdd4f13f815684d7df2bc8beb1", - "1:md5,59bf54f6f8a70534ccb107f989a359e8", - "2:md5,563f4d52c2a274ee07b1c2e903c8e053", - "3:md5,5dc4e93210483696e4b8ccd261b59ea4", - "1:md5,6c497854befbd0fbc27df2f15dd6620a", - "2:md5,5acfcfc8b05f5937b96dc5e330f00241", - "3:md5,59af25140054c5fa5659295c0810adbc", - "1:md5,604ec2d55485b819025f15d6cb25c3d1", - "2:md5,db580bfe58001e49f7a7f5e75748bc69", - "3:md5,b00f1bb37e6ebf8ef0a70cf5e8c8f023", - "1:md5,7095884e5e1e9baac3a24d15ba0c1f7b", - "1:md5,d5b194a88cfcc4939f402d1e06fb6b7d", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "1:md5,2338504a672e7656bdb5300d60f7353a", - "1:md5,12ab66f310ab8ebffc2a178a9008523e", - "1:md5,2716f328ef2e4ae7bdd2aebece4cc81a", - "1:md5,e18bcf5aa4b9aa00b724efe4b7fc9a08", - "1:md5,228aed44f36d6c96e0ae385cfdbf59d7", - "1:md5,320dae82e5e926f94c26ca0c496a94be", - "1:md5,5e1f8a06ee1b586ed10d84e51695f34d", - "1:md5,0e9f2432ab893f8fac56226edbb7243c", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", @@ -351,14 +324,13 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "zmetadata:md5,e50f7a50b909b3dc4650609f1c05480b" + "zmetadata:md5,9d5c0fa793978ffc16fb325d7531da7f" ] ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-16T09:55:36.595068" + "timestamp": "2025-07-16T10:33:01.720179" } } \ No newline at end of file From 456c21f54638dca9d05feac63bd60106bf451306 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 16 Jul 2025 13:18:18 +0200 Subject: [PATCH 122/227] cleanup sopa cache only if possible --- subworkflows/local/baysor/main.nf | 2 +- workflows/sopa.nf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/subworkflows/local/baysor/main.nf b/subworkflows/local/baysor/main.nf index aa9bd97..d5ee847 100644 --- a/subworkflows/local/baysor/main.nf +++ b/subworkflows/local/baysor/main.nf @@ -66,7 +66,7 @@ process resolveBaysor { """ sopa resolve baysor ${sdata_path} ${cli_arguments} - rm -r ${sdata_path}/.sopa_cache/transcript_patches # cleanup large baysor files + rm -r ${sdata_path}/.sopa_cache/transcript_patches || true # cleanup large baysor files """ } diff --git a/workflows/sopa.nf b/workflows/sopa.nf index d6b7548..678fb2b 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -296,7 +296,7 @@ process publish { script: """ - rm -r ${sdata_path}/.sopa_cache + rm -r ${sdata_path}/.sopa_cache || true echo "Publishing ${sdata_path}" """ From 526fd797ad3a2c5e37edb2623add2b6e4a55667c Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 22 Jul 2025 09:17:15 +0200 Subject: [PATCH 123/227] minor cleanup --- workflows/sopa.nf | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 678fb2b..825956e 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -284,9 +284,7 @@ process report { process publish { label "process_single" - publishDir "${params.outdir}", mode: params.publish_dir_mode, saveAs: { fname -> - fname.contains('sopa_cache') ? null : fname - } + publishDir "${params.outdir}", mode: params.publish_dir_mode input: path sdata_path From f29699738f770721859a35b8dd88091a1bd03983 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 22 Jul 2025 09:46:28 +0200 Subject: [PATCH 124/227] bump version 1.0.0 --- .nf-core.yml | 7 ++++--- nextflow.config | 6 +----- ro-crate-metadata.json | 44 ++++++++++++++++++++++++++++++++---------- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/.nf-core.yml b/.nf-core.yml index 776ee35..681e585 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -9,8 +9,9 @@ lint: files_unchanged: - .github/CONTRIBUTING.md - assets/sendmail_template.txt - - .github/CONTRIBUTING.md - - assets/sendmail_template.txt + - assets/nf-core-sopa_logo_light.png + - docs/images/nf-core-sopa_logo_light.png + - docs/images/nf-core-sopa_logo_dark.png multiqc_config: false nf_core_version: 3.3.2 repository_type: pipeline @@ -27,4 +28,4 @@ template: - igenomes - multiqc - fastqc - version: 1.0.0dev + version: 1.0.0 diff --git a/nextflow.config b/nextflow.config index 2882902..adbe300 100644 --- a/nextflow.config +++ b/nextflow.config @@ -170,10 +170,6 @@ profiles { includeConfig params.custom_config_base && (!System.getenv('NXF_OFFLINE') || !params.custom_config_base.startsWith('http')) ? "${params.custom_config_base}/nfcore_custom.config" : "/dev/null" -// Load nf-core/sopa custom profiles from different institutions. -// TODO nf-core: Optionally, you can add a pipeline-specific nf-core config at https://github.com/nf-core/configs -// includeConfig params.custom_config_base && (!System.getenv('NXF_OFFLINE') || !params.custom_config_base.startsWith('http')) ? "${params.custom_config_base}/pipeline/sopa.config" : "/dev/null" - // Set default registry for Apptainer, Docker, Podman, Charliecloud and Singularity independent of -profile // Will not be used unless Apptainer / Docker / Podman / Charliecloud / Singularity are enabled // Set to your registry if you have a mirror of containers @@ -242,7 +238,7 @@ manifest { mainScript = 'main.nf' defaultBranch = 'master' nextflowVersion = '!>=24.10.5' - version = '1.0.0dev' + version = '1.0.0' doi = '' } diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index b535b07..9e941a1 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -21,8 +21,8 @@ { "@id": "./", "@type": "Dataset", - "creativeWorkStatus": "InProgress", - "datePublished": "2025-07-09T19:52:43+00:00", + "creativeWorkStatus": "Stable", + "datePublished": "2025-07-22T07:34:52+00:00", "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n

    \n \"sopa_overview\"\n

    \n\n0. (Visium HD only) Raw data processing with Space Ranger\n1. (Optional) Tissue segmentation\n2. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n3. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n4. (Optional) Cell-type annotation **_- coming soon_**\n5. User-friendly output creation for visualization and quick analysis\n6. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://gustaveroussy.github.io/sopa/).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `--configfile` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n --configfile \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { @@ -40,6 +40,15 @@ { "@id": "docs/images/" }, + { + "@id": "modules/" + }, + { + "@id": "modules/local/" + }, + { + "@id": "modules/nf-core/" + }, { "@id": "workflows/" }, @@ -93,7 +102,7 @@ }, "mentions": [ { - "@id": "#ae2f664d-8a9b-4c49-a216-83593a47e161" + "@id": "#338ae6ee-eff7-46fc-840c-c41c9598f01d" } ], "name": "nf-core/sopa" @@ -126,7 +135,7 @@ } ], "dateCreated": "", - "dateModified": "2025-07-09T19:52:43Z", + "dateModified": "2025-07-22T09:34:52Z", "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", "keywords": [ "nf-core", @@ -156,10 +165,10 @@ }, "url": [ "https://github.com/nf-core/sopa", - "https://nf-co.re/sopa/dev/" + "https://nf-co.re/sopa/1.0.0/" ], "version": [ - "1.0.0dev" + "1.0.0" ] }, { @@ -175,11 +184,11 @@ "version": "!>=24.10.5" }, { - "@id": "#ae2f664d-8a9b-4c49-a216-83593a47e161", + "@id": "#338ae6ee-eff7-46fc-840c-c41c9598f01d", "@type": "TestSuite", "instance": [ { - "@id": "#cdc1d9e3-b100-458b-a806-69bf822c2ecd" + "@id": "#3368e15c-d6bb-4a54-bebb-755f4cb3edb4" } ], "mainEntity": { @@ -188,7 +197,7 @@ "name": "Test suite for nf-core/sopa" }, { - "@id": "#cdc1d9e3-b100-458b-a806-69bf822c2ecd", + "@id": "#3368e15c-d6bb-4a54-bebb-755f4cb3edb4", "@type": "TestInstance", "name": "GitHub Actions workflow for testing nf-core/sopa", "resource": "repos/nf-core/sopa/actions/workflows/nf-test.yml", @@ -225,6 +234,21 @@ "@type": "Dataset", "description": "Images for the documentation files" }, + { + "@id": "modules/", + "@type": "Dataset", + "description": "Modules used by the pipeline" + }, + { + "@id": "modules/local/", + "@type": "Dataset", + "description": "Pipeline-specific modules" + }, + { + "@id": "modules/nf-core/", + "@type": "Dataset", + "description": "nf-core modules" + }, { "@id": "workflows/", "@type": "Dataset", @@ -309,7 +333,7 @@ { "@id": "https://orcid.org/0000-0002-3836-2889", "@type": "Person", - "email": "quentin.blampey@gmail.com", + "email": "33903498+quentinblampey@users.noreply.github.com", "name": "Quentin Blampey" } ] From 3972c4c14c0be43ba4c7676a83a5d37322ea8fb6 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 22 Jul 2025 10:01:03 +0200 Subject: [PATCH 125/227] minor update to trigger PR --- nextflow_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nextflow_schema.json b/nextflow_schema.json index c3fd33e..a041553 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -29,7 +29,7 @@ "exists": true, "pattern": "^\\S+\\.yaml$", "description": "Path to a Sopa config file describing the technology used and the pipeline parameters.", - "help_text": "Choose one existing config file amont public one: https://github.com/gustaveroussy/sopa/tree/master/workflow/config", + "help_text": "Choose one existing config file amont public one: https://github.com/gustaveroussy/sopa/tree/main/workflow/config", "fa_icon": "fas fa-file" }, "outdir": { From 05ea1f60fa506ce84dcef43e51f8ff2263e70f23 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 22 Jul 2025 10:06:44 +0200 Subject: [PATCH 126/227] changelog update for v1.0.0 --- CHANGELOG.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5d9125..e44e8cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,14 +3,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## v1.0.0dev - [date] +## v1.0.0 - [2025-07-22] Initial release of nf-core/sopa, created with the [nf-core](https://nf-co.re/) template. ### `Added` -### `Fixed` - -### `Dependencies` - -### `Deprecated` +Sopa can be run with all the technologies currently supported - including Visium HD. From 9edadd2722a61559548ad590f87b4fade8ef3dd7 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 22 Jul 2025 10:32:15 +0200 Subject: [PATCH 127/227] ensure the data_path exists --- tests/README.md | 3 ++- tests/samplesheet.csv | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/README.md b/tests/README.md index 38c9473..8c07078 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,6 +1,7 @@ # Tests -The `samplesheet.csv` is technology-agnostic, and uses synthetic data generated when running the pipeline. +> [!NOTE] +> The `samplesheet.csv` is technology-agnostic, and uses synthetic data generated when running the pipeline. The samplesheet uses a fake data path to make sure the path exists, but then it generates the dataset on-the-fly. ## Visium HD specific case diff --git a/tests/samplesheet.csv b/tests/samplesheet.csv index 73f269f..d45a3ad 100644 --- a/tests/samplesheet.csv +++ b/tests/samplesheet.csv @@ -1,2 +1,2 @@ data_path -../../../tests/sample1 +https://github.com/nf-core/sopa/blob/dev/tests/README.md From 0d82d572b3ef9b40b9542637230c41f195f2b39d Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 22 Jul 2025 15:04:29 +0200 Subject: [PATCH 128/227] move subworkflows to modules --- conf/base.config | 2 +- conf/modules.config | 2 +- .../local/baysor/main.nf | 35 +-- .../local/cellpose/main.nf | 25 +- .../local/proseg/main.nf | 16 +- modules/local/sopa_core/main.nf | 184 ++++++++++++ .../local/stardist/main.nf | 25 +- subworkflows/local/baysor/environment.yml | 8 - subworkflows/local/cellpose/environment.yml | 8 - subworkflows/local/proseg/environment.yml | 8 - subworkflows/local/stardist/environment.yml | 8 - workflows/sopa.nf | 272 ++++++------------ 12 files changed, 288 insertions(+), 305 deletions(-) rename {subworkflows => modules}/local/baysor/main.nf (55%) rename {subworkflows => modules}/local/cellpose/main.nf (60%) rename {subworkflows => modules}/local/proseg/main.nf (67%) create mode 100644 modules/local/sopa_core/main.nf rename {subworkflows => modules}/local/stardist/main.nf (60%) delete mode 100644 subworkflows/local/baysor/environment.yml delete mode 100644 subworkflows/local/cellpose/environment.yml delete mode 100644 subworkflows/local/proseg/environment.yml delete mode 100644 subworkflows/local/stardist/environment.yml diff --git a/conf/base.config b/conf/base.config index cf6c183..93a3ee6 100644 --- a/conf/base.config +++ b/conf/base.config @@ -43,7 +43,7 @@ process { withLabel:process_high_memory { memory = { 200.GB * task.attempt } } - withName:patchSegmentationProseg { + withName:PATCH_SEGMENTATION_PROSEG { cpus = { 8 * task.attempt } memory = { 200.GB * task.attempt } time = { 10.d * task.attempt } diff --git a/conf/modules.config b/conf/modules.config index b8f18f9..8a3188e 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -20,7 +20,7 @@ process { ] } - withName: patchSegmentationCellpose { + withName: PATCH_SEGMENTATION_CELLPOSE { containerOptions = '' } } diff --git a/subworkflows/local/baysor/main.nf b/modules/local/baysor/main.nf similarity index 55% rename from subworkflows/local/baysor/main.nf rename to modules/local/baysor/main.nf index d5ee847..fb74dfb 100644 --- a/subworkflows/local/baysor/main.nf +++ b/modules/local/baysor/main.nf @@ -1,28 +1,4 @@ -include { ArgsCLI } from '../../../modules/local/utils' - -workflow BAYSOR { - take: - ch_patches - config - - main: - baysor_args = ArgsCLI(config.segmentation.baysor, null, ["config"]) - - ch_patches - .map { meta, sdata_path, patches_file_transcripts -> [meta, sdata_path, patches_file_transcripts.splitText()] } - .flatMap { meta, sdata_path, patches_indices -> patches_indices.collect { index -> [meta, sdata_path, baysor_args, index.trim().toInteger(), patches_indices.size] } } - .set { ch_baysor } - - ch_segmented = patchSegmentationBaysor(ch_baysor).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - - (ch_resolved, _out) = resolveBaysor(ch_segmented, resolveArgs(config)) - - emit: - ch_resolved -} - - -process patchSegmentationBaysor { +process PATCH_SEGMENTATION_BAYSOR { label "process_long" conda "${moduleDir}/environment.yml" @@ -46,7 +22,7 @@ process patchSegmentationBaysor { """ } -process resolveBaysor { +process RESOLVE_BAYSOR { label "process_low" conda "${moduleDir}/environment.yml" @@ -69,10 +45,3 @@ process resolveBaysor { rm -r ${sdata_path}/.sopa_cache/transcript_patches || true # cleanup large baysor files """ } - -def resolveArgs(Map config) { - def gene_column = config.segmentation.baysor.config.data.gene - def min_area = config.segmentation.baysor.min_area ?: 0 - - return "--gene-column ${gene_column} --min-area ${min_area}" -} diff --git a/subworkflows/local/cellpose/main.nf b/modules/local/cellpose/main.nf similarity index 60% rename from subworkflows/local/cellpose/main.nf rename to modules/local/cellpose/main.nf index 64f5f0c..1519c4b 100644 --- a/subworkflows/local/cellpose/main.nf +++ b/modules/local/cellpose/main.nf @@ -1,28 +1,7 @@ include { ArgsCLI } from '../../../modules/local/utils' -workflow CELLPOSE { - take: - ch_patches - config - main: - cellpose_args = ArgsCLI(config.segmentation.cellpose) - - ch_patches - .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } - .flatMap { meta, sdata_path, n_patches -> (0.. [meta, sdata_path, cellpose_args, index, n_patches] } } - .set { ch_cellpose } - - ch_segmented = patchSegmentationCellpose(ch_cellpose).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - - (ch_resolved, _out) = resolveCellpose(ch_segmented) - - emit: - ch_resolved -} - - -process patchSegmentationCellpose { +process PATCH_SEGMENTATION_CELLPOSE { label "process_single" conda "${moduleDir}/environment.yml" @@ -42,7 +21,7 @@ process patchSegmentationCellpose { """ } -process resolveCellpose { +process RESOLVE_CELLPOSE { label "process_low" conda "${moduleDir}/environment.yml" diff --git a/subworkflows/local/proseg/main.nf b/modules/local/proseg/main.nf similarity index 67% rename from subworkflows/local/proseg/main.nf rename to modules/local/proseg/main.nf index c57118a..c8729d6 100644 --- a/subworkflows/local/proseg/main.nf +++ b/modules/local/proseg/main.nf @@ -1,21 +1,7 @@ include { ArgsCLI } from '../../../modules/local/utils' -workflow PROSEG { - take: - ch_patches - config - main: - proseg_args = ArgsCLI(config.segmentation.proseg, null, ["command_line_suffix"]) - - (ch_segmented, _out) = patchSegmentationProseg(ch_patches, proseg_args) - - emit: - ch_segmented -} - - -process patchSegmentationProseg { +process PATCH_SEGMENTATION_PROSEG { label "process_high" conda "${moduleDir}/environment.yml" diff --git a/modules/local/sopa_core/main.nf b/modules/local/sopa_core/main.nf new file mode 100644 index 0000000..224e792 --- /dev/null +++ b/modules/local/sopa_core/main.nf @@ -0,0 +1,184 @@ +include { ArgsReaderCLI } from '../utils' + +process TO_SPATIALDATA { + label "process_high" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(input_files) + val args + + output: + tuple val(meta), path("${meta.sdata_dir}") + + script: + """ + sopa convert ${meta.data_dir} --sdata-path ${meta.sdata_dir} ${ArgsReaderCLI(args, meta)} + """ +} + +process TISSUE_SEGMENTATION { + label "process_low" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/shapes/region_of_interest" + + script: + """ + sopa segmentation tissue ${sdata_path} ${cli_arguments} + """ +} + +process MAKE_IMAGE_PATCHES { + label "process_single" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/patches_file_image") + path "${sdata_path}/shapes/image_patches" + + script: + """ + sopa patchify image ${sdata_path} ${cli_arguments} + """ +} + +process MAKE_TRANSCRIPT_PATCHES { + label "process_medium" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/patches_file_transcripts") + + script: + """ + sopa patchify transcripts ${sdata_path} ${cli_arguments} + """ +} + +process AGGREGATE { + label "process_medium" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/tables/table" + + script: + """ + sopa aggregate ${sdata_path} ${cli_arguments} + """ +} + +process EXPLORER_RAW { + label "process_high" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + publishDir "${params.outdir}", mode: params.publish_dir_mode + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + path "${meta.explorer_dir}/morphology*" + path "${meta.explorer_dir}/transcripts*", optional: true + + script: + """ + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "+it" --no-save-h5ad + """ +} + +process EXPLORER { + label "process_high" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + publishDir "${params.outdir}", mode: params.publish_dir_mode + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + path "${meta.explorer_dir}/experiment.xenium" + path "${meta.explorer_dir}/analysis.zarr.zip" + path "${meta.explorer_dir}/cell_feature_matrix.zarr.zip" + path "${meta.explorer_dir}/adata.h5ad" + path "${meta.explorer_dir}/cells.zarr.zip" + + script: + """ + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "-it" + """ +} + +process REPORT { + label "process_medium" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + publishDir "${params.outdir}", mode: params.publish_dir_mode + + input: + tuple val(meta), path(sdata_path) + + output: + path "${meta.explorer_dir}/analysis_summary.html" + + script: + """ + mkdir -p ${meta.explorer_dir} + + sopa report ${sdata_path} ${meta.explorer_dir}/analysis_summary.html + """ +} diff --git a/subworkflows/local/stardist/main.nf b/modules/local/stardist/main.nf similarity index 60% rename from subworkflows/local/stardist/main.nf rename to modules/local/stardist/main.nf index 05036be..0823017 100644 --- a/subworkflows/local/stardist/main.nf +++ b/modules/local/stardist/main.nf @@ -1,28 +1,7 @@ include { ArgsCLI } from '../../../modules/local/utils' -workflow STARDIST { - take: - ch_patches - config - main: - stardist_args = ArgsCLI(config.segmentation.stardist) - - ch_patches - .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } - .flatMap { meta, sdata_path, n_patches -> (0.. [meta, sdata_path, stardist_args, index, n_patches] } } - .set { ch_stardist } - - ch_segmented = patchSegmentationStardist(ch_stardist).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - - (ch_resolved, _out) = resolveStardist(ch_segmented) - - emit: - ch_resolved -} - - -process patchSegmentationStardist { +process PATCH_SEGMENTATION_STARDIST { label "process_single" conda "${moduleDir}/environment.yml" @@ -42,7 +21,7 @@ process patchSegmentationStardist { """ } -process resolveStardist { +process RESOLVE_STARDIST { label "process_low" conda "${moduleDir}/environment.yml" diff --git a/subworkflows/local/baysor/environment.yml b/subworkflows/local/baysor/environment.yml deleted file mode 100644 index 6808f3c..0000000 --- a/subworkflows/local/baysor/environment.yml +++ /dev/null @@ -1,8 +0,0 @@ -channels: - - conda-forge - - bioconda -dependencies: - - python=3.10 - - pip=24.3.1 - - pip: - - sopa[baysor]>=2.0.2 diff --git a/subworkflows/local/cellpose/environment.yml b/subworkflows/local/cellpose/environment.yml deleted file mode 100644 index 8c8a60d..0000000 --- a/subworkflows/local/cellpose/environment.yml +++ /dev/null @@ -1,8 +0,0 @@ -channels: - - conda-forge - - bioconda -dependencies: - - python=3.10 - - pip=24.3.1 - - pip: - - sopa[cellpose]>=2.0.2 diff --git a/subworkflows/local/proseg/environment.yml b/subworkflows/local/proseg/environment.yml deleted file mode 100644 index 1fd551b..0000000 --- a/subworkflows/local/proseg/environment.yml +++ /dev/null @@ -1,8 +0,0 @@ -channels: - - conda-forge - - bioconda -dependencies: - - python=3.10 - - pip=24.3.1 - - pip: - - sopa>=2.0.3 diff --git a/subworkflows/local/stardist/environment.yml b/subworkflows/local/stardist/environment.yml deleted file mode 100644 index 389491b..0000000 --- a/subworkflows/local/stardist/environment.yml +++ /dev/null @@ -1,8 +0,0 @@ -channels: - - conda-forge - - bioconda -dependencies: - - python=3.10 - - pip=24.3.1 - - pip: - - sopa[stardist]>=2.0.2 diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 825956e..e2ba93a 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -6,10 +6,20 @@ include { paramsSummaryMap } from 'plugin/nf-schema' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_sopa_pipeline' -include { CELLPOSE } from '../subworkflows/local/cellpose' -include { STARDIST } from '../subworkflows/local/stardist' -include { BAYSOR } from '../subworkflows/local/baysor' -include { PROSEG } from '../subworkflows/local/proseg' +include { PATCH_SEGMENTATION_BAYSOR ; RESOLVE_BAYSOR } from '../modules/local/baysor' +include { PATCH_SEGMENTATION_CELLPOSE ; RESOLVE_CELLPOSE } from '../modules/local/cellpose' +include { PATCH_SEGMENTATION_STARDIST ; RESOLVE_STARDIST } from '../modules/local/stardist' +include { PATCH_SEGMENTATION_PROSEG } from '../modules/local/proseg' +include { + TO_SPATIALDATA ; + TISSUE_SEGMENTATION ; + MAKE_IMAGE_PATCHES ; + MAKE_TRANSCRIPT_PATCHES ; + AGGREGATE ; + EXPLORER ; + EXPLORER_RAW ; + REPORT +} from '../modules/local/sopa_core' include { readConfigFile } from '../modules/local/utils' include { ArgsCLI } from '../modules/local/utils' include { ArgsReaderCLI } from '../modules/local/utils' @@ -41,47 +51,47 @@ workflow SOPA { ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.data_dir] } } - ch_spatialdata = toSpatialData(ch_input_spatialdata, config.read) + ch_spatialdata = TO_SPATIALDATA(ch_input_spatialdata, config.read) - explorer_raw(ch_spatialdata, ArgsCLI(config.explorer)) + EXPLORER_RAW(ch_spatialdata, ArgsCLI(config.explorer)) if (config.segmentation.tissue) { - (ch_tissue_seg, _out) = tissueSegmentation(ch_spatialdata, ArgsCLI(config.segmentation.tissue)) + (ch_tissue_seg, _out) = TISSUE_SEGMENTATION(ch_spatialdata, ArgsCLI(config.segmentation.tissue)) } else { ch_tissue_seg = ch_spatialdata } if (config.segmentation.cellpose) { - (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) + (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) ch_resolved = CELLPOSE(ch_image_patches, config) } if (config.segmentation.stardist) { - (ch_image_patches, _out) = makeImagePatches(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) + (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) ch_resolved = STARDIST(ch_image_patches, config) } if (config.segmentation.baysor) { ch_input_baysor = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg - ch_transcripts_patches = makeTranscriptPatches(ch_input_baysor, transcriptPatchesArgs(config, "baysor")) + ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_baysor, transcriptPatchesArgs(config, "baysor")) ch_resolved = BAYSOR(ch_transcripts_patches, config) } if (config.segmentation.proseg) { ch_input_proseg = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg - ch_proseg_patches = makeTranscriptPatches(ch_input_proseg, transcriptPatchesArgs(config, "proseg")) + ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, transcriptPatchesArgs(config, "proseg")) ch_resolved = PROSEG(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, config) } - (ch_aggregated, _out) = aggregate(ch_resolved, ArgsCLI(config.aggregate)) + (ch_aggregated, _out) = AGGREGATE(ch_resolved, ArgsCLI(config.aggregate)) - explorer(ch_aggregated, ArgsCLI(config.explorer)) - report(ch_aggregated) + EXPLORER(ch_aggregated, ArgsCLI(config.explorer)) + REPORT(ch_aggregated) - publish(ch_aggregated.map { it[1] }) + PUBLISH(ch_aggregated.map { it[1] }) // @@ -98,206 +108,107 @@ workflow SOPA { versions = ch_versions // channel: [ path(versions.yml) ] } -process toSpatialData { - label "process_high" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - input: - tuple val(meta), path(input_files) - val args - - output: - tuple val(meta), path("${meta.sdata_dir}") - - script: - """ - sopa convert ${meta.data_dir} --sdata-path ${meta.sdata_dir} ${ArgsReaderCLI(args, meta)} - """ -} - -process tissueSegmentation { - label "process_low" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - input: - tuple val(meta), path(sdata_path) - val cli_arguments - - output: - tuple val(meta), path(sdata_path) - path "${sdata_path}/shapes/region_of_interest" - - script: - """ - sopa segmentation tissue ${sdata_path} ${cli_arguments} - """ -} - -process makeImagePatches { +process PUBLISH { label "process_single" - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + publishDir "${params.outdir}", mode: params.publish_dir_mode input: - tuple val(meta), path(sdata_path) - val cli_arguments + path sdata_path output: - tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/patches_file_image") - path "${sdata_path}/shapes/image_patches" + path sdata_path script: """ - sopa patchify image ${sdata_path} ${cli_arguments} - """ -} - -process makeTranscriptPatches { - label "process_medium" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - input: - tuple val(meta), path(sdata_path) - val cli_arguments - - output: - tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/patches_file_transcripts") + rm -r ${sdata_path}/.sopa_cache || true - script: - """ - sopa patchify transcripts ${sdata_path} ${cli_arguments} + echo "Publishing ${sdata_path}" """ } -process aggregate { - label "process_medium" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - input: - tuple val(meta), path(sdata_path) - val cli_arguments - - output: - tuple val(meta), path(sdata_path) - path "${sdata_path}/tables/table" - - script: - """ - sopa aggregate ${sdata_path} ${cli_arguments} - """ -} +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + SEGMENTATION WORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ -process explorer_raw { - label "process_high" +workflow CELLPOSE { + take: + ch_patches + config - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + main: + cellpose_args = ArgsCLI(config.segmentation.cellpose) - publishDir "${params.outdir}", mode: params.publish_dir_mode + ch_patches + .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } + .flatMap { meta, sdata_path, n_patches -> (0.. [meta, sdata_path, cellpose_args, index, n_patches] } } + .set { ch_cellpose } - input: - tuple val(meta), path(sdata_path) - val cli_arguments + ch_segmented = PATCH_SEGMENTATION_CELLPOSE(ch_cellpose).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - output: - path "${meta.explorer_dir}/morphology*" - path "${meta.explorer_dir}/transcripts*", optional: true + (ch_resolved, _out) = RESOLVE_CELLPOSE(ch_segmented) - script: - """ - sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "+it" --no-save-h5ad - """ + emit: + ch_resolved } -process explorer { - label "process_high" +workflow STARDIST { + take: + ch_patches + config - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + main: + stardist_args = ArgsCLI(config.segmentation.stardist) - publishDir "${params.outdir}", mode: params.publish_dir_mode + ch_patches + .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } + .flatMap { meta, sdata_path, n_patches -> (0.. [meta, sdata_path, stardist_args, index, n_patches] } } + .set { ch_stardist } - input: - tuple val(meta), path(sdata_path) - val cli_arguments + ch_segmented = PATCH_SEGMENTATION_STARDIST(ch_stardist).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - output: - path "${meta.explorer_dir}/experiment.xenium" - path "${meta.explorer_dir}/analysis.zarr.zip" - path "${meta.explorer_dir}/cell_feature_matrix.zarr.zip" - path "${meta.explorer_dir}/adata.h5ad" - path "${meta.explorer_dir}/cells.zarr.zip" + (ch_resolved, _out) = RESOLVE_STARDIST(ch_segmented) - script: - """ - sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "-it" - """ + emit: + ch_resolved } -process report { - label "process_medium" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - publishDir "${params.outdir}", mode: params.publish_dir_mode - - input: - tuple val(meta), path(sdata_path) +workflow PROSEG { + take: + ch_patches + config - output: - path "${meta.explorer_dir}/analysis_summary.html" + main: + proseg_args = ArgsCLI(config.segmentation.proseg, null, ["command_line_suffix"]) - script: - """ - mkdir -p ${meta.explorer_dir} + (ch_segmented, _out) = PATCH_SEGMENTATION_PROSEG(ch_patches, proseg_args) - sopa report ${sdata_path} ${meta.explorer_dir}/analysis_summary.html - """ + emit: + ch_segmented } -process publish { - label "process_single" - publishDir "${params.outdir}", mode: params.publish_dir_mode +workflow BAYSOR { + take: + ch_patches + config - input: - path sdata_path + main: + baysor_args = ArgsCLI(config.segmentation.baysor, null, ["config"]) - output: - path sdata_path + ch_patches + .map { meta, sdata_path, patches_file_transcripts -> [meta, sdata_path, patches_file_transcripts.splitText()] } + .flatMap { meta, sdata_path, patches_indices -> patches_indices.collect { index -> [meta, sdata_path, baysor_args, index.trim().toInteger(), patches_indices.size] } } + .set { ch_baysor } - script: - """ - rm -r ${sdata_path}/.sopa_cache || true + ch_segmented = PATCH_SEGMENTATION_BAYSOR(ch_baysor).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - echo "Publishing ${sdata_path}" - """ + (ch_resolved, _out) = RESOLVE_BAYSOR(ch_segmented, resolveArgs(config)) + + emit: + ch_resolved } def transcriptPatchesArgs(Map config, String method) { @@ -305,3 +216,10 @@ def transcriptPatchesArgs(Map config, String method) { return ArgsCLI(config.patchify, "micron") + " " + prior_args } + +def resolveArgs(Map config) { + def gene_column = config.segmentation.baysor.config.data.gene + def min_area = config.segmentation.baysor.min_area ?: 0 + + return "--gene-column ${gene_column} --min-area ${min_area}" +} From 331846eae4a1a03685a13f3299197705636d5f19 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 22 Jul 2025 15:13:47 +0200 Subject: [PATCH 129/227] fix sample name in tests snapshots --- tests/cellpose.nf.test.snap | 574 ++++++++++++++++++------------------ tests/default.nf.test.snap | 574 ++++++++++++++++++------------------ tests/proseg.nf.test.snap | 574 ++++++++++++++++++------------------ tests/samplesheet.csv | 4 +- 4 files changed, 863 insertions(+), 863 deletions(-) diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 68ab19f..2cf727b 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -4,298 +4,298 @@ 9, { "Workflow": { - "nf-core/sopa": "v1.0.0dev" + "nf-core/sopa": "v1.0.0" } }, [ "pipeline_info", "pipeline_info/nf_core_sopa_software_mqc_versions.yml", - "sample1.explorer", - "sample1.explorer/adata.h5ad", - "sample1.explorer/analysis.zarr.zip", - "sample1.explorer/analysis_summary.html", - "sample1.explorer/cell_feature_matrix.zarr.zip", - "sample1.explorer/cells.zarr.zip", - "sample1.explorer/experiment.xenium", - "sample1.explorer/morphology.ome.tif", - "sample1.explorer/transcripts.zarr.zip", - "sample1.zarr", - "sample1.zarr/.zattrs", - "sample1.zarr/.zgroup", - "sample1.zarr/images", - "sample1.zarr/images/.zgroup", - "sample1.zarr/images/he_image", - "sample1.zarr/images/he_image/.zattrs", - "sample1.zarr/images/he_image/.zgroup", - "sample1.zarr/images/he_image/0", - "sample1.zarr/images/he_image/0/.zarray", - "sample1.zarr/images/he_image/0/0", - "sample1.zarr/images/he_image/0/0/0", - "sample1.zarr/images/he_image/0/0/0/0", - "sample1.zarr/images/he_image/0/0/0/1", - "sample1.zarr/images/he_image/0/0/0/2", - "sample1.zarr/images/he_image/0/0/0/3", - "sample1.zarr/images/he_image/0/0/1", - "sample1.zarr/images/he_image/0/0/1/0", - "sample1.zarr/images/he_image/0/0/1/1", - "sample1.zarr/images/he_image/0/0/1/2", - "sample1.zarr/images/he_image/0/0/1/3", - "sample1.zarr/images/he_image/0/0/2", - "sample1.zarr/images/he_image/0/0/2/0", - "sample1.zarr/images/he_image/0/0/2/1", - "sample1.zarr/images/he_image/0/0/2/2", - "sample1.zarr/images/he_image/0/0/2/3", - "sample1.zarr/images/he_image/0/0/3", - "sample1.zarr/images/he_image/0/0/3/0", - "sample1.zarr/images/he_image/0/0/3/1", - "sample1.zarr/images/he_image/0/0/3/2", - "sample1.zarr/images/he_image/0/0/3/3", - "sample1.zarr/images/he_image/1", - "sample1.zarr/images/he_image/1/.zarray", - "sample1.zarr/images/he_image/1/0", - "sample1.zarr/images/he_image/1/0/0", - "sample1.zarr/images/he_image/1/0/0/0", - "sample1.zarr/images/he_image/1/0/0/1", - "sample1.zarr/images/he_image/1/0/1", - "sample1.zarr/images/he_image/1/0/1/0", - "sample1.zarr/images/he_image/1/0/1/1", - "sample1.zarr/images/he_image/2", - "sample1.zarr/images/he_image/2/.zarray", - "sample1.zarr/images/he_image/2/0", - "sample1.zarr/images/he_image/2/0/0", - "sample1.zarr/images/he_image/2/0/0/0", - "sample1.zarr/images/image", - "sample1.zarr/images/image/.zattrs", - "sample1.zarr/images/image/.zgroup", - "sample1.zarr/images/image/0", - "sample1.zarr/images/image/0/.zarray", - "sample1.zarr/images/image/0/0", - "sample1.zarr/images/image/0/0/0", - "sample1.zarr/images/image/0/0/0/0", - "sample1.zarr/images/image/0/0/0/1", - "sample1.zarr/images/image/0/0/1", - "sample1.zarr/images/image/0/0/1/0", - "sample1.zarr/images/image/0/0/1/1", - "sample1.zarr/images/image/0/1", - "sample1.zarr/images/image/0/1/0", - "sample1.zarr/images/image/0/1/0/0", - "sample1.zarr/images/image/0/1/0/1", - "sample1.zarr/images/image/0/1/1", - "sample1.zarr/images/image/0/1/1/0", - "sample1.zarr/images/image/0/1/1/1", - "sample1.zarr/images/image/0/2", - "sample1.zarr/images/image/0/2/0", - "sample1.zarr/images/image/0/2/0/0", - "sample1.zarr/images/image/0/2/0/1", - "sample1.zarr/images/image/0/2/1", - "sample1.zarr/images/image/0/2/1/0", - "sample1.zarr/images/image/0/2/1/1", - "sample1.zarr/images/image/0/3", - "sample1.zarr/images/image/0/3/0", - "sample1.zarr/images/image/0/3/0/0", - "sample1.zarr/images/image/0/3/0/1", - "sample1.zarr/images/image/0/3/1", - "sample1.zarr/images/image/0/3/1/0", - "sample1.zarr/images/image/0/3/1/1", - "sample1.zarr/points", - "sample1.zarr/points/.zgroup", - "sample1.zarr/points/transcripts", - "sample1.zarr/points/transcripts/.zattrs", - "sample1.zarr/points/transcripts/.zgroup", - "sample1.zarr/points/transcripts/points.parquet", - "sample1.zarr/points/transcripts/points.parquet/part.0.parquet", - "sample1.zarr/shapes", - "sample1.zarr/shapes/.zgroup", - "sample1.zarr/shapes/baysor_boundaries", - "sample1.zarr/shapes/baysor_boundaries/.zattrs", - "sample1.zarr/shapes/baysor_boundaries/.zgroup", - "sample1.zarr/shapes/baysor_boundaries/shapes.parquet", - "sample1.zarr/shapes/cells", - "sample1.zarr/shapes/cells/.zattrs", - "sample1.zarr/shapes/cells/.zgroup", - "sample1.zarr/shapes/cells/shapes.parquet", - "sample1.zarr/shapes/transcripts_patches", - "sample1.zarr/shapes/transcripts_patches/.zattrs", - "sample1.zarr/shapes/transcripts_patches/.zgroup", - "sample1.zarr/shapes/transcripts_patches/shapes.parquet", - "sample1.zarr/tables", - "sample1.zarr/tables/.zgroup", - "sample1.zarr/tables/table", - "sample1.zarr/tables/table/.zattrs", - "sample1.zarr/tables/table/.zgroup", - "sample1.zarr/tables/table/X", - "sample1.zarr/tables/table/X/.zattrs", - "sample1.zarr/tables/table/X/.zgroup", - "sample1.zarr/tables/table/X/data", - "sample1.zarr/tables/table/X/data/.zarray", - "sample1.zarr/tables/table/X/data/0", - "sample1.zarr/tables/table/X/indices", - "sample1.zarr/tables/table/X/indices/.zarray", - "sample1.zarr/tables/table/X/indices/0", - "sample1.zarr/tables/table/X/indptr", - "sample1.zarr/tables/table/X/indptr/.zarray", - "sample1.zarr/tables/table/X/indptr/0", - "sample1.zarr/tables/table/layers", - "sample1.zarr/tables/table/layers/.zattrs", - "sample1.zarr/tables/table/layers/.zgroup", - "sample1.zarr/tables/table/obs", - "sample1.zarr/tables/table/obs/.zattrs", - "sample1.zarr/tables/table/obs/.zgroup", - "sample1.zarr/tables/table/obs/_index", - "sample1.zarr/tables/table/obs/_index/.zarray", - "sample1.zarr/tables/table/obs/_index/.zattrs", - "sample1.zarr/tables/table/obs/_index/0", - "sample1.zarr/tables/table/obs/area", - "sample1.zarr/tables/table/obs/area/.zarray", - "sample1.zarr/tables/table/obs/area/.zattrs", - "sample1.zarr/tables/table/obs/area/0", - "sample1.zarr/tables/table/obs/avg_assignment_confidence", - "sample1.zarr/tables/table/obs/avg_assignment_confidence/.zarray", - "sample1.zarr/tables/table/obs/avg_assignment_confidence/.zattrs", - "sample1.zarr/tables/table/obs/avg_assignment_confidence/0", - "sample1.zarr/tables/table/obs/avg_confidence", - "sample1.zarr/tables/table/obs/avg_confidence/.zarray", - "sample1.zarr/tables/table/obs/avg_confidence/.zattrs", - "sample1.zarr/tables/table/obs/avg_confidence/0", - "sample1.zarr/tables/table/obs/baysor_area", - "sample1.zarr/tables/table/obs/baysor_area/.zarray", - "sample1.zarr/tables/table/obs/baysor_area/.zattrs", - "sample1.zarr/tables/table/obs/baysor_area/0", - "sample1.zarr/tables/table/obs/cell_id", - "sample1.zarr/tables/table/obs/cell_id/.zarray", - "sample1.zarr/tables/table/obs/cell_id/.zattrs", - "sample1.zarr/tables/table/obs/cell_id/0", - "sample1.zarr/tables/table/obs/cluster", - "sample1.zarr/tables/table/obs/cluster/.zarray", - "sample1.zarr/tables/table/obs/cluster/.zattrs", - "sample1.zarr/tables/table/obs/cluster/0", - "sample1.zarr/tables/table/obs/density", - "sample1.zarr/tables/table/obs/density/.zarray", - "sample1.zarr/tables/table/obs/density/.zattrs", - "sample1.zarr/tables/table/obs/density/0", - "sample1.zarr/tables/table/obs/elongation", - "sample1.zarr/tables/table/obs/elongation/.zarray", - "sample1.zarr/tables/table/obs/elongation/.zattrs", - "sample1.zarr/tables/table/obs/elongation/0", - "sample1.zarr/tables/table/obs/lifespan", - "sample1.zarr/tables/table/obs/lifespan/.zarray", - "sample1.zarr/tables/table/obs/lifespan/.zattrs", - "sample1.zarr/tables/table/obs/lifespan/0", - "sample1.zarr/tables/table/obs/max_cluster_frac", - "sample1.zarr/tables/table/obs/max_cluster_frac/.zarray", - "sample1.zarr/tables/table/obs/max_cluster_frac/.zattrs", - "sample1.zarr/tables/table/obs/max_cluster_frac/0", - "sample1.zarr/tables/table/obs/n_transcripts", - "sample1.zarr/tables/table/obs/n_transcripts/.zarray", - "sample1.zarr/tables/table/obs/n_transcripts/.zattrs", - "sample1.zarr/tables/table/obs/n_transcripts/0", - "sample1.zarr/tables/table/obs/region", - "sample1.zarr/tables/table/obs/region/.zattrs", - "sample1.zarr/tables/table/obs/region/.zgroup", - "sample1.zarr/tables/table/obs/region/categories", - "sample1.zarr/tables/table/obs/region/categories/.zarray", - "sample1.zarr/tables/table/obs/region/categories/.zattrs", - "sample1.zarr/tables/table/obs/region/categories/0", - "sample1.zarr/tables/table/obs/region/codes", - "sample1.zarr/tables/table/obs/region/codes/.zarray", - "sample1.zarr/tables/table/obs/region/codes/.zattrs", - "sample1.zarr/tables/table/obs/region/codes/0", - "sample1.zarr/tables/table/obs/slide", - "sample1.zarr/tables/table/obs/slide/.zattrs", - "sample1.zarr/tables/table/obs/slide/.zgroup", - "sample1.zarr/tables/table/obs/slide/categories", - "sample1.zarr/tables/table/obs/slide/categories/.zarray", - "sample1.zarr/tables/table/obs/slide/categories/.zattrs", - "sample1.zarr/tables/table/obs/slide/categories/0", - "sample1.zarr/tables/table/obs/slide/codes", - "sample1.zarr/tables/table/obs/slide/codes/.zarray", - "sample1.zarr/tables/table/obs/slide/codes/.zattrs", - "sample1.zarr/tables/table/obs/slide/codes/0", - "sample1.zarr/tables/table/obs/x", - "sample1.zarr/tables/table/obs/x/.zarray", - "sample1.zarr/tables/table/obs/x/.zattrs", - "sample1.zarr/tables/table/obs/x/0", - "sample1.zarr/tables/table/obs/y", - "sample1.zarr/tables/table/obs/y/.zarray", - "sample1.zarr/tables/table/obs/y/.zattrs", - "sample1.zarr/tables/table/obs/y/0", - "sample1.zarr/tables/table/obsm", - "sample1.zarr/tables/table/obsm/.zattrs", - "sample1.zarr/tables/table/obsm/.zgroup", - "sample1.zarr/tables/table/obsm/intensities", - "sample1.zarr/tables/table/obsm/intensities/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/.zgroup", - "sample1.zarr/tables/table/obsm/intensities/CD20", - "sample1.zarr/tables/table/obsm/intensities/CD20/.zarray", - "sample1.zarr/tables/table/obsm/intensities/CD20/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/CD20/0", - "sample1.zarr/tables/table/obsm/intensities/CD3", - "sample1.zarr/tables/table/obsm/intensities/CD3/.zarray", - "sample1.zarr/tables/table/obsm/intensities/CD3/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/CD3/0", - "sample1.zarr/tables/table/obsm/intensities/CK", - "sample1.zarr/tables/table/obsm/intensities/CK/.zarray", - "sample1.zarr/tables/table/obsm/intensities/CK/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/CK/0", - "sample1.zarr/tables/table/obsm/intensities/DAPI", - "sample1.zarr/tables/table/obsm/intensities/DAPI/.zarray", - "sample1.zarr/tables/table/obsm/intensities/DAPI/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/DAPI/0", - "sample1.zarr/tables/table/obsm/intensities/_index", - "sample1.zarr/tables/table/obsm/intensities/_index/.zarray", - "sample1.zarr/tables/table/obsm/intensities/_index/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/_index/0", - "sample1.zarr/tables/table/obsm/spatial", - "sample1.zarr/tables/table/obsm/spatial/.zarray", - "sample1.zarr/tables/table/obsm/spatial/.zattrs", - "sample1.zarr/tables/table/obsm/spatial/0", - "sample1.zarr/tables/table/obsm/spatial/0/0", - "sample1.zarr/tables/table/obsp", - "sample1.zarr/tables/table/obsp/.zattrs", - "sample1.zarr/tables/table/obsp/.zgroup", - "sample1.zarr/tables/table/uns", - "sample1.zarr/tables/table/uns/.zattrs", - "sample1.zarr/tables/table/uns/.zgroup", - "sample1.zarr/tables/table/uns/sopa_attrs", - "sample1.zarr/tables/table/uns/sopa_attrs/.zattrs", - "sample1.zarr/tables/table/uns/sopa_attrs/.zgroup", - "sample1.zarr/tables/table/uns/sopa_attrs/intensities", - "sample1.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", - "sample1.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", - "sample1.zarr/tables/table/uns/sopa_attrs/intensities/0", - "sample1.zarr/tables/table/uns/sopa_attrs/transcripts", - "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", - "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", - "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/0", - "sample1.zarr/tables/table/uns/spatialdata_attrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/.zattrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/.zgroup", - "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key", - "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", - "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region/0", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/0", - "sample1.zarr/tables/table/var", - "sample1.zarr/tables/table/var/.zattrs", - "sample1.zarr/tables/table/var/.zgroup", - "sample1.zarr/tables/table/var/Name", - "sample1.zarr/tables/table/var/Name/.zarray", - "sample1.zarr/tables/table/var/Name/.zattrs", - "sample1.zarr/tables/table/var/Name/0", - "sample1.zarr/tables/table/varm", - "sample1.zarr/tables/table/varm/.zattrs", - "sample1.zarr/tables/table/varm/.zgroup", - "sample1.zarr/tables/table/varp", - "sample1.zarr/tables/table/varp/.zattrs", - "sample1.zarr/tables/table/varp/.zgroup", - "sample1.zarr/zmetadata" + "sample_name.explorer", + "sample_name.explorer/adata.h5ad", + "sample_name.explorer/analysis.zarr.zip", + "sample_name.explorer/analysis_summary.html", + "sample_name.explorer/cell_feature_matrix.zarr.zip", + "sample_name.explorer/cells.zarr.zip", + "sample_name.explorer/experiment.xenium", + "sample_name.explorer/morphology.ome.tif", + "sample_name.explorer/transcripts.zarr.zip", + "sample_name.zarr", + "sample_name.zarr/.zattrs", + "sample_name.zarr/.zgroup", + "sample_name.zarr/images", + "sample_name.zarr/images/.zgroup", + "sample_name.zarr/images/he_image", + "sample_name.zarr/images/he_image/.zattrs", + "sample_name.zarr/images/he_image/.zgroup", + "sample_name.zarr/images/he_image/0", + "sample_name.zarr/images/he_image/0/.zarray", + "sample_name.zarr/images/he_image/0/0", + "sample_name.zarr/images/he_image/0/0/0", + "sample_name.zarr/images/he_image/0/0/0/0", + "sample_name.zarr/images/he_image/0/0/0/1", + "sample_name.zarr/images/he_image/0/0/0/2", + "sample_name.zarr/images/he_image/0/0/0/3", + "sample_name.zarr/images/he_image/0/0/1", + "sample_name.zarr/images/he_image/0/0/1/0", + "sample_name.zarr/images/he_image/0/0/1/1", + "sample_name.zarr/images/he_image/0/0/1/2", + "sample_name.zarr/images/he_image/0/0/1/3", + "sample_name.zarr/images/he_image/0/0/2", + "sample_name.zarr/images/he_image/0/0/2/0", + "sample_name.zarr/images/he_image/0/0/2/1", + "sample_name.zarr/images/he_image/0/0/2/2", + "sample_name.zarr/images/he_image/0/0/2/3", + "sample_name.zarr/images/he_image/0/0/3", + "sample_name.zarr/images/he_image/0/0/3/0", + "sample_name.zarr/images/he_image/0/0/3/1", + "sample_name.zarr/images/he_image/0/0/3/2", + "sample_name.zarr/images/he_image/0/0/3/3", + "sample_name.zarr/images/he_image/1", + "sample_name.zarr/images/he_image/1/.zarray", + "sample_name.zarr/images/he_image/1/0", + "sample_name.zarr/images/he_image/1/0/0", + "sample_name.zarr/images/he_image/1/0/0/0", + "sample_name.zarr/images/he_image/1/0/0/1", + "sample_name.zarr/images/he_image/1/0/1", + "sample_name.zarr/images/he_image/1/0/1/0", + "sample_name.zarr/images/he_image/1/0/1/1", + "sample_name.zarr/images/he_image/2", + "sample_name.zarr/images/he_image/2/.zarray", + "sample_name.zarr/images/he_image/2/0", + "sample_name.zarr/images/he_image/2/0/0", + "sample_name.zarr/images/he_image/2/0/0/0", + "sample_name.zarr/images/image", + "sample_name.zarr/images/image/.zattrs", + "sample_name.zarr/images/image/.zgroup", + "sample_name.zarr/images/image/0", + "sample_name.zarr/images/image/0/.zarray", + "sample_name.zarr/images/image/0/0", + "sample_name.zarr/images/image/0/0/0", + "sample_name.zarr/images/image/0/0/0/0", + "sample_name.zarr/images/image/0/0/0/1", + "sample_name.zarr/images/image/0/0/1", + "sample_name.zarr/images/image/0/0/1/0", + "sample_name.zarr/images/image/0/0/1/1", + "sample_name.zarr/images/image/0/1", + "sample_name.zarr/images/image/0/1/0", + "sample_name.zarr/images/image/0/1/0/0", + "sample_name.zarr/images/image/0/1/0/1", + "sample_name.zarr/images/image/0/1/1", + "sample_name.zarr/images/image/0/1/1/0", + "sample_name.zarr/images/image/0/1/1/1", + "sample_name.zarr/images/image/0/2", + "sample_name.zarr/images/image/0/2/0", + "sample_name.zarr/images/image/0/2/0/0", + "sample_name.zarr/images/image/0/2/0/1", + "sample_name.zarr/images/image/0/2/1", + "sample_name.zarr/images/image/0/2/1/0", + "sample_name.zarr/images/image/0/2/1/1", + "sample_name.zarr/images/image/0/3", + "sample_name.zarr/images/image/0/3/0", + "sample_name.zarr/images/image/0/3/0/0", + "sample_name.zarr/images/image/0/3/0/1", + "sample_name.zarr/images/image/0/3/1", + "sample_name.zarr/images/image/0/3/1/0", + "sample_name.zarr/images/image/0/3/1/1", + "sample_name.zarr/points", + "sample_name.zarr/points/.zgroup", + "sample_name.zarr/points/transcripts", + "sample_name.zarr/points/transcripts/.zattrs", + "sample_name.zarr/points/transcripts/.zgroup", + "sample_name.zarr/points/transcripts/points.parquet", + "sample_name.zarr/points/transcripts/points.parquet/part.0.parquet", + "sample_name.zarr/shapes", + "sample_name.zarr/shapes/.zgroup", + "sample_name.zarr/shapes/baysor_boundaries", + "sample_name.zarr/shapes/baysor_boundaries/.zattrs", + "sample_name.zarr/shapes/baysor_boundaries/.zgroup", + "sample_name.zarr/shapes/baysor_boundaries/shapes.parquet", + "sample_name.zarr/shapes/cells", + "sample_name.zarr/shapes/cells/.zattrs", + "sample_name.zarr/shapes/cells/.zgroup", + "sample_name.zarr/shapes/cells/shapes.parquet", + "sample_name.zarr/shapes/transcripts_patches", + "sample_name.zarr/shapes/transcripts_patches/.zattrs", + "sample_name.zarr/shapes/transcripts_patches/.zgroup", + "sample_name.zarr/shapes/transcripts_patches/shapes.parquet", + "sample_name.zarr/tables", + "sample_name.zarr/tables/.zgroup", + "sample_name.zarr/tables/table", + "sample_name.zarr/tables/table/.zattrs", + "sample_name.zarr/tables/table/.zgroup", + "sample_name.zarr/tables/table/X", + "sample_name.zarr/tables/table/X/.zattrs", + "sample_name.zarr/tables/table/X/.zgroup", + "sample_name.zarr/tables/table/X/data", + "sample_name.zarr/tables/table/X/data/.zarray", + "sample_name.zarr/tables/table/X/data/0", + "sample_name.zarr/tables/table/X/indices", + "sample_name.zarr/tables/table/X/indices/.zarray", + "sample_name.zarr/tables/table/X/indices/0", + "sample_name.zarr/tables/table/X/indptr", + "sample_name.zarr/tables/table/X/indptr/.zarray", + "sample_name.zarr/tables/table/X/indptr/0", + "sample_name.zarr/tables/table/layers", + "sample_name.zarr/tables/table/layers/.zattrs", + "sample_name.zarr/tables/table/layers/.zgroup", + "sample_name.zarr/tables/table/obs", + "sample_name.zarr/tables/table/obs/.zattrs", + "sample_name.zarr/tables/table/obs/.zgroup", + "sample_name.zarr/tables/table/obs/_index", + "sample_name.zarr/tables/table/obs/_index/.zarray", + "sample_name.zarr/tables/table/obs/_index/.zattrs", + "sample_name.zarr/tables/table/obs/_index/0", + "sample_name.zarr/tables/table/obs/area", + "sample_name.zarr/tables/table/obs/area/.zarray", + "sample_name.zarr/tables/table/obs/area/.zattrs", + "sample_name.zarr/tables/table/obs/area/0", + "sample_name.zarr/tables/table/obs/avg_assignment_confidence", + "sample_name.zarr/tables/table/obs/avg_assignment_confidence/.zarray", + "sample_name.zarr/tables/table/obs/avg_assignment_confidence/.zattrs", + "sample_name.zarr/tables/table/obs/avg_assignment_confidence/0", + "sample_name.zarr/tables/table/obs/avg_confidence", + "sample_name.zarr/tables/table/obs/avg_confidence/.zarray", + "sample_name.zarr/tables/table/obs/avg_confidence/.zattrs", + "sample_name.zarr/tables/table/obs/avg_confidence/0", + "sample_name.zarr/tables/table/obs/baysor_area", + "sample_name.zarr/tables/table/obs/baysor_area/.zarray", + "sample_name.zarr/tables/table/obs/baysor_area/.zattrs", + "sample_name.zarr/tables/table/obs/baysor_area/0", + "sample_name.zarr/tables/table/obs/cell_id", + "sample_name.zarr/tables/table/obs/cell_id/.zarray", + "sample_name.zarr/tables/table/obs/cell_id/.zattrs", + "sample_name.zarr/tables/table/obs/cell_id/0", + "sample_name.zarr/tables/table/obs/cluster", + "sample_name.zarr/tables/table/obs/cluster/.zarray", + "sample_name.zarr/tables/table/obs/cluster/.zattrs", + "sample_name.zarr/tables/table/obs/cluster/0", + "sample_name.zarr/tables/table/obs/density", + "sample_name.zarr/tables/table/obs/density/.zarray", + "sample_name.zarr/tables/table/obs/density/.zattrs", + "sample_name.zarr/tables/table/obs/density/0", + "sample_name.zarr/tables/table/obs/elongation", + "sample_name.zarr/tables/table/obs/elongation/.zarray", + "sample_name.zarr/tables/table/obs/elongation/.zattrs", + "sample_name.zarr/tables/table/obs/elongation/0", + "sample_name.zarr/tables/table/obs/lifespan", + "sample_name.zarr/tables/table/obs/lifespan/.zarray", + "sample_name.zarr/tables/table/obs/lifespan/.zattrs", + "sample_name.zarr/tables/table/obs/lifespan/0", + "sample_name.zarr/tables/table/obs/max_cluster_frac", + "sample_name.zarr/tables/table/obs/max_cluster_frac/.zarray", + "sample_name.zarr/tables/table/obs/max_cluster_frac/.zattrs", + "sample_name.zarr/tables/table/obs/max_cluster_frac/0", + "sample_name.zarr/tables/table/obs/n_transcripts", + "sample_name.zarr/tables/table/obs/n_transcripts/.zarray", + "sample_name.zarr/tables/table/obs/n_transcripts/.zattrs", + "sample_name.zarr/tables/table/obs/n_transcripts/0", + "sample_name.zarr/tables/table/obs/region", + "sample_name.zarr/tables/table/obs/region/.zattrs", + "sample_name.zarr/tables/table/obs/region/.zgroup", + "sample_name.zarr/tables/table/obs/region/categories", + "sample_name.zarr/tables/table/obs/region/categories/.zarray", + "sample_name.zarr/tables/table/obs/region/categories/.zattrs", + "sample_name.zarr/tables/table/obs/region/categories/0", + "sample_name.zarr/tables/table/obs/region/codes", + "sample_name.zarr/tables/table/obs/region/codes/.zarray", + "sample_name.zarr/tables/table/obs/region/codes/.zattrs", + "sample_name.zarr/tables/table/obs/region/codes/0", + "sample_name.zarr/tables/table/obs/slide", + "sample_name.zarr/tables/table/obs/slide/.zattrs", + "sample_name.zarr/tables/table/obs/slide/.zgroup", + "sample_name.zarr/tables/table/obs/slide/categories", + "sample_name.zarr/tables/table/obs/slide/categories/.zarray", + "sample_name.zarr/tables/table/obs/slide/categories/.zattrs", + "sample_name.zarr/tables/table/obs/slide/categories/0", + "sample_name.zarr/tables/table/obs/slide/codes", + "sample_name.zarr/tables/table/obs/slide/codes/.zarray", + "sample_name.zarr/tables/table/obs/slide/codes/.zattrs", + "sample_name.zarr/tables/table/obs/slide/codes/0", + "sample_name.zarr/tables/table/obs/x", + "sample_name.zarr/tables/table/obs/x/.zarray", + "sample_name.zarr/tables/table/obs/x/.zattrs", + "sample_name.zarr/tables/table/obs/x/0", + "sample_name.zarr/tables/table/obs/y", + "sample_name.zarr/tables/table/obs/y/.zarray", + "sample_name.zarr/tables/table/obs/y/.zattrs", + "sample_name.zarr/tables/table/obs/y/0", + "sample_name.zarr/tables/table/obsm", + "sample_name.zarr/tables/table/obsm/.zattrs", + "sample_name.zarr/tables/table/obsm/.zgroup", + "sample_name.zarr/tables/table/obsm/intensities", + "sample_name.zarr/tables/table/obsm/intensities/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/.zgroup", + "sample_name.zarr/tables/table/obsm/intensities/CD20", + "sample_name.zarr/tables/table/obsm/intensities/CD20/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/CD20/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/CD20/0", + "sample_name.zarr/tables/table/obsm/intensities/CD3", + "sample_name.zarr/tables/table/obsm/intensities/CD3/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/CD3/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/CD3/0", + "sample_name.zarr/tables/table/obsm/intensities/CK", + "sample_name.zarr/tables/table/obsm/intensities/CK/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/CK/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/CK/0", + "sample_name.zarr/tables/table/obsm/intensities/DAPI", + "sample_name.zarr/tables/table/obsm/intensities/DAPI/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/DAPI/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/DAPI/0", + "sample_name.zarr/tables/table/obsm/intensities/_index", + "sample_name.zarr/tables/table/obsm/intensities/_index/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/_index/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/_index/0", + "sample_name.zarr/tables/table/obsm/spatial", + "sample_name.zarr/tables/table/obsm/spatial/.zarray", + "sample_name.zarr/tables/table/obsm/spatial/.zattrs", + "sample_name.zarr/tables/table/obsm/spatial/0", + "sample_name.zarr/tables/table/obsm/spatial/0/0", + "sample_name.zarr/tables/table/obsp", + "sample_name.zarr/tables/table/obsp/.zattrs", + "sample_name.zarr/tables/table/obsp/.zgroup", + "sample_name.zarr/tables/table/uns", + "sample_name.zarr/tables/table/uns/.zattrs", + "sample_name.zarr/tables/table/uns/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/0", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/0", + "sample_name.zarr/tables/table/var", + "sample_name.zarr/tables/table/var/.zattrs", + "sample_name.zarr/tables/table/var/.zgroup", + "sample_name.zarr/tables/table/var/Name", + "sample_name.zarr/tables/table/var/Name/.zarray", + "sample_name.zarr/tables/table/var/Name/.zattrs", + "sample_name.zarr/tables/table/var/Name/0", + "sample_name.zarr/tables/table/varm", + "sample_name.zarr/tables/table/varm/.zattrs", + "sample_name.zarr/tables/table/varm/.zgroup", + "sample_name.zarr/tables/table/varp", + "sample_name.zarr/tables/table/varp/.zattrs", + "sample_name.zarr/tables/table/varp/.zgroup", + "sample_name.zarr/zmetadata" ], [ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index c8488ed..bbbccdf 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -4,298 +4,298 @@ 9, { "Workflow": { - "nf-core/sopa": "v1.0.0dev" + "nf-core/sopa": "v1.0.0" } }, [ "pipeline_info", "pipeline_info/nf_core_sopa_software_mqc_versions.yml", - "sample1.explorer", - "sample1.explorer/adata.h5ad", - "sample1.explorer/analysis.zarr.zip", - "sample1.explorer/analysis_summary.html", - "sample1.explorer/cell_feature_matrix.zarr.zip", - "sample1.explorer/cells.zarr.zip", - "sample1.explorer/experiment.xenium", - "sample1.explorer/morphology.ome.tif", - "sample1.explorer/transcripts.zarr.zip", - "sample1.zarr", - "sample1.zarr/.zattrs", - "sample1.zarr/.zgroup", - "sample1.zarr/images", - "sample1.zarr/images/.zgroup", - "sample1.zarr/images/he_image", - "sample1.zarr/images/he_image/.zattrs", - "sample1.zarr/images/he_image/.zgroup", - "sample1.zarr/images/he_image/0", - "sample1.zarr/images/he_image/0/.zarray", - "sample1.zarr/images/he_image/0/0", - "sample1.zarr/images/he_image/0/0/0", - "sample1.zarr/images/he_image/0/0/0/0", - "sample1.zarr/images/he_image/0/0/0/1", - "sample1.zarr/images/he_image/0/0/0/2", - "sample1.zarr/images/he_image/0/0/0/3", - "sample1.zarr/images/he_image/0/0/1", - "sample1.zarr/images/he_image/0/0/1/0", - "sample1.zarr/images/he_image/0/0/1/1", - "sample1.zarr/images/he_image/0/0/1/2", - "sample1.zarr/images/he_image/0/0/1/3", - "sample1.zarr/images/he_image/0/0/2", - "sample1.zarr/images/he_image/0/0/2/0", - "sample1.zarr/images/he_image/0/0/2/1", - "sample1.zarr/images/he_image/0/0/2/2", - "sample1.zarr/images/he_image/0/0/2/3", - "sample1.zarr/images/he_image/0/0/3", - "sample1.zarr/images/he_image/0/0/3/0", - "sample1.zarr/images/he_image/0/0/3/1", - "sample1.zarr/images/he_image/0/0/3/2", - "sample1.zarr/images/he_image/0/0/3/3", - "sample1.zarr/images/he_image/1", - "sample1.zarr/images/he_image/1/.zarray", - "sample1.zarr/images/he_image/1/0", - "sample1.zarr/images/he_image/1/0/0", - "sample1.zarr/images/he_image/1/0/0/0", - "sample1.zarr/images/he_image/1/0/0/1", - "sample1.zarr/images/he_image/1/0/1", - "sample1.zarr/images/he_image/1/0/1/0", - "sample1.zarr/images/he_image/1/0/1/1", - "sample1.zarr/images/he_image/2", - "sample1.zarr/images/he_image/2/.zarray", - "sample1.zarr/images/he_image/2/0", - "sample1.zarr/images/he_image/2/0/0", - "sample1.zarr/images/he_image/2/0/0/0", - "sample1.zarr/images/image", - "sample1.zarr/images/image/.zattrs", - "sample1.zarr/images/image/.zgroup", - "sample1.zarr/images/image/0", - "sample1.zarr/images/image/0/.zarray", - "sample1.zarr/images/image/0/0", - "sample1.zarr/images/image/0/0/0", - "sample1.zarr/images/image/0/0/0/0", - "sample1.zarr/images/image/0/0/0/1", - "sample1.zarr/images/image/0/0/1", - "sample1.zarr/images/image/0/0/1/0", - "sample1.zarr/images/image/0/0/1/1", - "sample1.zarr/images/image/0/1", - "sample1.zarr/images/image/0/1/0", - "sample1.zarr/images/image/0/1/0/0", - "sample1.zarr/images/image/0/1/0/1", - "sample1.zarr/images/image/0/1/1", - "sample1.zarr/images/image/0/1/1/0", - "sample1.zarr/images/image/0/1/1/1", - "sample1.zarr/images/image/0/2", - "sample1.zarr/images/image/0/2/0", - "sample1.zarr/images/image/0/2/0/0", - "sample1.zarr/images/image/0/2/0/1", - "sample1.zarr/images/image/0/2/1", - "sample1.zarr/images/image/0/2/1/0", - "sample1.zarr/images/image/0/2/1/1", - "sample1.zarr/images/image/0/3", - "sample1.zarr/images/image/0/3/0", - "sample1.zarr/images/image/0/3/0/0", - "sample1.zarr/images/image/0/3/0/1", - "sample1.zarr/images/image/0/3/1", - "sample1.zarr/images/image/0/3/1/0", - "sample1.zarr/images/image/0/3/1/1", - "sample1.zarr/points", - "sample1.zarr/points/.zgroup", - "sample1.zarr/points/transcripts", - "sample1.zarr/points/transcripts/.zattrs", - "sample1.zarr/points/transcripts/.zgroup", - "sample1.zarr/points/transcripts/points.parquet", - "sample1.zarr/points/transcripts/points.parquet/part.0.parquet", - "sample1.zarr/shapes", - "sample1.zarr/shapes/.zgroup", - "sample1.zarr/shapes/baysor_boundaries", - "sample1.zarr/shapes/baysor_boundaries/.zattrs", - "sample1.zarr/shapes/baysor_boundaries/.zgroup", - "sample1.zarr/shapes/baysor_boundaries/shapes.parquet", - "sample1.zarr/shapes/cells", - "sample1.zarr/shapes/cells/.zattrs", - "sample1.zarr/shapes/cells/.zgroup", - "sample1.zarr/shapes/cells/shapes.parquet", - "sample1.zarr/shapes/transcripts_patches", - "sample1.zarr/shapes/transcripts_patches/.zattrs", - "sample1.zarr/shapes/transcripts_patches/.zgroup", - "sample1.zarr/shapes/transcripts_patches/shapes.parquet", - "sample1.zarr/tables", - "sample1.zarr/tables/.zgroup", - "sample1.zarr/tables/table", - "sample1.zarr/tables/table/.zattrs", - "sample1.zarr/tables/table/.zgroup", - "sample1.zarr/tables/table/X", - "sample1.zarr/tables/table/X/.zattrs", - "sample1.zarr/tables/table/X/.zgroup", - "sample1.zarr/tables/table/X/data", - "sample1.zarr/tables/table/X/data/.zarray", - "sample1.zarr/tables/table/X/data/0", - "sample1.zarr/tables/table/X/indices", - "sample1.zarr/tables/table/X/indices/.zarray", - "sample1.zarr/tables/table/X/indices/0", - "sample1.zarr/tables/table/X/indptr", - "sample1.zarr/tables/table/X/indptr/.zarray", - "sample1.zarr/tables/table/X/indptr/0", - "sample1.zarr/tables/table/layers", - "sample1.zarr/tables/table/layers/.zattrs", - "sample1.zarr/tables/table/layers/.zgroup", - "sample1.zarr/tables/table/obs", - "sample1.zarr/tables/table/obs/.zattrs", - "sample1.zarr/tables/table/obs/.zgroup", - "sample1.zarr/tables/table/obs/_index", - "sample1.zarr/tables/table/obs/_index/.zarray", - "sample1.zarr/tables/table/obs/_index/.zattrs", - "sample1.zarr/tables/table/obs/_index/0", - "sample1.zarr/tables/table/obs/area", - "sample1.zarr/tables/table/obs/area/.zarray", - "sample1.zarr/tables/table/obs/area/.zattrs", - "sample1.zarr/tables/table/obs/area/0", - "sample1.zarr/tables/table/obs/avg_assignment_confidence", - "sample1.zarr/tables/table/obs/avg_assignment_confidence/.zarray", - "sample1.zarr/tables/table/obs/avg_assignment_confidence/.zattrs", - "sample1.zarr/tables/table/obs/avg_assignment_confidence/0", - "sample1.zarr/tables/table/obs/avg_confidence", - "sample1.zarr/tables/table/obs/avg_confidence/.zarray", - "sample1.zarr/tables/table/obs/avg_confidence/.zattrs", - "sample1.zarr/tables/table/obs/avg_confidence/0", - "sample1.zarr/tables/table/obs/baysor_area", - "sample1.zarr/tables/table/obs/baysor_area/.zarray", - "sample1.zarr/tables/table/obs/baysor_area/.zattrs", - "sample1.zarr/tables/table/obs/baysor_area/0", - "sample1.zarr/tables/table/obs/cell_id", - "sample1.zarr/tables/table/obs/cell_id/.zarray", - "sample1.zarr/tables/table/obs/cell_id/.zattrs", - "sample1.zarr/tables/table/obs/cell_id/0", - "sample1.zarr/tables/table/obs/cluster", - "sample1.zarr/tables/table/obs/cluster/.zarray", - "sample1.zarr/tables/table/obs/cluster/.zattrs", - "sample1.zarr/tables/table/obs/cluster/0", - "sample1.zarr/tables/table/obs/density", - "sample1.zarr/tables/table/obs/density/.zarray", - "sample1.zarr/tables/table/obs/density/.zattrs", - "sample1.zarr/tables/table/obs/density/0", - "sample1.zarr/tables/table/obs/elongation", - "sample1.zarr/tables/table/obs/elongation/.zarray", - "sample1.zarr/tables/table/obs/elongation/.zattrs", - "sample1.zarr/tables/table/obs/elongation/0", - "sample1.zarr/tables/table/obs/lifespan", - "sample1.zarr/tables/table/obs/lifespan/.zarray", - "sample1.zarr/tables/table/obs/lifespan/.zattrs", - "sample1.zarr/tables/table/obs/lifespan/0", - "sample1.zarr/tables/table/obs/max_cluster_frac", - "sample1.zarr/tables/table/obs/max_cluster_frac/.zarray", - "sample1.zarr/tables/table/obs/max_cluster_frac/.zattrs", - "sample1.zarr/tables/table/obs/max_cluster_frac/0", - "sample1.zarr/tables/table/obs/n_transcripts", - "sample1.zarr/tables/table/obs/n_transcripts/.zarray", - "sample1.zarr/tables/table/obs/n_transcripts/.zattrs", - "sample1.zarr/tables/table/obs/n_transcripts/0", - "sample1.zarr/tables/table/obs/region", - "sample1.zarr/tables/table/obs/region/.zattrs", - "sample1.zarr/tables/table/obs/region/.zgroup", - "sample1.zarr/tables/table/obs/region/categories", - "sample1.zarr/tables/table/obs/region/categories/.zarray", - "sample1.zarr/tables/table/obs/region/categories/.zattrs", - "sample1.zarr/tables/table/obs/region/categories/0", - "sample1.zarr/tables/table/obs/region/codes", - "sample1.zarr/tables/table/obs/region/codes/.zarray", - "sample1.zarr/tables/table/obs/region/codes/.zattrs", - "sample1.zarr/tables/table/obs/region/codes/0", - "sample1.zarr/tables/table/obs/slide", - "sample1.zarr/tables/table/obs/slide/.zattrs", - "sample1.zarr/tables/table/obs/slide/.zgroup", - "sample1.zarr/tables/table/obs/slide/categories", - "sample1.zarr/tables/table/obs/slide/categories/.zarray", - "sample1.zarr/tables/table/obs/slide/categories/.zattrs", - "sample1.zarr/tables/table/obs/slide/categories/0", - "sample1.zarr/tables/table/obs/slide/codes", - "sample1.zarr/tables/table/obs/slide/codes/.zarray", - "sample1.zarr/tables/table/obs/slide/codes/.zattrs", - "sample1.zarr/tables/table/obs/slide/codes/0", - "sample1.zarr/tables/table/obs/x", - "sample1.zarr/tables/table/obs/x/.zarray", - "sample1.zarr/tables/table/obs/x/.zattrs", - "sample1.zarr/tables/table/obs/x/0", - "sample1.zarr/tables/table/obs/y", - "sample1.zarr/tables/table/obs/y/.zarray", - "sample1.zarr/tables/table/obs/y/.zattrs", - "sample1.zarr/tables/table/obs/y/0", - "sample1.zarr/tables/table/obsm", - "sample1.zarr/tables/table/obsm/.zattrs", - "sample1.zarr/tables/table/obsm/.zgroup", - "sample1.zarr/tables/table/obsm/intensities", - "sample1.zarr/tables/table/obsm/intensities/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/.zgroup", - "sample1.zarr/tables/table/obsm/intensities/CD20", - "sample1.zarr/tables/table/obsm/intensities/CD20/.zarray", - "sample1.zarr/tables/table/obsm/intensities/CD20/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/CD20/0", - "sample1.zarr/tables/table/obsm/intensities/CD3", - "sample1.zarr/tables/table/obsm/intensities/CD3/.zarray", - "sample1.zarr/tables/table/obsm/intensities/CD3/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/CD3/0", - "sample1.zarr/tables/table/obsm/intensities/CK", - "sample1.zarr/tables/table/obsm/intensities/CK/.zarray", - "sample1.zarr/tables/table/obsm/intensities/CK/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/CK/0", - "sample1.zarr/tables/table/obsm/intensities/DAPI", - "sample1.zarr/tables/table/obsm/intensities/DAPI/.zarray", - "sample1.zarr/tables/table/obsm/intensities/DAPI/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/DAPI/0", - "sample1.zarr/tables/table/obsm/intensities/_index", - "sample1.zarr/tables/table/obsm/intensities/_index/.zarray", - "sample1.zarr/tables/table/obsm/intensities/_index/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/_index/0", - "sample1.zarr/tables/table/obsm/spatial", - "sample1.zarr/tables/table/obsm/spatial/.zarray", - "sample1.zarr/tables/table/obsm/spatial/.zattrs", - "sample1.zarr/tables/table/obsm/spatial/0", - "sample1.zarr/tables/table/obsm/spatial/0/0", - "sample1.zarr/tables/table/obsp", - "sample1.zarr/tables/table/obsp/.zattrs", - "sample1.zarr/tables/table/obsp/.zgroup", - "sample1.zarr/tables/table/uns", - "sample1.zarr/tables/table/uns/.zattrs", - "sample1.zarr/tables/table/uns/.zgroup", - "sample1.zarr/tables/table/uns/sopa_attrs", - "sample1.zarr/tables/table/uns/sopa_attrs/.zattrs", - "sample1.zarr/tables/table/uns/sopa_attrs/.zgroup", - "sample1.zarr/tables/table/uns/sopa_attrs/intensities", - "sample1.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", - "sample1.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", - "sample1.zarr/tables/table/uns/sopa_attrs/intensities/0", - "sample1.zarr/tables/table/uns/sopa_attrs/transcripts", - "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", - "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", - "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/0", - "sample1.zarr/tables/table/uns/spatialdata_attrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/.zattrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/.zgroup", - "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key", - "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", - "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region/0", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/0", - "sample1.zarr/tables/table/var", - "sample1.zarr/tables/table/var/.zattrs", - "sample1.zarr/tables/table/var/.zgroup", - "sample1.zarr/tables/table/var/Name", - "sample1.zarr/tables/table/var/Name/.zarray", - "sample1.zarr/tables/table/var/Name/.zattrs", - "sample1.zarr/tables/table/var/Name/0", - "sample1.zarr/tables/table/varm", - "sample1.zarr/tables/table/varm/.zattrs", - "sample1.zarr/tables/table/varm/.zgroup", - "sample1.zarr/tables/table/varp", - "sample1.zarr/tables/table/varp/.zattrs", - "sample1.zarr/tables/table/varp/.zgroup", - "sample1.zarr/zmetadata" + "sample_name.explorer", + "sample_name.explorer/adata.h5ad", + "sample_name.explorer/analysis.zarr.zip", + "sample_name.explorer/analysis_summary.html", + "sample_name.explorer/cell_feature_matrix.zarr.zip", + "sample_name.explorer/cells.zarr.zip", + "sample_name.explorer/experiment.xenium", + "sample_name.explorer/morphology.ome.tif", + "sample_name.explorer/transcripts.zarr.zip", + "sample_name.zarr", + "sample_name.zarr/.zattrs", + "sample_name.zarr/.zgroup", + "sample_name.zarr/images", + "sample_name.zarr/images/.zgroup", + "sample_name.zarr/images/he_image", + "sample_name.zarr/images/he_image/.zattrs", + "sample_name.zarr/images/he_image/.zgroup", + "sample_name.zarr/images/he_image/0", + "sample_name.zarr/images/he_image/0/.zarray", + "sample_name.zarr/images/he_image/0/0", + "sample_name.zarr/images/he_image/0/0/0", + "sample_name.zarr/images/he_image/0/0/0/0", + "sample_name.zarr/images/he_image/0/0/0/1", + "sample_name.zarr/images/he_image/0/0/0/2", + "sample_name.zarr/images/he_image/0/0/0/3", + "sample_name.zarr/images/he_image/0/0/1", + "sample_name.zarr/images/he_image/0/0/1/0", + "sample_name.zarr/images/he_image/0/0/1/1", + "sample_name.zarr/images/he_image/0/0/1/2", + "sample_name.zarr/images/he_image/0/0/1/3", + "sample_name.zarr/images/he_image/0/0/2", + "sample_name.zarr/images/he_image/0/0/2/0", + "sample_name.zarr/images/he_image/0/0/2/1", + "sample_name.zarr/images/he_image/0/0/2/2", + "sample_name.zarr/images/he_image/0/0/2/3", + "sample_name.zarr/images/he_image/0/0/3", + "sample_name.zarr/images/he_image/0/0/3/0", + "sample_name.zarr/images/he_image/0/0/3/1", + "sample_name.zarr/images/he_image/0/0/3/2", + "sample_name.zarr/images/he_image/0/0/3/3", + "sample_name.zarr/images/he_image/1", + "sample_name.zarr/images/he_image/1/.zarray", + "sample_name.zarr/images/he_image/1/0", + "sample_name.zarr/images/he_image/1/0/0", + "sample_name.zarr/images/he_image/1/0/0/0", + "sample_name.zarr/images/he_image/1/0/0/1", + "sample_name.zarr/images/he_image/1/0/1", + "sample_name.zarr/images/he_image/1/0/1/0", + "sample_name.zarr/images/he_image/1/0/1/1", + "sample_name.zarr/images/he_image/2", + "sample_name.zarr/images/he_image/2/.zarray", + "sample_name.zarr/images/he_image/2/0", + "sample_name.zarr/images/he_image/2/0/0", + "sample_name.zarr/images/he_image/2/0/0/0", + "sample_name.zarr/images/image", + "sample_name.zarr/images/image/.zattrs", + "sample_name.zarr/images/image/.zgroup", + "sample_name.zarr/images/image/0", + "sample_name.zarr/images/image/0/.zarray", + "sample_name.zarr/images/image/0/0", + "sample_name.zarr/images/image/0/0/0", + "sample_name.zarr/images/image/0/0/0/0", + "sample_name.zarr/images/image/0/0/0/1", + "sample_name.zarr/images/image/0/0/1", + "sample_name.zarr/images/image/0/0/1/0", + "sample_name.zarr/images/image/0/0/1/1", + "sample_name.zarr/images/image/0/1", + "sample_name.zarr/images/image/0/1/0", + "sample_name.zarr/images/image/0/1/0/0", + "sample_name.zarr/images/image/0/1/0/1", + "sample_name.zarr/images/image/0/1/1", + "sample_name.zarr/images/image/0/1/1/0", + "sample_name.zarr/images/image/0/1/1/1", + "sample_name.zarr/images/image/0/2", + "sample_name.zarr/images/image/0/2/0", + "sample_name.zarr/images/image/0/2/0/0", + "sample_name.zarr/images/image/0/2/0/1", + "sample_name.zarr/images/image/0/2/1", + "sample_name.zarr/images/image/0/2/1/0", + "sample_name.zarr/images/image/0/2/1/1", + "sample_name.zarr/images/image/0/3", + "sample_name.zarr/images/image/0/3/0", + "sample_name.zarr/images/image/0/3/0/0", + "sample_name.zarr/images/image/0/3/0/1", + "sample_name.zarr/images/image/0/3/1", + "sample_name.zarr/images/image/0/3/1/0", + "sample_name.zarr/images/image/0/3/1/1", + "sample_name.zarr/points", + "sample_name.zarr/points/.zgroup", + "sample_name.zarr/points/transcripts", + "sample_name.zarr/points/transcripts/.zattrs", + "sample_name.zarr/points/transcripts/.zgroup", + "sample_name.zarr/points/transcripts/points.parquet", + "sample_name.zarr/points/transcripts/points.parquet/part.0.parquet", + "sample_name.zarr/shapes", + "sample_name.zarr/shapes/.zgroup", + "sample_name.zarr/shapes/baysor_boundaries", + "sample_name.zarr/shapes/baysor_boundaries/.zattrs", + "sample_name.zarr/shapes/baysor_boundaries/.zgroup", + "sample_name.zarr/shapes/baysor_boundaries/shapes.parquet", + "sample_name.zarr/shapes/cells", + "sample_name.zarr/shapes/cells/.zattrs", + "sample_name.zarr/shapes/cells/.zgroup", + "sample_name.zarr/shapes/cells/shapes.parquet", + "sample_name.zarr/shapes/transcripts_patches", + "sample_name.zarr/shapes/transcripts_patches/.zattrs", + "sample_name.zarr/shapes/transcripts_patches/.zgroup", + "sample_name.zarr/shapes/transcripts_patches/shapes.parquet", + "sample_name.zarr/tables", + "sample_name.zarr/tables/.zgroup", + "sample_name.zarr/tables/table", + "sample_name.zarr/tables/table/.zattrs", + "sample_name.zarr/tables/table/.zgroup", + "sample_name.zarr/tables/table/X", + "sample_name.zarr/tables/table/X/.zattrs", + "sample_name.zarr/tables/table/X/.zgroup", + "sample_name.zarr/tables/table/X/data", + "sample_name.zarr/tables/table/X/data/.zarray", + "sample_name.zarr/tables/table/X/data/0", + "sample_name.zarr/tables/table/X/indices", + "sample_name.zarr/tables/table/X/indices/.zarray", + "sample_name.zarr/tables/table/X/indices/0", + "sample_name.zarr/tables/table/X/indptr", + "sample_name.zarr/tables/table/X/indptr/.zarray", + "sample_name.zarr/tables/table/X/indptr/0", + "sample_name.zarr/tables/table/layers", + "sample_name.zarr/tables/table/layers/.zattrs", + "sample_name.zarr/tables/table/layers/.zgroup", + "sample_name.zarr/tables/table/obs", + "sample_name.zarr/tables/table/obs/.zattrs", + "sample_name.zarr/tables/table/obs/.zgroup", + "sample_name.zarr/tables/table/obs/_index", + "sample_name.zarr/tables/table/obs/_index/.zarray", + "sample_name.zarr/tables/table/obs/_index/.zattrs", + "sample_name.zarr/tables/table/obs/_index/0", + "sample_name.zarr/tables/table/obs/area", + "sample_name.zarr/tables/table/obs/area/.zarray", + "sample_name.zarr/tables/table/obs/area/.zattrs", + "sample_name.zarr/tables/table/obs/area/0", + "sample_name.zarr/tables/table/obs/avg_assignment_confidence", + "sample_name.zarr/tables/table/obs/avg_assignment_confidence/.zarray", + "sample_name.zarr/tables/table/obs/avg_assignment_confidence/.zattrs", + "sample_name.zarr/tables/table/obs/avg_assignment_confidence/0", + "sample_name.zarr/tables/table/obs/avg_confidence", + "sample_name.zarr/tables/table/obs/avg_confidence/.zarray", + "sample_name.zarr/tables/table/obs/avg_confidence/.zattrs", + "sample_name.zarr/tables/table/obs/avg_confidence/0", + "sample_name.zarr/tables/table/obs/baysor_area", + "sample_name.zarr/tables/table/obs/baysor_area/.zarray", + "sample_name.zarr/tables/table/obs/baysor_area/.zattrs", + "sample_name.zarr/tables/table/obs/baysor_area/0", + "sample_name.zarr/tables/table/obs/cell_id", + "sample_name.zarr/tables/table/obs/cell_id/.zarray", + "sample_name.zarr/tables/table/obs/cell_id/.zattrs", + "sample_name.zarr/tables/table/obs/cell_id/0", + "sample_name.zarr/tables/table/obs/cluster", + "sample_name.zarr/tables/table/obs/cluster/.zarray", + "sample_name.zarr/tables/table/obs/cluster/.zattrs", + "sample_name.zarr/tables/table/obs/cluster/0", + "sample_name.zarr/tables/table/obs/density", + "sample_name.zarr/tables/table/obs/density/.zarray", + "sample_name.zarr/tables/table/obs/density/.zattrs", + "sample_name.zarr/tables/table/obs/density/0", + "sample_name.zarr/tables/table/obs/elongation", + "sample_name.zarr/tables/table/obs/elongation/.zarray", + "sample_name.zarr/tables/table/obs/elongation/.zattrs", + "sample_name.zarr/tables/table/obs/elongation/0", + "sample_name.zarr/tables/table/obs/lifespan", + "sample_name.zarr/tables/table/obs/lifespan/.zarray", + "sample_name.zarr/tables/table/obs/lifespan/.zattrs", + "sample_name.zarr/tables/table/obs/lifespan/0", + "sample_name.zarr/tables/table/obs/max_cluster_frac", + "sample_name.zarr/tables/table/obs/max_cluster_frac/.zarray", + "sample_name.zarr/tables/table/obs/max_cluster_frac/.zattrs", + "sample_name.zarr/tables/table/obs/max_cluster_frac/0", + "sample_name.zarr/tables/table/obs/n_transcripts", + "sample_name.zarr/tables/table/obs/n_transcripts/.zarray", + "sample_name.zarr/tables/table/obs/n_transcripts/.zattrs", + "sample_name.zarr/tables/table/obs/n_transcripts/0", + "sample_name.zarr/tables/table/obs/region", + "sample_name.zarr/tables/table/obs/region/.zattrs", + "sample_name.zarr/tables/table/obs/region/.zgroup", + "sample_name.zarr/tables/table/obs/region/categories", + "sample_name.zarr/tables/table/obs/region/categories/.zarray", + "sample_name.zarr/tables/table/obs/region/categories/.zattrs", + "sample_name.zarr/tables/table/obs/region/categories/0", + "sample_name.zarr/tables/table/obs/region/codes", + "sample_name.zarr/tables/table/obs/region/codes/.zarray", + "sample_name.zarr/tables/table/obs/region/codes/.zattrs", + "sample_name.zarr/tables/table/obs/region/codes/0", + "sample_name.zarr/tables/table/obs/slide", + "sample_name.zarr/tables/table/obs/slide/.zattrs", + "sample_name.zarr/tables/table/obs/slide/.zgroup", + "sample_name.zarr/tables/table/obs/slide/categories", + "sample_name.zarr/tables/table/obs/slide/categories/.zarray", + "sample_name.zarr/tables/table/obs/slide/categories/.zattrs", + "sample_name.zarr/tables/table/obs/slide/categories/0", + "sample_name.zarr/tables/table/obs/slide/codes", + "sample_name.zarr/tables/table/obs/slide/codes/.zarray", + "sample_name.zarr/tables/table/obs/slide/codes/.zattrs", + "sample_name.zarr/tables/table/obs/slide/codes/0", + "sample_name.zarr/tables/table/obs/x", + "sample_name.zarr/tables/table/obs/x/.zarray", + "sample_name.zarr/tables/table/obs/x/.zattrs", + "sample_name.zarr/tables/table/obs/x/0", + "sample_name.zarr/tables/table/obs/y", + "sample_name.zarr/tables/table/obs/y/.zarray", + "sample_name.zarr/tables/table/obs/y/.zattrs", + "sample_name.zarr/tables/table/obs/y/0", + "sample_name.zarr/tables/table/obsm", + "sample_name.zarr/tables/table/obsm/.zattrs", + "sample_name.zarr/tables/table/obsm/.zgroup", + "sample_name.zarr/tables/table/obsm/intensities", + "sample_name.zarr/tables/table/obsm/intensities/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/.zgroup", + "sample_name.zarr/tables/table/obsm/intensities/CD20", + "sample_name.zarr/tables/table/obsm/intensities/CD20/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/CD20/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/CD20/0", + "sample_name.zarr/tables/table/obsm/intensities/CD3", + "sample_name.zarr/tables/table/obsm/intensities/CD3/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/CD3/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/CD3/0", + "sample_name.zarr/tables/table/obsm/intensities/CK", + "sample_name.zarr/tables/table/obsm/intensities/CK/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/CK/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/CK/0", + "sample_name.zarr/tables/table/obsm/intensities/DAPI", + "sample_name.zarr/tables/table/obsm/intensities/DAPI/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/DAPI/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/DAPI/0", + "sample_name.zarr/tables/table/obsm/intensities/_index", + "sample_name.zarr/tables/table/obsm/intensities/_index/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/_index/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/_index/0", + "sample_name.zarr/tables/table/obsm/spatial", + "sample_name.zarr/tables/table/obsm/spatial/.zarray", + "sample_name.zarr/tables/table/obsm/spatial/.zattrs", + "sample_name.zarr/tables/table/obsm/spatial/0", + "sample_name.zarr/tables/table/obsm/spatial/0/0", + "sample_name.zarr/tables/table/obsp", + "sample_name.zarr/tables/table/obsp/.zattrs", + "sample_name.zarr/tables/table/obsp/.zgroup", + "sample_name.zarr/tables/table/uns", + "sample_name.zarr/tables/table/uns/.zattrs", + "sample_name.zarr/tables/table/uns/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/0", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/0", + "sample_name.zarr/tables/table/var", + "sample_name.zarr/tables/table/var/.zattrs", + "sample_name.zarr/tables/table/var/.zgroup", + "sample_name.zarr/tables/table/var/Name", + "sample_name.zarr/tables/table/var/Name/.zarray", + "sample_name.zarr/tables/table/var/Name/.zattrs", + "sample_name.zarr/tables/table/var/Name/0", + "sample_name.zarr/tables/table/varm", + "sample_name.zarr/tables/table/varm/.zattrs", + "sample_name.zarr/tables/table/varm/.zgroup", + "sample_name.zarr/tables/table/varp", + "sample_name.zarr/tables/table/varp/.zattrs", + "sample_name.zarr/tables/table/varp/.zgroup", + "sample_name.zarr/zmetadata" ], [ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", diff --git a/tests/proseg.nf.test.snap b/tests/proseg.nf.test.snap index a785b94..76bdffb 100644 --- a/tests/proseg.nf.test.snap +++ b/tests/proseg.nf.test.snap @@ -4,298 +4,298 @@ 9, { "Workflow": { - "nf-core/sopa": "v1.0.0dev" + "nf-core/sopa": "v1.0.0" } }, [ "pipeline_info", "pipeline_info/nf_core_sopa_software_mqc_versions.yml", - "sample1.explorer", - "sample1.explorer/adata.h5ad", - "sample1.explorer/analysis.zarr.zip", - "sample1.explorer/analysis_summary.html", - "sample1.explorer/cell_feature_matrix.zarr.zip", - "sample1.explorer/cells.zarr.zip", - "sample1.explorer/experiment.xenium", - "sample1.explorer/morphology.ome.tif", - "sample1.explorer/transcripts.zarr.zip", - "sample1.zarr", - "sample1.zarr/.zattrs", - "sample1.zarr/.zgroup", - "sample1.zarr/images", - "sample1.zarr/images/.zgroup", - "sample1.zarr/images/he_image", - "sample1.zarr/images/he_image/.zattrs", - "sample1.zarr/images/he_image/.zgroup", - "sample1.zarr/images/he_image/0", - "sample1.zarr/images/he_image/0/.zarray", - "sample1.zarr/images/he_image/0/0", - "sample1.zarr/images/he_image/0/0/0", - "sample1.zarr/images/he_image/0/0/0/0", - "sample1.zarr/images/he_image/0/0/0/1", - "sample1.zarr/images/he_image/0/0/0/2", - "sample1.zarr/images/he_image/0/0/0/3", - "sample1.zarr/images/he_image/0/0/1", - "sample1.zarr/images/he_image/0/0/1/0", - "sample1.zarr/images/he_image/0/0/1/1", - "sample1.zarr/images/he_image/0/0/1/2", - "sample1.zarr/images/he_image/0/0/1/3", - "sample1.zarr/images/he_image/0/0/2", - "sample1.zarr/images/he_image/0/0/2/0", - "sample1.zarr/images/he_image/0/0/2/1", - "sample1.zarr/images/he_image/0/0/2/2", - "sample1.zarr/images/he_image/0/0/2/3", - "sample1.zarr/images/he_image/0/0/3", - "sample1.zarr/images/he_image/0/0/3/0", - "sample1.zarr/images/he_image/0/0/3/1", - "sample1.zarr/images/he_image/0/0/3/2", - "sample1.zarr/images/he_image/0/0/3/3", - "sample1.zarr/images/he_image/1", - "sample1.zarr/images/he_image/1/.zarray", - "sample1.zarr/images/he_image/1/0", - "sample1.zarr/images/he_image/1/0/0", - "sample1.zarr/images/he_image/1/0/0/0", - "sample1.zarr/images/he_image/1/0/0/1", - "sample1.zarr/images/he_image/1/0/1", - "sample1.zarr/images/he_image/1/0/1/0", - "sample1.zarr/images/he_image/1/0/1/1", - "sample1.zarr/images/he_image/2", - "sample1.zarr/images/he_image/2/.zarray", - "sample1.zarr/images/he_image/2/0", - "sample1.zarr/images/he_image/2/0/0", - "sample1.zarr/images/he_image/2/0/0/0", - "sample1.zarr/images/image", - "sample1.zarr/images/image/.zattrs", - "sample1.zarr/images/image/.zgroup", - "sample1.zarr/images/image/0", - "sample1.zarr/images/image/0/.zarray", - "sample1.zarr/images/image/0/0", - "sample1.zarr/images/image/0/0/0", - "sample1.zarr/images/image/0/0/0/0", - "sample1.zarr/images/image/0/0/0/1", - "sample1.zarr/images/image/0/0/1", - "sample1.zarr/images/image/0/0/1/0", - "sample1.zarr/images/image/0/0/1/1", - "sample1.zarr/images/image/0/1", - "sample1.zarr/images/image/0/1/0", - "sample1.zarr/images/image/0/1/0/0", - "sample1.zarr/images/image/0/1/0/1", - "sample1.zarr/images/image/0/1/1", - "sample1.zarr/images/image/0/1/1/0", - "sample1.zarr/images/image/0/1/1/1", - "sample1.zarr/images/image/0/2", - "sample1.zarr/images/image/0/2/0", - "sample1.zarr/images/image/0/2/0/0", - "sample1.zarr/images/image/0/2/0/1", - "sample1.zarr/images/image/0/2/1", - "sample1.zarr/images/image/0/2/1/0", - "sample1.zarr/images/image/0/2/1/1", - "sample1.zarr/images/image/0/3", - "sample1.zarr/images/image/0/3/0", - "sample1.zarr/images/image/0/3/0/0", - "sample1.zarr/images/image/0/3/0/1", - "sample1.zarr/images/image/0/3/1", - "sample1.zarr/images/image/0/3/1/0", - "sample1.zarr/images/image/0/3/1/1", - "sample1.zarr/points", - "sample1.zarr/points/.zgroup", - "sample1.zarr/points/transcripts", - "sample1.zarr/points/transcripts/.zattrs", - "sample1.zarr/points/transcripts/.zgroup", - "sample1.zarr/points/transcripts/points.parquet", - "sample1.zarr/points/transcripts/points.parquet/part.0.parquet", - "sample1.zarr/shapes", - "sample1.zarr/shapes/.zgroup", - "sample1.zarr/shapes/baysor_boundaries", - "sample1.zarr/shapes/baysor_boundaries/.zattrs", - "sample1.zarr/shapes/baysor_boundaries/.zgroup", - "sample1.zarr/shapes/baysor_boundaries/shapes.parquet", - "sample1.zarr/shapes/cells", - "sample1.zarr/shapes/cells/.zattrs", - "sample1.zarr/shapes/cells/.zgroup", - "sample1.zarr/shapes/cells/shapes.parquet", - "sample1.zarr/shapes/transcripts_patches", - "sample1.zarr/shapes/transcripts_patches/.zattrs", - "sample1.zarr/shapes/transcripts_patches/.zgroup", - "sample1.zarr/shapes/transcripts_patches/shapes.parquet", - "sample1.zarr/tables", - "sample1.zarr/tables/.zgroup", - "sample1.zarr/tables/table", - "sample1.zarr/tables/table/.zattrs", - "sample1.zarr/tables/table/.zgroup", - "sample1.zarr/tables/table/X", - "sample1.zarr/tables/table/X/.zattrs", - "sample1.zarr/tables/table/X/.zgroup", - "sample1.zarr/tables/table/X/data", - "sample1.zarr/tables/table/X/data/.zarray", - "sample1.zarr/tables/table/X/data/0", - "sample1.zarr/tables/table/X/indices", - "sample1.zarr/tables/table/X/indices/.zarray", - "sample1.zarr/tables/table/X/indices/0", - "sample1.zarr/tables/table/X/indptr", - "sample1.zarr/tables/table/X/indptr/.zarray", - "sample1.zarr/tables/table/X/indptr/0", - "sample1.zarr/tables/table/layers", - "sample1.zarr/tables/table/layers/.zattrs", - "sample1.zarr/tables/table/layers/.zgroup", - "sample1.zarr/tables/table/obs", - "sample1.zarr/tables/table/obs/.zattrs", - "sample1.zarr/tables/table/obs/.zgroup", - "sample1.zarr/tables/table/obs/_index", - "sample1.zarr/tables/table/obs/_index/.zarray", - "sample1.zarr/tables/table/obs/_index/.zattrs", - "sample1.zarr/tables/table/obs/_index/0", - "sample1.zarr/tables/table/obs/area", - "sample1.zarr/tables/table/obs/area/.zarray", - "sample1.zarr/tables/table/obs/area/.zattrs", - "sample1.zarr/tables/table/obs/area/0", - "sample1.zarr/tables/table/obs/avg_assignment_confidence", - "sample1.zarr/tables/table/obs/avg_assignment_confidence/.zarray", - "sample1.zarr/tables/table/obs/avg_assignment_confidence/.zattrs", - "sample1.zarr/tables/table/obs/avg_assignment_confidence/0", - "sample1.zarr/tables/table/obs/avg_confidence", - "sample1.zarr/tables/table/obs/avg_confidence/.zarray", - "sample1.zarr/tables/table/obs/avg_confidence/.zattrs", - "sample1.zarr/tables/table/obs/avg_confidence/0", - "sample1.zarr/tables/table/obs/baysor_area", - "sample1.zarr/tables/table/obs/baysor_area/.zarray", - "sample1.zarr/tables/table/obs/baysor_area/.zattrs", - "sample1.zarr/tables/table/obs/baysor_area/0", - "sample1.zarr/tables/table/obs/cell_id", - "sample1.zarr/tables/table/obs/cell_id/.zarray", - "sample1.zarr/tables/table/obs/cell_id/.zattrs", - "sample1.zarr/tables/table/obs/cell_id/0", - "sample1.zarr/tables/table/obs/cluster", - "sample1.zarr/tables/table/obs/cluster/.zarray", - "sample1.zarr/tables/table/obs/cluster/.zattrs", - "sample1.zarr/tables/table/obs/cluster/0", - "sample1.zarr/tables/table/obs/density", - "sample1.zarr/tables/table/obs/density/.zarray", - "sample1.zarr/tables/table/obs/density/.zattrs", - "sample1.zarr/tables/table/obs/density/0", - "sample1.zarr/tables/table/obs/elongation", - "sample1.zarr/tables/table/obs/elongation/.zarray", - "sample1.zarr/tables/table/obs/elongation/.zattrs", - "sample1.zarr/tables/table/obs/elongation/0", - "sample1.zarr/tables/table/obs/lifespan", - "sample1.zarr/tables/table/obs/lifespan/.zarray", - "sample1.zarr/tables/table/obs/lifespan/.zattrs", - "sample1.zarr/tables/table/obs/lifespan/0", - "sample1.zarr/tables/table/obs/max_cluster_frac", - "sample1.zarr/tables/table/obs/max_cluster_frac/.zarray", - "sample1.zarr/tables/table/obs/max_cluster_frac/.zattrs", - "sample1.zarr/tables/table/obs/max_cluster_frac/0", - "sample1.zarr/tables/table/obs/n_transcripts", - "sample1.zarr/tables/table/obs/n_transcripts/.zarray", - "sample1.zarr/tables/table/obs/n_transcripts/.zattrs", - "sample1.zarr/tables/table/obs/n_transcripts/0", - "sample1.zarr/tables/table/obs/region", - "sample1.zarr/tables/table/obs/region/.zattrs", - "sample1.zarr/tables/table/obs/region/.zgroup", - "sample1.zarr/tables/table/obs/region/categories", - "sample1.zarr/tables/table/obs/region/categories/.zarray", - "sample1.zarr/tables/table/obs/region/categories/.zattrs", - "sample1.zarr/tables/table/obs/region/categories/0", - "sample1.zarr/tables/table/obs/region/codes", - "sample1.zarr/tables/table/obs/region/codes/.zarray", - "sample1.zarr/tables/table/obs/region/codes/.zattrs", - "sample1.zarr/tables/table/obs/region/codes/0", - "sample1.zarr/tables/table/obs/slide", - "sample1.zarr/tables/table/obs/slide/.zattrs", - "sample1.zarr/tables/table/obs/slide/.zgroup", - "sample1.zarr/tables/table/obs/slide/categories", - "sample1.zarr/tables/table/obs/slide/categories/.zarray", - "sample1.zarr/tables/table/obs/slide/categories/.zattrs", - "sample1.zarr/tables/table/obs/slide/categories/0", - "sample1.zarr/tables/table/obs/slide/codes", - "sample1.zarr/tables/table/obs/slide/codes/.zarray", - "sample1.zarr/tables/table/obs/slide/codes/.zattrs", - "sample1.zarr/tables/table/obs/slide/codes/0", - "sample1.zarr/tables/table/obs/x", - "sample1.zarr/tables/table/obs/x/.zarray", - "sample1.zarr/tables/table/obs/x/.zattrs", - "sample1.zarr/tables/table/obs/x/0", - "sample1.zarr/tables/table/obs/y", - "sample1.zarr/tables/table/obs/y/.zarray", - "sample1.zarr/tables/table/obs/y/.zattrs", - "sample1.zarr/tables/table/obs/y/0", - "sample1.zarr/tables/table/obsm", - "sample1.zarr/tables/table/obsm/.zattrs", - "sample1.zarr/tables/table/obsm/.zgroup", - "sample1.zarr/tables/table/obsm/intensities", - "sample1.zarr/tables/table/obsm/intensities/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/.zgroup", - "sample1.zarr/tables/table/obsm/intensities/CD20", - "sample1.zarr/tables/table/obsm/intensities/CD20/.zarray", - "sample1.zarr/tables/table/obsm/intensities/CD20/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/CD20/0", - "sample1.zarr/tables/table/obsm/intensities/CD3", - "sample1.zarr/tables/table/obsm/intensities/CD3/.zarray", - "sample1.zarr/tables/table/obsm/intensities/CD3/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/CD3/0", - "sample1.zarr/tables/table/obsm/intensities/CK", - "sample1.zarr/tables/table/obsm/intensities/CK/.zarray", - "sample1.zarr/tables/table/obsm/intensities/CK/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/CK/0", - "sample1.zarr/tables/table/obsm/intensities/DAPI", - "sample1.zarr/tables/table/obsm/intensities/DAPI/.zarray", - "sample1.zarr/tables/table/obsm/intensities/DAPI/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/DAPI/0", - "sample1.zarr/tables/table/obsm/intensities/_index", - "sample1.zarr/tables/table/obsm/intensities/_index/.zarray", - "sample1.zarr/tables/table/obsm/intensities/_index/.zattrs", - "sample1.zarr/tables/table/obsm/intensities/_index/0", - "sample1.zarr/tables/table/obsm/spatial", - "sample1.zarr/tables/table/obsm/spatial/.zarray", - "sample1.zarr/tables/table/obsm/spatial/.zattrs", - "sample1.zarr/tables/table/obsm/spatial/0", - "sample1.zarr/tables/table/obsm/spatial/0/0", - "sample1.zarr/tables/table/obsp", - "sample1.zarr/tables/table/obsp/.zattrs", - "sample1.zarr/tables/table/obsp/.zgroup", - "sample1.zarr/tables/table/uns", - "sample1.zarr/tables/table/uns/.zattrs", - "sample1.zarr/tables/table/uns/.zgroup", - "sample1.zarr/tables/table/uns/sopa_attrs", - "sample1.zarr/tables/table/uns/sopa_attrs/.zattrs", - "sample1.zarr/tables/table/uns/sopa_attrs/.zgroup", - "sample1.zarr/tables/table/uns/sopa_attrs/intensities", - "sample1.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", - "sample1.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", - "sample1.zarr/tables/table/uns/sopa_attrs/intensities/0", - "sample1.zarr/tables/table/uns/sopa_attrs/transcripts", - "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", - "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", - "sample1.zarr/tables/table/uns/sopa_attrs/transcripts/0", - "sample1.zarr/tables/table/uns/spatialdata_attrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/.zattrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/.zgroup", - "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key", - "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", - "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region/0", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", - "sample1.zarr/tables/table/uns/spatialdata_attrs/region_key/0", - "sample1.zarr/tables/table/var", - "sample1.zarr/tables/table/var/.zattrs", - "sample1.zarr/tables/table/var/.zgroup", - "sample1.zarr/tables/table/var/Name", - "sample1.zarr/tables/table/var/Name/.zarray", - "sample1.zarr/tables/table/var/Name/.zattrs", - "sample1.zarr/tables/table/var/Name/0", - "sample1.zarr/tables/table/varm", - "sample1.zarr/tables/table/varm/.zattrs", - "sample1.zarr/tables/table/varm/.zgroup", - "sample1.zarr/tables/table/varp", - "sample1.zarr/tables/table/varp/.zattrs", - "sample1.zarr/tables/table/varp/.zgroup", - "sample1.zarr/zmetadata" + "sample_name.explorer", + "sample_name.explorer/adata.h5ad", + "sample_name.explorer/analysis.zarr.zip", + "sample_name.explorer/analysis_summary.html", + "sample_name.explorer/cell_feature_matrix.zarr.zip", + "sample_name.explorer/cells.zarr.zip", + "sample_name.explorer/experiment.xenium", + "sample_name.explorer/morphology.ome.tif", + "sample_name.explorer/transcripts.zarr.zip", + "sample_name.zarr", + "sample_name.zarr/.zattrs", + "sample_name.zarr/.zgroup", + "sample_name.zarr/images", + "sample_name.zarr/images/.zgroup", + "sample_name.zarr/images/he_image", + "sample_name.zarr/images/he_image/.zattrs", + "sample_name.zarr/images/he_image/.zgroup", + "sample_name.zarr/images/he_image/0", + "sample_name.zarr/images/he_image/0/.zarray", + "sample_name.zarr/images/he_image/0/0", + "sample_name.zarr/images/he_image/0/0/0", + "sample_name.zarr/images/he_image/0/0/0/0", + "sample_name.zarr/images/he_image/0/0/0/1", + "sample_name.zarr/images/he_image/0/0/0/2", + "sample_name.zarr/images/he_image/0/0/0/3", + "sample_name.zarr/images/he_image/0/0/1", + "sample_name.zarr/images/he_image/0/0/1/0", + "sample_name.zarr/images/he_image/0/0/1/1", + "sample_name.zarr/images/he_image/0/0/1/2", + "sample_name.zarr/images/he_image/0/0/1/3", + "sample_name.zarr/images/he_image/0/0/2", + "sample_name.zarr/images/he_image/0/0/2/0", + "sample_name.zarr/images/he_image/0/0/2/1", + "sample_name.zarr/images/he_image/0/0/2/2", + "sample_name.zarr/images/he_image/0/0/2/3", + "sample_name.zarr/images/he_image/0/0/3", + "sample_name.zarr/images/he_image/0/0/3/0", + "sample_name.zarr/images/he_image/0/0/3/1", + "sample_name.zarr/images/he_image/0/0/3/2", + "sample_name.zarr/images/he_image/0/0/3/3", + "sample_name.zarr/images/he_image/1", + "sample_name.zarr/images/he_image/1/.zarray", + "sample_name.zarr/images/he_image/1/0", + "sample_name.zarr/images/he_image/1/0/0", + "sample_name.zarr/images/he_image/1/0/0/0", + "sample_name.zarr/images/he_image/1/0/0/1", + "sample_name.zarr/images/he_image/1/0/1", + "sample_name.zarr/images/he_image/1/0/1/0", + "sample_name.zarr/images/he_image/1/0/1/1", + "sample_name.zarr/images/he_image/2", + "sample_name.zarr/images/he_image/2/.zarray", + "sample_name.zarr/images/he_image/2/0", + "sample_name.zarr/images/he_image/2/0/0", + "sample_name.zarr/images/he_image/2/0/0/0", + "sample_name.zarr/images/image", + "sample_name.zarr/images/image/.zattrs", + "sample_name.zarr/images/image/.zgroup", + "sample_name.zarr/images/image/0", + "sample_name.zarr/images/image/0/.zarray", + "sample_name.zarr/images/image/0/0", + "sample_name.zarr/images/image/0/0/0", + "sample_name.zarr/images/image/0/0/0/0", + "sample_name.zarr/images/image/0/0/0/1", + "sample_name.zarr/images/image/0/0/1", + "sample_name.zarr/images/image/0/0/1/0", + "sample_name.zarr/images/image/0/0/1/1", + "sample_name.zarr/images/image/0/1", + "sample_name.zarr/images/image/0/1/0", + "sample_name.zarr/images/image/0/1/0/0", + "sample_name.zarr/images/image/0/1/0/1", + "sample_name.zarr/images/image/0/1/1", + "sample_name.zarr/images/image/0/1/1/0", + "sample_name.zarr/images/image/0/1/1/1", + "sample_name.zarr/images/image/0/2", + "sample_name.zarr/images/image/0/2/0", + "sample_name.zarr/images/image/0/2/0/0", + "sample_name.zarr/images/image/0/2/0/1", + "sample_name.zarr/images/image/0/2/1", + "sample_name.zarr/images/image/0/2/1/0", + "sample_name.zarr/images/image/0/2/1/1", + "sample_name.zarr/images/image/0/3", + "sample_name.zarr/images/image/0/3/0", + "sample_name.zarr/images/image/0/3/0/0", + "sample_name.zarr/images/image/0/3/0/1", + "sample_name.zarr/images/image/0/3/1", + "sample_name.zarr/images/image/0/3/1/0", + "sample_name.zarr/images/image/0/3/1/1", + "sample_name.zarr/points", + "sample_name.zarr/points/.zgroup", + "sample_name.zarr/points/transcripts", + "sample_name.zarr/points/transcripts/.zattrs", + "sample_name.zarr/points/transcripts/.zgroup", + "sample_name.zarr/points/transcripts/points.parquet", + "sample_name.zarr/points/transcripts/points.parquet/part.0.parquet", + "sample_name.zarr/shapes", + "sample_name.zarr/shapes/.zgroup", + "sample_name.zarr/shapes/baysor_boundaries", + "sample_name.zarr/shapes/baysor_boundaries/.zattrs", + "sample_name.zarr/shapes/baysor_boundaries/.zgroup", + "sample_name.zarr/shapes/baysor_boundaries/shapes.parquet", + "sample_name.zarr/shapes/cells", + "sample_name.zarr/shapes/cells/.zattrs", + "sample_name.zarr/shapes/cells/.zgroup", + "sample_name.zarr/shapes/cells/shapes.parquet", + "sample_name.zarr/shapes/transcripts_patches", + "sample_name.zarr/shapes/transcripts_patches/.zattrs", + "sample_name.zarr/shapes/transcripts_patches/.zgroup", + "sample_name.zarr/shapes/transcripts_patches/shapes.parquet", + "sample_name.zarr/tables", + "sample_name.zarr/tables/.zgroup", + "sample_name.zarr/tables/table", + "sample_name.zarr/tables/table/.zattrs", + "sample_name.zarr/tables/table/.zgroup", + "sample_name.zarr/tables/table/X", + "sample_name.zarr/tables/table/X/.zattrs", + "sample_name.zarr/tables/table/X/.zgroup", + "sample_name.zarr/tables/table/X/data", + "sample_name.zarr/tables/table/X/data/.zarray", + "sample_name.zarr/tables/table/X/data/0", + "sample_name.zarr/tables/table/X/indices", + "sample_name.zarr/tables/table/X/indices/.zarray", + "sample_name.zarr/tables/table/X/indices/0", + "sample_name.zarr/tables/table/X/indptr", + "sample_name.zarr/tables/table/X/indptr/.zarray", + "sample_name.zarr/tables/table/X/indptr/0", + "sample_name.zarr/tables/table/layers", + "sample_name.zarr/tables/table/layers/.zattrs", + "sample_name.zarr/tables/table/layers/.zgroup", + "sample_name.zarr/tables/table/obs", + "sample_name.zarr/tables/table/obs/.zattrs", + "sample_name.zarr/tables/table/obs/.zgroup", + "sample_name.zarr/tables/table/obs/_index", + "sample_name.zarr/tables/table/obs/_index/.zarray", + "sample_name.zarr/tables/table/obs/_index/.zattrs", + "sample_name.zarr/tables/table/obs/_index/0", + "sample_name.zarr/tables/table/obs/area", + "sample_name.zarr/tables/table/obs/area/.zarray", + "sample_name.zarr/tables/table/obs/area/.zattrs", + "sample_name.zarr/tables/table/obs/area/0", + "sample_name.zarr/tables/table/obs/avg_assignment_confidence", + "sample_name.zarr/tables/table/obs/avg_assignment_confidence/.zarray", + "sample_name.zarr/tables/table/obs/avg_assignment_confidence/.zattrs", + "sample_name.zarr/tables/table/obs/avg_assignment_confidence/0", + "sample_name.zarr/tables/table/obs/avg_confidence", + "sample_name.zarr/tables/table/obs/avg_confidence/.zarray", + "sample_name.zarr/tables/table/obs/avg_confidence/.zattrs", + "sample_name.zarr/tables/table/obs/avg_confidence/0", + "sample_name.zarr/tables/table/obs/baysor_area", + "sample_name.zarr/tables/table/obs/baysor_area/.zarray", + "sample_name.zarr/tables/table/obs/baysor_area/.zattrs", + "sample_name.zarr/tables/table/obs/baysor_area/0", + "sample_name.zarr/tables/table/obs/cell_id", + "sample_name.zarr/tables/table/obs/cell_id/.zarray", + "sample_name.zarr/tables/table/obs/cell_id/.zattrs", + "sample_name.zarr/tables/table/obs/cell_id/0", + "sample_name.zarr/tables/table/obs/cluster", + "sample_name.zarr/tables/table/obs/cluster/.zarray", + "sample_name.zarr/tables/table/obs/cluster/.zattrs", + "sample_name.zarr/tables/table/obs/cluster/0", + "sample_name.zarr/tables/table/obs/density", + "sample_name.zarr/tables/table/obs/density/.zarray", + "sample_name.zarr/tables/table/obs/density/.zattrs", + "sample_name.zarr/tables/table/obs/density/0", + "sample_name.zarr/tables/table/obs/elongation", + "sample_name.zarr/tables/table/obs/elongation/.zarray", + "sample_name.zarr/tables/table/obs/elongation/.zattrs", + "sample_name.zarr/tables/table/obs/elongation/0", + "sample_name.zarr/tables/table/obs/lifespan", + "sample_name.zarr/tables/table/obs/lifespan/.zarray", + "sample_name.zarr/tables/table/obs/lifespan/.zattrs", + "sample_name.zarr/tables/table/obs/lifespan/0", + "sample_name.zarr/tables/table/obs/max_cluster_frac", + "sample_name.zarr/tables/table/obs/max_cluster_frac/.zarray", + "sample_name.zarr/tables/table/obs/max_cluster_frac/.zattrs", + "sample_name.zarr/tables/table/obs/max_cluster_frac/0", + "sample_name.zarr/tables/table/obs/n_transcripts", + "sample_name.zarr/tables/table/obs/n_transcripts/.zarray", + "sample_name.zarr/tables/table/obs/n_transcripts/.zattrs", + "sample_name.zarr/tables/table/obs/n_transcripts/0", + "sample_name.zarr/tables/table/obs/region", + "sample_name.zarr/tables/table/obs/region/.zattrs", + "sample_name.zarr/tables/table/obs/region/.zgroup", + "sample_name.zarr/tables/table/obs/region/categories", + "sample_name.zarr/tables/table/obs/region/categories/.zarray", + "sample_name.zarr/tables/table/obs/region/categories/.zattrs", + "sample_name.zarr/tables/table/obs/region/categories/0", + "sample_name.zarr/tables/table/obs/region/codes", + "sample_name.zarr/tables/table/obs/region/codes/.zarray", + "sample_name.zarr/tables/table/obs/region/codes/.zattrs", + "sample_name.zarr/tables/table/obs/region/codes/0", + "sample_name.zarr/tables/table/obs/slide", + "sample_name.zarr/tables/table/obs/slide/.zattrs", + "sample_name.zarr/tables/table/obs/slide/.zgroup", + "sample_name.zarr/tables/table/obs/slide/categories", + "sample_name.zarr/tables/table/obs/slide/categories/.zarray", + "sample_name.zarr/tables/table/obs/slide/categories/.zattrs", + "sample_name.zarr/tables/table/obs/slide/categories/0", + "sample_name.zarr/tables/table/obs/slide/codes", + "sample_name.zarr/tables/table/obs/slide/codes/.zarray", + "sample_name.zarr/tables/table/obs/slide/codes/.zattrs", + "sample_name.zarr/tables/table/obs/slide/codes/0", + "sample_name.zarr/tables/table/obs/x", + "sample_name.zarr/tables/table/obs/x/.zarray", + "sample_name.zarr/tables/table/obs/x/.zattrs", + "sample_name.zarr/tables/table/obs/x/0", + "sample_name.zarr/tables/table/obs/y", + "sample_name.zarr/tables/table/obs/y/.zarray", + "sample_name.zarr/tables/table/obs/y/.zattrs", + "sample_name.zarr/tables/table/obs/y/0", + "sample_name.zarr/tables/table/obsm", + "sample_name.zarr/tables/table/obsm/.zattrs", + "sample_name.zarr/tables/table/obsm/.zgroup", + "sample_name.zarr/tables/table/obsm/intensities", + "sample_name.zarr/tables/table/obsm/intensities/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/.zgroup", + "sample_name.zarr/tables/table/obsm/intensities/CD20", + "sample_name.zarr/tables/table/obsm/intensities/CD20/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/CD20/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/CD20/0", + "sample_name.zarr/tables/table/obsm/intensities/CD3", + "sample_name.zarr/tables/table/obsm/intensities/CD3/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/CD3/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/CD3/0", + "sample_name.zarr/tables/table/obsm/intensities/CK", + "sample_name.zarr/tables/table/obsm/intensities/CK/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/CK/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/CK/0", + "sample_name.zarr/tables/table/obsm/intensities/DAPI", + "sample_name.zarr/tables/table/obsm/intensities/DAPI/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/DAPI/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/DAPI/0", + "sample_name.zarr/tables/table/obsm/intensities/_index", + "sample_name.zarr/tables/table/obsm/intensities/_index/.zarray", + "sample_name.zarr/tables/table/obsm/intensities/_index/.zattrs", + "sample_name.zarr/tables/table/obsm/intensities/_index/0", + "sample_name.zarr/tables/table/obsm/spatial", + "sample_name.zarr/tables/table/obsm/spatial/.zarray", + "sample_name.zarr/tables/table/obsm/spatial/.zattrs", + "sample_name.zarr/tables/table/obsm/spatial/0", + "sample_name.zarr/tables/table/obsm/spatial/0/0", + "sample_name.zarr/tables/table/obsp", + "sample_name.zarr/tables/table/obsp/.zattrs", + "sample_name.zarr/tables/table/obsp/.zgroup", + "sample_name.zarr/tables/table/uns", + "sample_name.zarr/tables/table/uns/.zattrs", + "sample_name.zarr/tables/table/uns/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/0", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/0", + "sample_name.zarr/tables/table/var", + "sample_name.zarr/tables/table/var/.zattrs", + "sample_name.zarr/tables/table/var/.zgroup", + "sample_name.zarr/tables/table/var/Name", + "sample_name.zarr/tables/table/var/Name/.zarray", + "sample_name.zarr/tables/table/var/Name/.zattrs", + "sample_name.zarr/tables/table/var/Name/0", + "sample_name.zarr/tables/table/varm", + "sample_name.zarr/tables/table/varm/.zattrs", + "sample_name.zarr/tables/table/varm/.zgroup", + "sample_name.zarr/tables/table/varp", + "sample_name.zarr/tables/table/varp/.zattrs", + "sample_name.zarr/tables/table/varp/.zgroup", + "sample_name.zarr/zmetadata" ], [ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", diff --git a/tests/samplesheet.csv b/tests/samplesheet.csv index d45a3ad..e88d6f7 100644 --- a/tests/samplesheet.csv +++ b/tests/samplesheet.csv @@ -1,2 +1,2 @@ -data_path -https://github.com/nf-core/sopa/blob/dev/tests/README.md +sample,data_path +sample_name,https://github.com/nf-core/sopa/blob/dev/tests/README.md From 993b7afef1c0513c1c02627a1556aff576813e0d Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 23 Jul 2025 14:17:52 +0200 Subject: [PATCH 130/227] adding packages versions --- modules/local/baysor/main.nf | 7 +++++ modules/local/cellpose/main.nf | 7 +++++ modules/local/proseg/main.nf | 7 +++++ modules/local/sopa_core/main.nf | 9 +++++++ modules/local/stardist/main.nf | 7 +++++ workflows/sopa.nf | 47 ++++++++++++++++++++++++++------- 6 files changed, 75 insertions(+), 9 deletions(-) diff --git a/modules/local/baysor/main.nf b/modules/local/baysor/main.nf index fb74dfb..fad0e1d 100644 --- a/modules/local/baysor/main.nf +++ b/modules/local/baysor/main.nf @@ -37,11 +37,18 @@ process RESOLVE_BAYSOR { output: tuple val(meta), path(sdata_path) path "${sdata_path}/shapes/baysor_boundaries" + path "versions.yml" script: """ sopa resolve baysor ${sdata_path} ${cli_arguments} rm -r ${sdata_path}/.sopa_cache/transcript_patches || true # cleanup large baysor files + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sopa: \$(sopa --version) + baysor: \$(baysor --version) + END_VERSIONS """ } diff --git a/modules/local/cellpose/main.nf b/modules/local/cellpose/main.nf index 1519c4b..0bb0e7c 100644 --- a/modules/local/cellpose/main.nf +++ b/modules/local/cellpose/main.nf @@ -35,9 +35,16 @@ process RESOLVE_CELLPOSE { output: tuple val(meta), path(sdata_path) path "${sdata_path}/shapes/cellpose_boundaries" + path "versions.yml" script: """ sopa resolve cellpose ${sdata_path} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sopa: \$(sopa --version) + cellpose: \$(python -c "import cellpose; print(cellpose.version)" 2> /dev/null) + END_VERSIONS """ } diff --git a/modules/local/proseg/main.nf b/modules/local/proseg/main.nf index c8729d6..71d61c6 100644 --- a/modules/local/proseg/main.nf +++ b/modules/local/proseg/main.nf @@ -16,9 +16,16 @@ process PATCH_SEGMENTATION_PROSEG { output: tuple val(meta), path(sdata_path) path "${sdata_path}/shapes/proseg_boundaries" + path "versions.yml" script: """ sopa segmentation proseg ${sdata_path} ${cli_arguments} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sopa: \$(sopa --version) + proseg: \$(proseg --version | cut -d' ' -f2) + END_VERSIONS """ } diff --git a/modules/local/sopa_core/main.nf b/modules/local/sopa_core/main.nf index 224e792..f8c1201 100644 --- a/modules/local/sopa_core/main.nf +++ b/modules/local/sopa_core/main.nf @@ -14,10 +14,19 @@ process TO_SPATIALDATA { output: tuple val(meta), path("${meta.sdata_dir}") + path "versions.yml" script: """ sopa convert ${meta.data_dir} --sdata-path ${meta.sdata_dir} ${ArgsReaderCLI(args, meta)} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sopa: \$(sopa --version 2> /dev/null) + spatialdata: \$(python -c "import spatialdata; print(spatialdata.__version__)" 2> /dev/null) + spatialdata_io: \$(python -c "import spatialdata_io; print(spatialdata_io.__version__)" 2> /dev/null) + scanpy: \$(python -c "import scanpy; print(scanpy.__version__)" 2> /dev/null) + END_VERSIONS """ } diff --git a/modules/local/stardist/main.nf b/modules/local/stardist/main.nf index 0823017..9341991 100644 --- a/modules/local/stardist/main.nf +++ b/modules/local/stardist/main.nf @@ -35,9 +35,16 @@ process RESOLVE_STARDIST { output: tuple val(meta), path(sdata_path) path "${sdata_path}/shapes/stardist_boundaries" + path "versions.yml" script: """ sopa resolve stardist ${sdata_path} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sopa: \$(sopa --version) + stardist: \$(python -c "import stardist; print(stardist.__version__)" 2> /dev/null) + END_VERSIONS """ } diff --git a/workflows/sopa.nf b/workflows/sopa.nf index e2ba93a..1f09490 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -51,7 +51,8 @@ workflow SOPA { ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.data_dir] } } - ch_spatialdata = TO_SPATIALDATA(ch_input_spatialdata, config.read) + (ch_spatialdata, versions) = TO_SPATIALDATA(ch_input_spatialdata, config.read) + ch_versions = ch_versions.mix(versions) EXPLORER_RAW(ch_spatialdata, ArgsCLI(config.explorer)) @@ -64,26 +65,34 @@ workflow SOPA { if (config.segmentation.cellpose) { (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) - ch_resolved = CELLPOSE(ch_image_patches, config) + (ch_resolved, versions) = CELLPOSE(ch_image_patches, config) + + ch_versions = ch_versions.mix(versions) } if (config.segmentation.stardist) { (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) - ch_resolved = STARDIST(ch_image_patches, config) + (ch_resolved, versions) = STARDIST(ch_image_patches, config) + + ch_versions = ch_versions.mix(versions) } if (config.segmentation.baysor) { ch_input_baysor = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_baysor, transcriptPatchesArgs(config, "baysor")) - ch_resolved = BAYSOR(ch_transcripts_patches, config) + (ch_resolved, versions) = BAYSOR(ch_transcripts_patches, config) + + ch_versions = ch_versions.mix(versions) } if (config.segmentation.proseg) { ch_input_proseg = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, transcriptPatchesArgs(config, "proseg")) - ch_resolved = PROSEG(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, config) + (ch_resolved, versions) = PROSEG(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, config) + + ch_versions = ch_versions.mix(versions) } (ch_aggregated, _out) = AGGREGATE(ch_resolved, ArgsCLI(config.aggregate)) @@ -139,6 +148,8 @@ workflow CELLPOSE { config main: + ch_versions = Channel.empty() + cellpose_args = ArgsCLI(config.segmentation.cellpose) ch_patches @@ -148,10 +159,13 @@ workflow CELLPOSE { ch_segmented = PATCH_SEGMENTATION_CELLPOSE(ch_cellpose).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - (ch_resolved, _out) = RESOLVE_CELLPOSE(ch_segmented) + (ch_resolved, _out, versions) = RESOLVE_CELLPOSE(ch_segmented) + + ch_versions = ch_versions.mix(versions) emit: ch_resolved + ch_versions } workflow STARDIST { @@ -160,6 +174,8 @@ workflow STARDIST { config main: + ch_versions = Channel.empty() + stardist_args = ArgsCLI(config.segmentation.stardist) ch_patches @@ -169,10 +185,13 @@ workflow STARDIST { ch_segmented = PATCH_SEGMENTATION_STARDIST(ch_stardist).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - (ch_resolved, _out) = RESOLVE_STARDIST(ch_segmented) + (ch_resolved, _out, versions) = RESOLVE_STARDIST(ch_segmented) + + ch_versions = ch_versions.mix(versions) emit: ch_resolved + ch_versions } workflow PROSEG { @@ -181,12 +200,17 @@ workflow PROSEG { config main: + ch_versions = Channel.empty() + proseg_args = ArgsCLI(config.segmentation.proseg, null, ["command_line_suffix"]) - (ch_segmented, _out) = PATCH_SEGMENTATION_PROSEG(ch_patches, proseg_args) + (ch_segmented, _out, versions) = PATCH_SEGMENTATION_PROSEG(ch_patches, proseg_args) + + ch_versions = ch_versions.mix(versions) emit: ch_segmented + ch_versions } @@ -196,6 +220,8 @@ workflow BAYSOR { config main: + ch_versions = Channel.empty() + baysor_args = ArgsCLI(config.segmentation.baysor, null, ["config"]) ch_patches @@ -205,10 +231,13 @@ workflow BAYSOR { ch_segmented = PATCH_SEGMENTATION_BAYSOR(ch_baysor).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - (ch_resolved, _out) = RESOLVE_BAYSOR(ch_segmented, resolveArgs(config)) + (ch_resolved, _out, versions) = RESOLVE_BAYSOR(ch_segmented, resolveArgs(config)) + + ch_versions = ch_versions.mix(versions) emit: ch_resolved + ch_versions } def transcriptPatchesArgs(Map config, String method) { From ffe9aae282f8ddfcb7506bf9a90b9c1dce8e501b Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 23 Jul 2025 14:33:03 +0200 Subject: [PATCH 131/227] remove package versions from snapshot - as use latest --- tests/cellpose.nf.test | 2 -- tests/cellpose.nf.test.snap | 5 ----- tests/default.nf.test | 2 -- tests/default.nf.test.snap | 5 ----- tests/proseg.nf.test | 2 -- tests/proseg.nf.test.snap | 5 ----- 6 files changed, 21 deletions(-) diff --git a/tests/cellpose.nf.test b/tests/cellpose.nf.test index cca280a..7cb4c5e 100644 --- a/tests/cellpose.nf.test +++ b/tests/cellpose.nf.test @@ -22,8 +22,6 @@ nextflow_pipeline { { assert snapshot( // Number of successful tasks workflow.trace.succeeded().size(), - // pipeline versions.yml file for multiqc from which Nextflow version is removed because we test pipelines on multiple Nextflow versions - removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_mqc_versions.yml"), // All stable path name, with a relative path stable_name, // All files with stable contents diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 2cf727b..086509a 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -2,11 +2,6 @@ "-profile test_cellpose": { "content": [ 9, - { - "Workflow": { - "nf-core/sopa": "v1.0.0" - } - }, [ "pipeline_info", "pipeline_info/nf_core_sopa_software_mqc_versions.yml", diff --git a/tests/default.nf.test b/tests/default.nf.test index f428bc1..e15322d 100644 --- a/tests/default.nf.test +++ b/tests/default.nf.test @@ -22,8 +22,6 @@ nextflow_pipeline { { assert snapshot( // Number of successful tasks workflow.trace.succeeded().size(), - // pipeline versions.yml file for multiqc from which Nextflow version is removed because we test pipelines on multiple Nextflow versions - removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_mqc_versions.yml"), // All stable path name, with a relative path stable_name, // All files with stable contents diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index bbbccdf..edaf839 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -2,11 +2,6 @@ "-profile test": { "content": [ 9, - { - "Workflow": { - "nf-core/sopa": "v1.0.0" - } - }, [ "pipeline_info", "pipeline_info/nf_core_sopa_software_mqc_versions.yml", diff --git a/tests/proseg.nf.test b/tests/proseg.nf.test index f56753e..7298a7a 100644 --- a/tests/proseg.nf.test +++ b/tests/proseg.nf.test @@ -22,8 +22,6 @@ nextflow_pipeline { { assert snapshot( // Number of successful tasks workflow.trace.succeeded().size(), - // pipeline versions.yml file for multiqc from which Nextflow version is removed because we test pipelines on multiple Nextflow versions - removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_mqc_versions.yml"), // All stable path name, with a relative path stable_name, // All files with stable contents diff --git a/tests/proseg.nf.test.snap b/tests/proseg.nf.test.snap index 76bdffb..345ee44 100644 --- a/tests/proseg.nf.test.snap +++ b/tests/proseg.nf.test.snap @@ -2,11 +2,6 @@ "-profile test_proseg": { "content": [ 9, - { - "Workflow": { - "nf-core/sopa": "v1.0.0" - } - }, [ "pipeline_info", "pipeline_info/nf_core_sopa_software_mqc_versions.yml", From 712ea9f23a8893ad2e8d926ace4c1d40de02edb1 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 23 Jul 2025 14:54:45 +0200 Subject: [PATCH 132/227] back to versions in snapshot --- tests/cellpose.nf.test | 2 ++ tests/cellpose.nf.test.snap | 17 ++++++++++++++++- tests/default.nf.test | 2 ++ tests/default.nf.test.snap | 17 ++++++++++++++++- tests/proseg.nf.test | 2 ++ tests/proseg.nf.test.snap | 17 ++++++++++++++++- 6 files changed, 54 insertions(+), 3 deletions(-) diff --git a/tests/cellpose.nf.test b/tests/cellpose.nf.test index 7cb4c5e..cca280a 100644 --- a/tests/cellpose.nf.test +++ b/tests/cellpose.nf.test @@ -22,6 +22,8 @@ nextflow_pipeline { { assert snapshot( // Number of successful tasks workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we test pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_mqc_versions.yml"), // All stable path name, with a relative path stable_name, // All files with stable contents diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 086509a..86caabe 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -2,6 +2,21 @@ "-profile test_cellpose": { "content": [ 9, + { + "RESOLVE_BAYSOR": { + "sopa": "2.1.1", + "baysor": "0.7.1" + }, + "TO_SPATIALDATA": { + "sopa": "2.1.1", + "spatialdata": "0.4.0", + "spatialdata_io": "0.2.0", + "scanpy": "1.11.3" + }, + "Workflow": { + "nf-core/sopa": "v1.0.0" + } + }, [ "pipeline_info", "pipeline_info/nf_core_sopa_software_mqc_versions.yml", @@ -326,6 +341,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-16T10:30:21.097962" + "timestamp": "2025-07-23T14:43:29.525774" } } \ No newline at end of file diff --git a/tests/default.nf.test b/tests/default.nf.test index e15322d..f428bc1 100644 --- a/tests/default.nf.test +++ b/tests/default.nf.test @@ -22,6 +22,8 @@ nextflow_pipeline { { assert snapshot( // Number of successful tasks workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we test pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_mqc_versions.yml"), // All stable path name, with a relative path stable_name, // All files with stable contents diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index edaf839..2396399 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -2,6 +2,21 @@ "-profile test": { "content": [ 9, + { + "RESOLVE_BAYSOR": { + "sopa": "2.1.1", + "baysor": "0.7.1" + }, + "TO_SPATIALDATA": { + "sopa": "2.1.1", + "spatialdata": "0.4.0", + "spatialdata_io": "0.2.0", + "scanpy": "1.11.3" + }, + "Workflow": { + "nf-core/sopa": "v1.0.0" + } + }, [ "pipeline_info", "pipeline_info/nf_core_sopa_software_mqc_versions.yml", @@ -326,6 +341,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-16T10:31:56.790814" + "timestamp": "2025-07-23T14:44:44.09277" } } \ No newline at end of file diff --git a/tests/proseg.nf.test b/tests/proseg.nf.test index 7298a7a..f56753e 100644 --- a/tests/proseg.nf.test +++ b/tests/proseg.nf.test @@ -22,6 +22,8 @@ nextflow_pipeline { { assert snapshot( // Number of successful tasks workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we test pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_mqc_versions.yml"), // All stable path name, with a relative path stable_name, // All files with stable contents diff --git a/tests/proseg.nf.test.snap b/tests/proseg.nf.test.snap index 345ee44..a775ef9 100644 --- a/tests/proseg.nf.test.snap +++ b/tests/proseg.nf.test.snap @@ -2,6 +2,21 @@ "-profile test_proseg": { "content": [ 9, + { + "RESOLVE_BAYSOR": { + "sopa": "2.1.1", + "baysor": "0.7.1" + }, + "TO_SPATIALDATA": { + "sopa": "2.1.1", + "spatialdata": "0.4.0", + "spatialdata_io": "0.2.0", + "scanpy": "1.11.3" + }, + "Workflow": { + "nf-core/sopa": "v1.0.0" + } + }, [ "pipeline_info", "pipeline_info/nf_core_sopa_software_mqc_versions.yml", @@ -326,6 +341,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-16T10:33:01.720179" + "timestamp": "2025-07-23T14:45:57.514099" } } \ No newline at end of file From cca237f2db156c970f0c2327c06cdf364424ec62 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 23 Jul 2025 15:44:12 +0200 Subject: [PATCH 133/227] use -params-file instead -f --configfile --- README.md | 4 +- conf/test.config | 36 ++++++++++- docs/usage.md | 8 +-- main.nf | 7 +-- modules/local/utils.nf | 59 +------------------ nextflow.config | 7 ++- nextflow_schema.json | 50 ++++++++++++---- .../local/utils_nfcore_sopa_pipeline/main.nf | 46 +++++++++++++++ workflows/sopa.nf | 49 +++++++-------- 9 files changed, 159 insertions(+), 107 deletions(-) diff --git a/README.md b/README.md index c867895..0d7a20a 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ SAMPLE2,/path/to/one/merscope_directory > [!WARNING] > If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters). -Then, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `--configfile` argument. +Then, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument. Now, you can run the pipeline using: @@ -62,7 +62,7 @@ Now, you can run the pipeline using: nextflow run nf-core/sopa \ -profile \ --input samplesheet.csv \ - --configfile \ + -params-file \ --outdir ``` diff --git a/conf/test.config b/conf/test.config index 70e1697..99296a1 100644 --- a/conf/test.config +++ b/conf/test.config @@ -24,5 +24,39 @@ params { // Input data input = "${baseDir}/tests/samplesheet.csv" - configfile = "https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/toy/baysor.yaml" + + read.technology = "toy_dataset" + + patchify.patch_width_pixel = 1200 + patchify.patch_overlap_pixel = 50 + patchify.patch_width_microns = 400 + patchify.patch_overlap_microns = 20 + + segmentation.baysor.min_area = 10 + + segmentation.baysor.config.data.force_2d = true + segmentation.baysor.config.data.min_molecules_per_cell = 10 + segmentation.baysor.config.data.x = "x" + segmentation.baysor.config.data.y = "y" + segmentation.baysor.config.data.z = "z" + segmentation.baysor.config.data.gene = "genes" + segmentation.baysor.config.data.min_molecules_per_gene = 0 + segmentation.baysor.config.data.min_molecules_per_segment = 3 + segmentation.baysor.config.data.confidence_nn_id = 6 + segmentation.baysor.config.segmentation.scale = 3 + segmentation.baysor.config.segmentation.scale_std = "25%" + segmentation.baysor.config.segmentation.prior_segmentation_confidence = 0 + segmentation.baysor.config.segmentation.estimate_scale_from_centers = false + segmentation.baysor.config.segmentation.n_clusters = 4 + segmentation.baysor.config.segmentation.iters = 500 + segmentation.baysor.config.segmentation.n_cells_init = 0 + segmentation.baysor.config.segmentation.nuclei_genes = "" + segmentation.baysor.config.segmentation.cyto_genes = "" + + aggregate.aggregate_channels = true + aggregate.min_transcripts = 5 + + explorer.gene_column = "genes" + explorer.ram_threshold_gb = 4 + explorer.pixel_size = 0.1 } diff --git a/docs/usage.md b/docs/usage.md index 96e7140..03b888c 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -40,20 +40,20 @@ The above samplesheet is made for [this public sample](https://www.10xgenomics.c ## Sopa config file -You'll also need to choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `--configfile` argument. +You'll also need to choose a Sopa config file (a.k.a. `-params-file` in Nextflow). You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument. For instance, if you have Xenium data and want to run Sopa with `proseg`, you can use: ``` ---configfile https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/xenium/proseg.yaml +--params-file https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/xenium/proseg.yaml ``` ## Running the pipeline -Once you have defined your samplesheet and `configfile`, you'll be able to run `nf-core/sopa`. The typical command for running the pipeline is as follows: +Once you have defined your samplesheet and `params-file`, you'll be able to run `nf-core/sopa`. The typical command for running the pipeline is as follows: ```bash -nextflow run nf-core/sopa --configfile --input ./samplesheet.csv --outdir ./results -profile docker +nextflow run nf-core/sopa -params-file --input ./samplesheet.csv --outdir ./results -profile docker ``` > [!NOTE] diff --git a/main.nf b/main.nf index e09be6e..566232f 100644 --- a/main.nf +++ b/main.nf @@ -41,8 +41,7 @@ workflow { // WORKFLOW: Run main workflow // NFCORE_SOPA( - PIPELINE_INITIALISATION.out.samplesheet, - params.configfile, + PIPELINE_INITIALISATION.out.samplesheet ) // // SUBWORKFLOW: Run completion tasks @@ -68,7 +67,6 @@ workflow { workflow NFCORE_SOPA { take: samplesheet // channel: samplesheet read in from --input - configfile main: @@ -76,7 +74,6 @@ workflow NFCORE_SOPA { // WORKFLOW: Run pipeline // SOPA( - samplesheet, - configfile, + samplesheet ) } diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 2512ddf..68a9b29 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -35,6 +35,8 @@ def stringifyValueForCli(value) { } def ArgsCLI(Map params, String contains = null, List keys = null) { + params = params ?: [:] + return params .findAll { key, _value -> (contains == null || key.contains(contains)) && (keys == null || key in keys) @@ -62,21 +64,6 @@ def ArgsReaderCLI(Map args, Map meta) { return ArgsCLI(args) } -def readConfigFile(String configfile) { - def reader - - if (configfile ==~ /^https?:\/\/.*/) { - reader = new InputStreamReader(new URL(configfile).openStream()) - } - else { - reader = new File(configfile).newReader() - } - - def config = new groovy.yaml.YamlSlurper().parse(reader) - - return validate(config) -} - def deepCopyCollection(object) { if (object instanceof Map) { object.collectEntries { key, value -> @@ -92,45 +79,3 @@ def deepCopyCollection(object) { object } } - - -def validate(Map config) { - def TRANSCRIPT_BASED_METHODS = ['proseg', 'baysor', 'comseg'] - def STAINING_BASED_METHODS = ['stardist', 'cellpose'] - - // top-level checks - assert config.read instanceof Map && config.read.containsKey('technology') : "Provide a 'read.technology' key" - assert config.containsKey('segmentation') : "Provide a 'segmentation' section" - - // backward compatibility - TRANSCRIPT_BASED_METHODS.each { m -> - if (config.segmentation?.get(m)?.containsKey('cell_key')) { - println("Deprecated 'cell_key' → using 'prior_shapes_key' instead.") - config.segmentation[m].prior_shapes_key = config.segmentation[m].cell_key - config.segmentation[m].remove('cell_key') - } - } - if (config.aggregate?.containsKey('average_intensities')) { - println("Deprecated 'average_intensities' → using 'aggregate_channels' instead.") - config.aggregate.aggregate_channels = config.aggregate.average_intensities - config.aggregate.remove('average_intensities') - } - - // check segmentation methods - assert config.segmentation : "Provide at least one segmentation method" - assert TRANSCRIPT_BASED_METHODS.count { config.segmentation.containsKey(it) } <= 1 : "Only one of ${TRANSCRIPT_BASED_METHODS} may be used" - assert STAINING_BASED_METHODS.count { config.segmentation.containsKey(it) } <= 1 : "Only one of ${STAINING_BASED_METHODS} may be used" - if (config.segmentation.containsKey('stardist')) { - assert TRANSCRIPT_BASED_METHODS.every { !config.segmentation.containsKey(it) } : "'stardist' cannot be combined with transcript-based methods" - } - - // check prior shapes key - TRANSCRIPT_BASED_METHODS.each { m -> - if (config.segmentation.containsKey(m) && config.segmentation.containsKey('cellpose')) { - config.segmentation[m].prior_shapes_key = 'cellpose_boundaries' - } - } - - - return config -} diff --git a/nextflow.config b/nextflow.config index adbe300..0315d8f 100644 --- a/nextflow.config +++ b/nextflow.config @@ -11,7 +11,12 @@ params { // Input options input = null - configfile = null + read = null + segmentation = null + patchify = null + aggregate = null + annotation = null + explorer = null // Spaceranger options spaceranger_reference = "https://cf.10xgenomics.com/supp/spatial-exp/refdata-gex-GRCh38-2020-A.tar.gz" diff --git a/nextflow_schema.json b/nextflow_schema.json index a041553..4ad863b 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -10,7 +10,7 @@ "type": "object", "fa_icon": "fas fa-terminal", "description": "Define where the pipeline should find input data and save output data.", - "required": ["input", "outdir", "configfile"], + "required": ["input", "outdir"], "properties": { "input": { "type": "string", @@ -23,15 +23,6 @@ "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row. See [usage docs](https://nf-co.re/sopa/usage#samplesheet-input).", "fa_icon": "fas fa-file-csv" }, - "configfile": { - "type": "string", - "format": "file-path", - "exists": true, - "pattern": "^\\S+\\.yaml$", - "description": "Path to a Sopa config file describing the technology used and the pipeline parameters.", - "help_text": "Choose one existing config file amont public one: https://github.com/gustaveroussy/sopa/tree/main/workflow/config", - "fa_icon": "fas fa-file" - }, "outdir": { "type": "string", "format": "directory-path", @@ -47,6 +38,45 @@ } } }, + "sopa_config": { + "title": "Sopa config (a.k.a. params file)", + "type": "object", + "fa_icon": "fas fa-rocket", + "description": "Parameters related to Sopa", + "required": ["read", "segmentation"], + "properties": { + "read": { + "type": "object", + "description": "Dictionary of parameters to read the raw spatial inputs, e.g., technology name. See https://github.com/gustaveroussy/sopa/blob/main/workflow/config/example_commented.yaml", + "fa_icon": "fas fa-cog" + }, + "segmentation": { + "type": "object", + "description": "Dictionary of segmentation parameters. See https://github.com/gustaveroussy/sopa/blob/main/workflow/config/example_commented.yaml", + "fa_icon": "fas fa-cog" + }, + "patchify": { + "type": "object", + "description": "Dictionary of patches parameters. See https://github.com/gustaveroussy/sopa/blob/main/workflow/config/example_commented.yaml", + "fa_icon": "fas fa-cog" + }, + "aggregate": { + "type": "object", + "description": "Dictionary of aggregation parameters. See https://github.com/gustaveroussy/sopa/blob/main/workflow/config/example_commented.yaml", + "fa_icon": "fas fa-cog" + }, + "annotation": { + "type": "object", + "description": "Dictionary of annotation parameters. See https://github.com/gustaveroussy/sopa/blob/main/workflow/config/example_commented.yaml", + "fa_icon": "fas fa-cog" + }, + "explorer": { + "type": "object", + "description": "Dictionary of Xenium Explorer parameters. See https://github.com/gustaveroussy/sopa/blob/main/workflow/config/example_commented.yaml", + "fa_icon": "fas fa-cog" + } + } + }, "spaceranger_options": { "title": "Space Ranger options", "type": "object", diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index e62c2d2..c24d2db 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -101,6 +101,11 @@ workflow PIPELINE_INITIALISATION { } .set { ch_samplesheet } + // + // Sopa params validation + // + validateParams(params) + emit: samplesheet = ch_samplesheet versions = ch_versions @@ -230,3 +235,44 @@ def methodsDescriptionText(mqc_methods_yaml) { return description_html.toString() } + +def validateParams(params) { + def TRANSCRIPT_BASED_METHODS = ['proseg', 'baysor', 'comseg'] + def STAINING_BASED_METHODS = ['stardist', 'cellpose'] + + // top-level checks + assert params.read instanceof Map && params.read.containsKey('technology') : "Provide a 'read.technology' key" + assert params.containsKey('segmentation') : "Provide a 'segmentation' section" + + // backward compatibility + TRANSCRIPT_BASED_METHODS.each { m -> + if (params.segmentation?.get(m)?.containsKey('cell_key')) { + println("Deprecated 'cell_key' → using 'prior_shapes_key' instead.") + params.segmentation[m].prior_shapes_key = params.segmentation[m].cell_key + params.segmentation[m].remove('cell_key') + } + } + if (params.aggregate?.containsKey('average_intensities')) { + println("Deprecated 'average_intensities' → using 'aggregate_channels' instead.") + params.aggregate.aggregate_channels = params.aggregate.average_intensities + params.aggregate.remove('average_intensities') + } + + // check segmentation methods + assert params.segmentation : "Provide at least one segmentation method" + assert TRANSCRIPT_BASED_METHODS.count { params.segmentation.containsKey(it) } <= 1 : "Only one of ${TRANSCRIPT_BASED_METHODS} may be used" + assert STAINING_BASED_METHODS.count { params.segmentation.containsKey(it) } <= 1 : "Only one of ${STAINING_BASED_METHODS} may be used" + if (params.segmentation.containsKey('stardist')) { + assert TRANSCRIPT_BASED_METHODS.every { !params.segmentation.containsKey(it) } : "'stardist' cannot be combined with transcript-based methods" + } + + // check prior shapes key + TRANSCRIPT_BASED_METHODS.each { m -> + if (params.segmentation.containsKey(m) && params.segmentation.containsKey('cellpose')) { + params.segmentation[m].prior_shapes_key = 'cellpose_boundaries' + } + } + + + return params +} diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 1f09490..d537bc8 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -20,9 +20,7 @@ include { EXPLORER_RAW ; REPORT } from '../modules/local/sopa_core' -include { readConfigFile } from '../modules/local/utils' -include { ArgsCLI } from '../modules/local/utils' -include { ArgsReaderCLI } from '../modules/local/utils' +include { ArgsCLI ; ArgsReaderCLI } from '../modules/local/utils' include { SPACERANGER } from '../subworkflows/local/spaceranger' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -33,15 +31,12 @@ include { SPACERANGER } from '../subworkflows/local/spaceranger' workflow SOPA { take: ch_samplesheet // channel: samplesheet read in from --input - configfile // sopa configfile from --configfile main: ch_versions = Channel.empty() - def config = readConfigFile(configfile) - - if (config.read.technology == "visium_hd") { + if (params.read.technology == "visium_hd") { (ch_input_spatialdata, versions) = SPACERANGER(ch_samplesheet) ch_input_spatialdata = ch_input_spatialdata.map { meta, out -> [meta, [out[0].toString().replaceFirst(/(.*?outs).*/, '$1'), meta.image]] } @@ -51,53 +46,53 @@ workflow SOPA { ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.data_dir] } } - (ch_spatialdata, versions) = TO_SPATIALDATA(ch_input_spatialdata, config.read) + (ch_spatialdata, versions) = TO_SPATIALDATA(ch_input_spatialdata, params.read) ch_versions = ch_versions.mix(versions) - EXPLORER_RAW(ch_spatialdata, ArgsCLI(config.explorer)) + EXPLORER_RAW(ch_spatialdata, ArgsCLI(params.explorer)) - if (config.segmentation.tissue) { - (ch_tissue_seg, _out) = TISSUE_SEGMENTATION(ch_spatialdata, ArgsCLI(config.segmentation.tissue)) + if (params.segmentation.tissue) { + (ch_tissue_seg, _out) = TISSUE_SEGMENTATION(ch_spatialdata, ArgsCLI(params.segmentation.tissue)) } else { ch_tissue_seg = ch_spatialdata } - if (config.segmentation.cellpose) { - (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) - (ch_resolved, versions) = CELLPOSE(ch_image_patches, config) + if (params.segmentation.cellpose) { + (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(params.patchify, "pixel")) + (ch_resolved, versions) = CELLPOSE(ch_image_patches, params) ch_versions = ch_versions.mix(versions) } - if (config.segmentation.stardist) { - (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(config.patchify, "pixel")) - (ch_resolved, versions) = STARDIST(ch_image_patches, config) + if (params.segmentation.stardist) { + (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(params.patchify, "pixel")) + (ch_resolved, versions) = STARDIST(ch_image_patches, params) ch_versions = ch_versions.mix(versions) } - if (config.segmentation.baysor) { - ch_input_baysor = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg + if (params.segmentation.baysor) { + ch_input_baysor = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg - ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_baysor, transcriptPatchesArgs(config, "baysor")) - (ch_resolved, versions) = BAYSOR(ch_transcripts_patches, config) + ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_baysor, transcriptPatchesArgs(params, "baysor")) + (ch_resolved, versions) = BAYSOR(ch_transcripts_patches, params) ch_versions = ch_versions.mix(versions) } - if (config.segmentation.proseg) { - ch_input_proseg = config.segmentation.cellpose ? ch_resolved : ch_tissue_seg + if (params.segmentation.proseg) { + ch_input_proseg = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg - ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, transcriptPatchesArgs(config, "proseg")) - (ch_resolved, versions) = PROSEG(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, config) + ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, transcriptPatchesArgs(params, "proseg")) + (ch_resolved, versions) = PROSEG(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, params) ch_versions = ch_versions.mix(versions) } - (ch_aggregated, _out) = AGGREGATE(ch_resolved, ArgsCLI(config.aggregate)) + (ch_aggregated, _out) = AGGREGATE(ch_resolved, ArgsCLI(params.aggregate)) - EXPLORER(ch_aggregated, ArgsCLI(config.explorer)) + EXPLORER(ch_aggregated, ArgsCLI(params.explorer)) REPORT(ch_aggregated) PUBLISH(ch_aggregated.map { it[1] }) From c020f2a6460c04a163eddac14f06a8d56040b02b Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 23 Jul 2025 17:25:41 +0200 Subject: [PATCH 134/227] add sopa_config in allOf --- nextflow_schema.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nextflow_schema.json b/nextflow_schema.json index 4ad863b..e3e3764 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -227,6 +227,9 @@ { "$ref": "#/$defs/input_output_options" }, + { + "$ref": "#/$defs/sopa_config" + }, { "$ref": "#/$defs/spaceranger_options" }, From dfb21d09610b32121f0f18c45cb07a37ce46029f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 23 Jul 2025 17:27:23 +0200 Subject: [PATCH 135/227] fix ro-crate file --- ro-crate-metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 9e941a1..43237f1 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "Stable", "datePublished": "2025-07-22T07:34:52+00:00", - "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n

    \n \"sopa_overview\"\n

    \n\n0. (Visium HD only) Raw data processing with Space Ranger\n1. (Optional) Tissue segmentation\n2. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n3. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n4. (Optional) Cell-type annotation **_- coming soon_**\n5. User-friendly output creation for visualization and quick analysis\n6. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://gustaveroussy.github.io/sopa/).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `--configfile` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n --configfile \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n

    \n \"sopa_overview\"\n

    \n\n0. (Visium HD only) Raw data processing with Space Ranger\n1. (Optional) Tissue segmentation\n2. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n3. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n4. (Optional) Cell-type annotation **_- coming soon_**\n5. User-friendly output creation for visualization and quick analysis\n6. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://gustaveroussy.github.io/sopa/).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n -params-file \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" From 3e225a68f58312976d4b5fd410c756a6594483e4 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 23 Jul 2025 18:26:30 +0200 Subject: [PATCH 136/227] update nextflow schema --- conf/test.config | 3 -- conf/test_cellpose.config | 19 ++++++- conf/test_full.config | 20 ------- conf/test_proseg.config | 15 +++++- nextflow_schema.json | 110 +++++++++++++++++++++++++++++++++----- 5 files changed, 130 insertions(+), 37 deletions(-) delete mode 100644 conf/test_full.config diff --git a/conf/test.config b/conf/test.config index 99296a1..01ca4e6 100644 --- a/conf/test.config +++ b/conf/test.config @@ -27,8 +27,6 @@ params { read.technology = "toy_dataset" - patchify.patch_width_pixel = 1200 - patchify.patch_overlap_pixel = 50 patchify.patch_width_microns = 400 patchify.patch_overlap_microns = 20 @@ -56,7 +54,6 @@ params { aggregate.aggregate_channels = true aggregate.min_transcripts = 5 - explorer.gene_column = "genes" explorer.ram_threshold_gb = 4 explorer.pixel_size = 0.1 } diff --git a/conf/test_cellpose.config b/conf/test_cellpose.config index 1d9f71e..4a39c97 100644 --- a/conf/test_cellpose.config +++ b/conf/test_cellpose.config @@ -24,5 +24,22 @@ params { // Input data input = "${baseDir}/tests/samplesheet.csv" - configfile = "https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/toy/cellpose.yaml" + + read.technology = "toy_dataset" + + patchify.patch_width_pixel = 1200 + patchify.patch_overlap_pixel = 50 + patchify.patch_width_microns = 3000 + patchify.patch_overlap_microns = 40 + + segmentation.cellpose.diameter = 35 + segmentation.cellpose.channels = ["DAPI"] + segmentation.cellpose.flow_threshold = 2 + segmentation.cellpose.cellprob_threshold = -6 + segmentation.cellpose.min_area = 2500 + + aggregate.aggregate_channels = true + + explorer.ram_threshold_gb = 4 + explorer.pixel_size = 0.1 } diff --git a/conf/test_full.config b/conf/test_full.config deleted file mode 100644 index f86d576..0000000 --- a/conf/test_full.config +++ /dev/null @@ -1,20 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Nextflow config file for running full-size tests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Defines input files and everything required to run a full size pipeline test. - - Use as follows: - nextflow run nf-core/sopa -profile test_full, --outdir - ----------------------------------------------------------------------------------------- -*/ - -params { - config_profile_name = 'Full test profile' - config_profile_description = 'Full test dataset to check pipeline function' - - // Input data for full size test - input = "${baseDir}/tests/samplesheet.csv" - configfile = "${baseDir}/tests/config/baysor.yaml" -} diff --git a/conf/test_proseg.config b/conf/test_proseg.config index fd5c7d7..ae6dd61 100644 --- a/conf/test_proseg.config +++ b/conf/test_proseg.config @@ -24,5 +24,18 @@ params { // Input data input = "${baseDir}/tests/samplesheet.csv" - configfile = "https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/toy/proseg.yaml" + + read.technology = "toy_dataset" + read.kwargs.genes = 500 + + patchify.patch_width_microns = -1 + patchify.patch_overlap_microns = 0 + + segmentation.proseg.prior_shapes_key = "auto" + + aggregate.aggregate_channels = true + aggregate.min_transcripts = 5 + + explorer.ram_threshold_gb = 4 + explorer.pixel_size = 0.1 } diff --git a/nextflow_schema.json b/nextflow_schema.json index e3e3764..e14c4f1 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -47,33 +47,119 @@ "properties": { "read": { "type": "object", - "description": "Dictionary of parameters to read the raw spatial inputs, e.g., technology name. See https://github.com/gustaveroussy/sopa/blob/main/workflow/config/example_commented.yaml", - "fa_icon": "fas fa-cog" + "required": ["technology"], + "properties": { + "technology": { + "type": "string", + "description": "Technology used for the spatial data, e.g., 'xenium', 'merscope', ...", + "fa_icon": "fas fa-microscope" + }, + "kwargs": { + "type": "object", + "additionalProperties": true, + "fa_icon": "fas fa-gear" + } + }, + "additionalProperties": true, + "description": "Dictionary of parameters to read the raw spatial inputs, e.g., technology name.", + "fa_icon": "fas fa-gear" }, "segmentation": { "type": "object", - "description": "Dictionary of segmentation parameters. See https://github.com/gustaveroussy/sopa/blob/main/workflow/config/example_commented.yaml", - "fa_icon": "fas fa-cog" + "properties": { + "tissue": { + "type": "object", + "additionalProperties": true, + "description": "Dictionary of tissue segmentation parameters.", + "fa_icon": "fas fa-gear" + }, + "baysor": { + "type": "object", + "properties": { + "config": { + "type": "object", + "properties": { + "data": { + "type": "object", + "description": "Baysor config: data section.", + "fa_icon": "fas fa-gear", + "additionalProperties": true + }, + "segmentation": { + "type": "object", + "description": "Baysor config: segmentation section.", + "fa_icon": "fas fa-gear", + "additionalProperties": true + } + }, + "description": "Baysor configuration parameters.", + "fa_icon": "fas fa-gear" + } + }, + "additionalProperties": true, + "description": "Dictionary of Baysor parameters." + }, + "cellpose": { + "type": "object", + "additionalProperties": true, + "description": "Dictionary of Cellpose parameters.", + "fa_icon": "fas fa-gear" + }, + "stardist": { + "type": "object", + "additionalProperties": true, + "description": "Dictionary of Stardist parameters.", + "fa_icon": "fas fa-gear" + }, + "proseg": { + "type": "object", + "additionalProperties": true, + "description": "Dictionary of Proseg parameters.", + "fa_icon": "fas fa-gear" + } + }, + "additionalProperties": true, + "description": "Dictionary of segmentation parameters.", + "fa_icon": "fas fa-gear" }, "patchify": { "type": "object", - "description": "Dictionary of patches parameters. See https://github.com/gustaveroussy/sopa/blob/main/workflow/config/example_commented.yaml", - "fa_icon": "fas fa-cog" + "additionalProperties": true, + "description": "Dictionary of patches parameters.", + "fa_icon": "fas fa-gear" }, "aggregate": { "type": "object", - "description": "Dictionary of aggregation parameters. See https://github.com/gustaveroussy/sopa/blob/main/workflow/config/example_commented.yaml", - "fa_icon": "fas fa-cog" + "additionalProperties": true, + "description": "Dictionary of aggregation parameters.", + "fa_icon": "fas fa-gear" }, "annotation": { "type": "object", - "description": "Dictionary of annotation parameters. See https://github.com/gustaveroussy/sopa/blob/main/workflow/config/example_commented.yaml", - "fa_icon": "fas fa-cog" + "required": ["method", "args"], + "properties": { + "method": { + "type": "string", + "description": "Cell type annotation method, either 'tangram' or 'fluorescence'", + "enum": ["tangram", "fluorescence"], + "fa_icon": "fas fa-gear" + }, + "args": { + "type": "object", + "description": "Cell type annotation arguments", + "fa_icon": "fas fa-gear", + "additionalProperties": true + } + }, + "additionalProperties": true, + "description": "Dictionary of annotation parameters.", + "fa_icon": "fas fa-gear" }, "explorer": { "type": "object", - "description": "Dictionary of Xenium Explorer parameters. See https://github.com/gustaveroussy/sopa/blob/main/workflow/config/example_commented.yaml", - "fa_icon": "fas fa-cog" + "additionalProperties": true, + "description": "Dictionary of Xenium Explorer parameters.", + "fa_icon": "fas fa-gear" } } }, From 6e749e9e0300262559c0c07c6bf26631331ebc8a Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 09:03:13 +0200 Subject: [PATCH 137/227] add test full config back --- conf/test_full.config | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 conf/test_full.config diff --git a/conf/test_full.config b/conf/test_full.config new file mode 100644 index 0000000..e582bbd --- /dev/null +++ b/conf/test_full.config @@ -0,0 +1,33 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running full-size tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a full size pipeline test. + + Use as follows: + nextflow run nf-core/sopa -profile test_full, --outdir + +---------------------------------------------------------------------------------------- +*/ + +params { + config_profile_name = 'Full test profile' + config_profile_description = 'Full test dataset to check pipeline function' + + // Input data + input = "${baseDir}/tests/samplesheet.csv" + + read.technology = "toy_dataset" + read.kwargs.genes = 500 + + patchify.patch_width_microns = -1 + patchify.patch_overlap_microns = 0 + + segmentation.proseg.prior_shapes_key = "auto" + + aggregate.aggregate_channels = true + aggregate.min_transcripts = 5 + + explorer.ram_threshold_gb = 4 + explorer.pixel_size = 0.1 +} From bcb62aa2b80ced8d3d74488854e4d0ef77875954 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 12:05:08 +0200 Subject: [PATCH 138/227] update config profiles --- conf/test.config | 56 ++++++++++++++------------------ conf/test_baysor.config | 67 +++++++++++++++++++++++++++++++++++++++ conf/test_cellpose.config | 26 ++++++++------- conf/test_full.config | 29 +++++++++++------ conf/test_proseg.config | 41 ------------------------ nextflow.config | 2 +- 6 files changed, 127 insertions(+), 94 deletions(-) create mode 100644 conf/test_baysor.config delete mode 100644 conf/test_proseg.config diff --git a/conf/test.config b/conf/test.config index 01ca4e6..2c398ed 100644 --- a/conf/test.config +++ b/conf/test.config @@ -19,41 +19,33 @@ process { } params { - config_profile_name = 'Test profile' + config_profile_name = 'Test profile with Proseg' config_profile_description = 'Minimal test dataset to check pipeline function' // Input data input = "${baseDir}/tests/samplesheet.csv" - read.technology = "toy_dataset" - - patchify.patch_width_microns = 400 - patchify.patch_overlap_microns = 20 - - segmentation.baysor.min_area = 10 - - segmentation.baysor.config.data.force_2d = true - segmentation.baysor.config.data.min_molecules_per_cell = 10 - segmentation.baysor.config.data.x = "x" - segmentation.baysor.config.data.y = "y" - segmentation.baysor.config.data.z = "z" - segmentation.baysor.config.data.gene = "genes" - segmentation.baysor.config.data.min_molecules_per_gene = 0 - segmentation.baysor.config.data.min_molecules_per_segment = 3 - segmentation.baysor.config.data.confidence_nn_id = 6 - segmentation.baysor.config.segmentation.scale = 3 - segmentation.baysor.config.segmentation.scale_std = "25%" - segmentation.baysor.config.segmentation.prior_segmentation_confidence = 0 - segmentation.baysor.config.segmentation.estimate_scale_from_centers = false - segmentation.baysor.config.segmentation.n_clusters = 4 - segmentation.baysor.config.segmentation.iters = 500 - segmentation.baysor.config.segmentation.n_cells_init = 0 - segmentation.baysor.config.segmentation.nuclei_genes = "" - segmentation.baysor.config.segmentation.cyto_genes = "" - - aggregate.aggregate_channels = true - aggregate.min_transcripts = 5 - - explorer.ram_threshold_gb = 4 - explorer.pixel_size = 0.1 + read = [ + technology: "toy_dataset", + kwargs: [ + genes: 500 + ], + ] + + patchify = [ + patch_width_microns: 400, + patch_overlap_microns: 20, + ] + + segmentation.proseg.prior_shapes_key = "auto" + + aggregate = [ + aggregate_channels: true, + min_transcripts: 5, + ] + + explorer = [ + ram_threshold_gb: 4, + pixel_size: 0.1, + ] } diff --git a/conf/test_baysor.config b/conf/test_baysor.config new file mode 100644 index 0000000..c125885 --- /dev/null +++ b/conf/test_baysor.config @@ -0,0 +1,67 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/sopa -profile test, --outdir + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h', + ] +} + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Input data + input = "${baseDir}/tests/samplesheet.csv" + + read.technology = "toy_dataset" + + + patchify = [ + patch_width_microns: 400, + patch_overlap_microns: 20, + ] + + segmentation.baysor = [ + min_area: 10, + config: [ + data: [ + force_2d: true, + min_molecules_per_cell: 10, + x: "x", + y: "y", + z: "z", + gene: "genes", + min_molecules_per_gene: 0, + min_molecules_per_segment: 3, + confidence_nn_id: 6, + ], + segmentation: [ + scale: 3, + scale_std: "25%", + prior_segmentation_confidence: 0, + ], + ], + ] + + aggregate = [ + aggregate_channels: true, + min_transcripts: 5, + ] + + explorer = [ + ram_threshold_gb: 4, + pixel_size: 0.1, + ] +} diff --git a/conf/test_cellpose.config b/conf/test_cellpose.config index 4a39c97..e02a7d5 100644 --- a/conf/test_cellpose.config +++ b/conf/test_cellpose.config @@ -27,19 +27,23 @@ params { read.technology = "toy_dataset" - patchify.patch_width_pixel = 1200 - patchify.patch_overlap_pixel = 50 - patchify.patch_width_microns = 3000 - patchify.patch_overlap_microns = 40 + patchify = [ + patch_width_pixel: 5000, + patch_overlap_pixel: 50, + ] - segmentation.cellpose.diameter = 35 - segmentation.cellpose.channels = ["DAPI"] - segmentation.cellpose.flow_threshold = 2 - segmentation.cellpose.cellprob_threshold = -6 - segmentation.cellpose.min_area = 2500 + segmentation.cellpose = [ + diameter: 35, + channels: ["DAPI"], + flow_threshold: 2, + cellprob_threshold: -6, + min_area: 2500, + ] aggregate.aggregate_channels = true - explorer.ram_threshold_gb = 4 - explorer.pixel_size = 0.1 + explorer = [ + ram_threshold_gb: 4, + pixel_size: 0.1, + ] } diff --git a/conf/test_full.config b/conf/test_full.config index e582bbd..509e3ca 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -17,17 +17,28 @@ params { // Input data input = "${baseDir}/tests/samplesheet.csv" - read.technology = "toy_dataset" - read.kwargs.genes = 500 - - patchify.patch_width_microns = -1 - patchify.patch_overlap_microns = 0 + read = [ + technology: "toy_dataset", + kwargs: [ + genes: 500, + length: 10000, + ], + ] + + patchify = [ + patch_width_microns: 400, + patch_overlap_microns: 20, + ] segmentation.proseg.prior_shapes_key = "auto" - aggregate.aggregate_channels = true - aggregate.min_transcripts = 5 + aggregate = [ + aggregate_channels: true, + min_transcripts: 5, + ] - explorer.ram_threshold_gb = 4 - explorer.pixel_size = 0.1 + explorer = [ + ram_threshold_gb: 4, + pixel_size: 0.1, + ] } diff --git a/conf/test_proseg.config b/conf/test_proseg.config deleted file mode 100644 index ae6dd61..0000000 --- a/conf/test_proseg.config +++ /dev/null @@ -1,41 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Nextflow config file for running minimal tests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Defines input files and everything required to run a fast and simple pipeline test. - - Use as follows: - nextflow run nf-core/sopa -profile test, --outdir - ----------------------------------------------------------------------------------------- -*/ - -process { - resourceLimits = [ - cpus: 4, - memory: '15.GB', - time: '1.h', - ] -} - -params { - config_profile_name = 'Test profile with Proseg' - config_profile_description = 'Minimal test dataset to check pipeline function' - - // Input data - input = "${baseDir}/tests/samplesheet.csv" - - read.technology = "toy_dataset" - read.kwargs.genes = 500 - - patchify.patch_width_microns = -1 - patchify.patch_overlap_microns = 0 - - segmentation.proseg.prior_shapes_key = "auto" - - aggregate.aggregate_channels = true - aggregate.min_transcripts = 5 - - explorer.ram_threshold_gb = 4 - explorer.pixel_size = 0.1 -} diff --git a/nextflow.config b/nextflow.config index 0315d8f..de15be3 100644 --- a/nextflow.config +++ b/nextflow.config @@ -163,7 +163,7 @@ profiles { singularity.runOptions = '--nv' } test { includeConfig 'conf/test.config' } - test_proseg { includeConfig 'conf/test_proseg.config' } + test_baysor { includeConfig 'conf/test_baysor.config' } test_cellpose { includeConfig 'conf/test_cellpose.config' } test_full { includeConfig 'conf/test_full.config' } } From 779cfe6b18bf611ba5e98fcfe86e723785c91c54 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 12:05:21 +0200 Subject: [PATCH 139/227] improve docs usage clarity --- README.md | 2 +- docs/usage.md | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0d7a20a..f75c821 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ SAMPLE2,/path/to/one/merscope_directory > [!WARNING] > If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters). -Then, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument. +Then, choose the Sopa parameters. You can find existing Sopa params files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument. Now, you can run the pipeline using: diff --git a/docs/usage.md b/docs/usage.md index 03b888c..1e35b82 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -38,22 +38,25 @@ Visium_HD_Human_Lung_Cancer_Fixed_Frozen,Visium_HD_Human_Lung_Cancer_Fixed_Froze The above samplesheet is made for [this public sample](https://www.10xgenomics.com/datasets/visium-hd-cytassist-gene-expression-human-lung-cancer-fixed-frozen) (download all the "Input files" and untar the `fastq` zip file). -## Sopa config file +## Sopa parameters -You'll also need to choose a Sopa config file (a.k.a. `-params-file` in Nextflow). You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument. +You'll also need to choose some Sopa parameters that you'll provide to Nextflow via the `-params-file` option. You can find existing Sopa parameter files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument. For instance, if you have Xenium data and want to run Sopa with `proseg`, you can use: ``` ---params-file https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/xenium/proseg.yaml +-params-file https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/xenium/proseg.yaml ``` +> [!NOTE] +> This `-params-file` option is **not** specific to Sopa - you can list other Nextflow params inside it. In that case, make your own local params-file. + ## Running the pipeline Once you have defined your samplesheet and `params-file`, you'll be able to run `nf-core/sopa`. The typical command for running the pipeline is as follows: ```bash -nextflow run nf-core/sopa -params-file --input ./samplesheet.csv --outdir ./results -profile docker +nextflow run nf-core/sopa --input ./samplesheet.csv -params-file --outdir ./results -profile docker ``` > [!NOTE] From 94bc82b67e20a8bfab5347350a53b09eb9dee0f4 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 12:05:40 +0200 Subject: [PATCH 140/227] tests three profiles --- modules/local/cellpose/main.nf | 2 +- tests/{proseg.nf.test => baysor.nf.test} | 3 +- ...roseg.nf.test.snap => baysor.nf.test.snap} | 4 +- tests/cellpose.nf.test | 1 + tests/cellpose.nf.test.snap | 76 +++-------- tests/default.nf.test | 1 + tests/default.nf.test.snap | 120 ++++++++---------- tests/sample1 | 2 - tests/sample2 | 2 - 9 files changed, 79 insertions(+), 132 deletions(-) rename tests/{proseg.nf.test => baysor.nf.test} (95%) rename tests/{proseg.nf.test.snap => baysor.nf.test.snap} (99%) delete mode 100644 tests/sample1 delete mode 100644 tests/sample2 diff --git a/modules/local/cellpose/main.nf b/modules/local/cellpose/main.nf index 0bb0e7c..5912b24 100644 --- a/modules/local/cellpose/main.nf +++ b/modules/local/cellpose/main.nf @@ -44,7 +44,7 @@ process RESOLVE_CELLPOSE { cat <<-END_VERSIONS > versions.yml "${task.process}": sopa: \$(sopa --version) - cellpose: \$(python -c "import cellpose; print(cellpose.version)" 2> /dev/null) + cellpose: \$(python -c "import cellpose; print(cellpose.version)" 2> /dev/null | tail -n 1) END_VERSIONS """ } diff --git a/tests/proseg.nf.test b/tests/baysor.nf.test similarity index 95% rename from tests/proseg.nf.test rename to tests/baysor.nf.test index f56753e..946801b 100644 --- a/tests/proseg.nf.test +++ b/tests/baysor.nf.test @@ -2,9 +2,10 @@ nextflow_pipeline { name "Test pipeline" script "../main.nf" + profile "test_baysor" tag "pipeline" - test("-profile test_proseg") { + test("-profile test_baysor") { when { params { diff --git a/tests/proseg.nf.test.snap b/tests/baysor.nf.test.snap similarity index 99% rename from tests/proseg.nf.test.snap rename to tests/baysor.nf.test.snap index a775ef9..c246290 100644 --- a/tests/proseg.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -1,5 +1,5 @@ { - "-profile test_proseg": { + "-profile test_baysor": { "content": [ 9, { @@ -341,6 +341,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-23T14:45:57.514099" + "timestamp": "2025-07-24T11:26:13.853161" } } \ No newline at end of file diff --git a/tests/cellpose.nf.test b/tests/cellpose.nf.test index cca280a..de7ed9c 100644 --- a/tests/cellpose.nf.test +++ b/tests/cellpose.nf.test @@ -2,6 +2,7 @@ nextflow_pipeline { name "Test pipeline" script "../main.nf" + profile "test_cellpose" tag "pipeline" test("-profile test_cellpose") { diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 86caabe..494554b 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -3,9 +3,9 @@ "content": [ 9, { - "RESOLVE_BAYSOR": { + "RESOLVE_CELLPOSE": { "sopa": "2.1.1", - "baysor": "0.7.1" + "cellpose": "4.0.6" }, "TO_SPATIALDATA": { "sopa": "2.1.1", @@ -116,18 +116,18 @@ "sample_name.zarr/points/transcripts/points.parquet/part.0.parquet", "sample_name.zarr/shapes", "sample_name.zarr/shapes/.zgroup", - "sample_name.zarr/shapes/baysor_boundaries", - "sample_name.zarr/shapes/baysor_boundaries/.zattrs", - "sample_name.zarr/shapes/baysor_boundaries/.zgroup", - "sample_name.zarr/shapes/baysor_boundaries/shapes.parquet", + "sample_name.zarr/shapes/cellpose_boundaries", + "sample_name.zarr/shapes/cellpose_boundaries/.zattrs", + "sample_name.zarr/shapes/cellpose_boundaries/.zgroup", + "sample_name.zarr/shapes/cellpose_boundaries/shapes.parquet", "sample_name.zarr/shapes/cells", "sample_name.zarr/shapes/cells/.zattrs", "sample_name.zarr/shapes/cells/.zgroup", "sample_name.zarr/shapes/cells/shapes.parquet", - "sample_name.zarr/shapes/transcripts_patches", - "sample_name.zarr/shapes/transcripts_patches/.zattrs", - "sample_name.zarr/shapes/transcripts_patches/.zgroup", - "sample_name.zarr/shapes/transcripts_patches/shapes.parquet", + "sample_name.zarr/shapes/image_patches", + "sample_name.zarr/shapes/image_patches/.zattrs", + "sample_name.zarr/shapes/image_patches/.zgroup", + "sample_name.zarr/shapes/image_patches/shapes.parquet", "sample_name.zarr/tables", "sample_name.zarr/tables/.zgroup", "sample_name.zarr/tables/table", @@ -159,46 +159,10 @@ "sample_name.zarr/tables/table/obs/area/.zarray", "sample_name.zarr/tables/table/obs/area/.zattrs", "sample_name.zarr/tables/table/obs/area/0", - "sample_name.zarr/tables/table/obs/avg_assignment_confidence", - "sample_name.zarr/tables/table/obs/avg_assignment_confidence/.zarray", - "sample_name.zarr/tables/table/obs/avg_assignment_confidence/.zattrs", - "sample_name.zarr/tables/table/obs/avg_assignment_confidence/0", - "sample_name.zarr/tables/table/obs/avg_confidence", - "sample_name.zarr/tables/table/obs/avg_confidence/.zarray", - "sample_name.zarr/tables/table/obs/avg_confidence/.zattrs", - "sample_name.zarr/tables/table/obs/avg_confidence/0", - "sample_name.zarr/tables/table/obs/baysor_area", - "sample_name.zarr/tables/table/obs/baysor_area/.zarray", - "sample_name.zarr/tables/table/obs/baysor_area/.zattrs", - "sample_name.zarr/tables/table/obs/baysor_area/0", "sample_name.zarr/tables/table/obs/cell_id", "sample_name.zarr/tables/table/obs/cell_id/.zarray", "sample_name.zarr/tables/table/obs/cell_id/.zattrs", "sample_name.zarr/tables/table/obs/cell_id/0", - "sample_name.zarr/tables/table/obs/cluster", - "sample_name.zarr/tables/table/obs/cluster/.zarray", - "sample_name.zarr/tables/table/obs/cluster/.zattrs", - "sample_name.zarr/tables/table/obs/cluster/0", - "sample_name.zarr/tables/table/obs/density", - "sample_name.zarr/tables/table/obs/density/.zarray", - "sample_name.zarr/tables/table/obs/density/.zattrs", - "sample_name.zarr/tables/table/obs/density/0", - "sample_name.zarr/tables/table/obs/elongation", - "sample_name.zarr/tables/table/obs/elongation/.zarray", - "sample_name.zarr/tables/table/obs/elongation/.zattrs", - "sample_name.zarr/tables/table/obs/elongation/0", - "sample_name.zarr/tables/table/obs/lifespan", - "sample_name.zarr/tables/table/obs/lifespan/.zarray", - "sample_name.zarr/tables/table/obs/lifespan/.zattrs", - "sample_name.zarr/tables/table/obs/lifespan/0", - "sample_name.zarr/tables/table/obs/max_cluster_frac", - "sample_name.zarr/tables/table/obs/max_cluster_frac/.zarray", - "sample_name.zarr/tables/table/obs/max_cluster_frac/.zattrs", - "sample_name.zarr/tables/table/obs/max_cluster_frac/0", - "sample_name.zarr/tables/table/obs/n_transcripts", - "sample_name.zarr/tables/table/obs/n_transcripts/.zarray", - "sample_name.zarr/tables/table/obs/n_transcripts/.zattrs", - "sample_name.zarr/tables/table/obs/n_transcripts/0", "sample_name.zarr/tables/table/obs/region", "sample_name.zarr/tables/table/obs/region/.zattrs", "sample_name.zarr/tables/table/obs/region/.zgroup", @@ -221,14 +185,6 @@ "sample_name.zarr/tables/table/obs/slide/codes/.zarray", "sample_name.zarr/tables/table/obs/slide/codes/.zattrs", "sample_name.zarr/tables/table/obs/slide/codes/0", - "sample_name.zarr/tables/table/obs/x", - "sample_name.zarr/tables/table/obs/x/.zarray", - "sample_name.zarr/tables/table/obs/x/.zattrs", - "sample_name.zarr/tables/table/obs/x/0", - "sample_name.zarr/tables/table/obs/y", - "sample_name.zarr/tables/table/obs/y/.zarray", - "sample_name.zarr/tables/table/obs/y/.zattrs", - "sample_name.zarr/tables/table/obs/y/0", "sample_name.zarr/tables/table/obsm", "sample_name.zarr/tables/table/obsm/.zattrs", "sample_name.zarr/tables/table/obsm/.zgroup", @@ -295,10 +251,10 @@ "sample_name.zarr/tables/table/var", "sample_name.zarr/tables/table/var/.zattrs", "sample_name.zarr/tables/table/var/.zgroup", - "sample_name.zarr/tables/table/var/Name", - "sample_name.zarr/tables/table/var/Name/.zarray", - "sample_name.zarr/tables/table/var/Name/.zattrs", - "sample_name.zarr/tables/table/var/Name/0", + "sample_name.zarr/tables/table/var/_index", + "sample_name.zarr/tables/table/var/_index/.zarray", + "sample_name.zarr/tables/table/var/_index/.zattrs", + "sample_name.zarr/tables/table/var/_index/0", "sample_name.zarr/tables/table/varm", "sample_name.zarr/tables/table/varm/.zattrs", "sample_name.zarr/tables/table/varm/.zgroup", @@ -334,13 +290,13 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "zmetadata:md5,9d5c0fa793978ffc16fb325d7531da7f" + "zmetadata:md5,ab32569f52e288275cd8e5bbca2609af" ] ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-23T14:43:29.525774" + "timestamp": "2025-07-24T12:01:34.518465" } } \ No newline at end of file diff --git a/tests/default.nf.test b/tests/default.nf.test index f428bc1..b7eb781 100644 --- a/tests/default.nf.test +++ b/tests/default.nf.test @@ -2,6 +2,7 @@ nextflow_pipeline { name "Test pipeline" script "../main.nf" + profile "test" tag "pipeline" test("-profile test") { diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 2396399..c7ed4b5 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -1,11 +1,11 @@ { "-profile test": { "content": [ - 9, + 8, { - "RESOLVE_BAYSOR": { + "PATCH_SEGMENTATION_PROSEG": { "sopa": "2.1.1", - "baysor": "0.7.1" + "proseg": "2.0.4" }, "TO_SPATIALDATA": { "sopa": "2.1.1", @@ -116,14 +116,14 @@ "sample_name.zarr/points/transcripts/points.parquet/part.0.parquet", "sample_name.zarr/shapes", "sample_name.zarr/shapes/.zgroup", - "sample_name.zarr/shapes/baysor_boundaries", - "sample_name.zarr/shapes/baysor_boundaries/.zattrs", - "sample_name.zarr/shapes/baysor_boundaries/.zgroup", - "sample_name.zarr/shapes/baysor_boundaries/shapes.parquet", "sample_name.zarr/shapes/cells", "sample_name.zarr/shapes/cells/.zattrs", "sample_name.zarr/shapes/cells/.zgroup", "sample_name.zarr/shapes/cells/shapes.parquet", + "sample_name.zarr/shapes/proseg_boundaries", + "sample_name.zarr/shapes/proseg_boundaries/.zattrs", + "sample_name.zarr/shapes/proseg_boundaries/.zgroup", + "sample_name.zarr/shapes/proseg_boundaries/shapes.parquet", "sample_name.zarr/shapes/transcripts_patches", "sample_name.zarr/shapes/transcripts_patches/.zattrs", "sample_name.zarr/shapes/transcripts_patches/.zgroup", @@ -134,17 +134,14 @@ "sample_name.zarr/tables/table/.zattrs", "sample_name.zarr/tables/table/.zgroup", "sample_name.zarr/tables/table/X", + "sample_name.zarr/tables/table/X/.zarray", "sample_name.zarr/tables/table/X/.zattrs", - "sample_name.zarr/tables/table/X/.zgroup", - "sample_name.zarr/tables/table/X/data", - "sample_name.zarr/tables/table/X/data/.zarray", - "sample_name.zarr/tables/table/X/data/0", - "sample_name.zarr/tables/table/X/indices", - "sample_name.zarr/tables/table/X/indices/.zarray", - "sample_name.zarr/tables/table/X/indices/0", - "sample_name.zarr/tables/table/X/indptr", - "sample_name.zarr/tables/table/X/indptr/.zarray", - "sample_name.zarr/tables/table/X/indptr/0", + "sample_name.zarr/tables/table/X/0", + "sample_name.zarr/tables/table/X/0/0", + "sample_name.zarr/tables/table/X/0/1", + "sample_name.zarr/tables/table/X/1", + "sample_name.zarr/tables/table/X/1/0", + "sample_name.zarr/tables/table/X/1/1", "sample_name.zarr/tables/table/layers", "sample_name.zarr/tables/table/layers/.zattrs", "sample_name.zarr/tables/table/layers/.zgroup", @@ -159,46 +156,42 @@ "sample_name.zarr/tables/table/obs/area/.zarray", "sample_name.zarr/tables/table/obs/area/.zattrs", "sample_name.zarr/tables/table/obs/area/0", - "sample_name.zarr/tables/table/obs/avg_assignment_confidence", - "sample_name.zarr/tables/table/obs/avg_assignment_confidence/.zarray", - "sample_name.zarr/tables/table/obs/avg_assignment_confidence/.zattrs", - "sample_name.zarr/tables/table/obs/avg_assignment_confidence/0", - "sample_name.zarr/tables/table/obs/avg_confidence", - "sample_name.zarr/tables/table/obs/avg_confidence/.zarray", - "sample_name.zarr/tables/table/obs/avg_confidence/.zattrs", - "sample_name.zarr/tables/table/obs/avg_confidence/0", - "sample_name.zarr/tables/table/obs/baysor_area", - "sample_name.zarr/tables/table/obs/baysor_area/.zarray", - "sample_name.zarr/tables/table/obs/baysor_area/.zattrs", - "sample_name.zarr/tables/table/obs/baysor_area/0", + "sample_name.zarr/tables/table/obs/cell", + "sample_name.zarr/tables/table/obs/cell/.zarray", + "sample_name.zarr/tables/table/obs/cell/.zattrs", + "sample_name.zarr/tables/table/obs/cell/0", "sample_name.zarr/tables/table/obs/cell_id", "sample_name.zarr/tables/table/obs/cell_id/.zarray", "sample_name.zarr/tables/table/obs/cell_id/.zattrs", "sample_name.zarr/tables/table/obs/cell_id/0", + "sample_name.zarr/tables/table/obs/centroid_x", + "sample_name.zarr/tables/table/obs/centroid_x/.zarray", + "sample_name.zarr/tables/table/obs/centroid_x/.zattrs", + "sample_name.zarr/tables/table/obs/centroid_x/0", + "sample_name.zarr/tables/table/obs/centroid_y", + "sample_name.zarr/tables/table/obs/centroid_y/.zarray", + "sample_name.zarr/tables/table/obs/centroid_y/.zattrs", + "sample_name.zarr/tables/table/obs/centroid_y/0", + "sample_name.zarr/tables/table/obs/centroid_z", + "sample_name.zarr/tables/table/obs/centroid_z/.zarray", + "sample_name.zarr/tables/table/obs/centroid_z/.zattrs", + "sample_name.zarr/tables/table/obs/centroid_z/0", "sample_name.zarr/tables/table/obs/cluster", "sample_name.zarr/tables/table/obs/cluster/.zarray", "sample_name.zarr/tables/table/obs/cluster/.zattrs", "sample_name.zarr/tables/table/obs/cluster/0", - "sample_name.zarr/tables/table/obs/density", - "sample_name.zarr/tables/table/obs/density/.zarray", - "sample_name.zarr/tables/table/obs/density/.zattrs", - "sample_name.zarr/tables/table/obs/density/0", - "sample_name.zarr/tables/table/obs/elongation", - "sample_name.zarr/tables/table/obs/elongation/.zarray", - "sample_name.zarr/tables/table/obs/elongation/.zattrs", - "sample_name.zarr/tables/table/obs/elongation/0", - "sample_name.zarr/tables/table/obs/lifespan", - "sample_name.zarr/tables/table/obs/lifespan/.zarray", - "sample_name.zarr/tables/table/obs/lifespan/.zattrs", - "sample_name.zarr/tables/table/obs/lifespan/0", - "sample_name.zarr/tables/table/obs/max_cluster_frac", - "sample_name.zarr/tables/table/obs/max_cluster_frac/.zarray", - "sample_name.zarr/tables/table/obs/max_cluster_frac/.zattrs", - "sample_name.zarr/tables/table/obs/max_cluster_frac/0", - "sample_name.zarr/tables/table/obs/n_transcripts", - "sample_name.zarr/tables/table/obs/n_transcripts/.zarray", - "sample_name.zarr/tables/table/obs/n_transcripts/.zattrs", - "sample_name.zarr/tables/table/obs/n_transcripts/0", + "sample_name.zarr/tables/table/obs/fov", + "sample_name.zarr/tables/table/obs/fov/.zarray", + "sample_name.zarr/tables/table/obs/fov/.zattrs", + "sample_name.zarr/tables/table/obs/fov/0", + "sample_name.zarr/tables/table/obs/original_cell_id", + "sample_name.zarr/tables/table/obs/original_cell_id/.zarray", + "sample_name.zarr/tables/table/obs/original_cell_id/.zattrs", + "sample_name.zarr/tables/table/obs/original_cell_id/0", + "sample_name.zarr/tables/table/obs/population", + "sample_name.zarr/tables/table/obs/population/.zarray", + "sample_name.zarr/tables/table/obs/population/.zattrs", + "sample_name.zarr/tables/table/obs/population/0", "sample_name.zarr/tables/table/obs/region", "sample_name.zarr/tables/table/obs/region/.zattrs", "sample_name.zarr/tables/table/obs/region/.zgroup", @@ -210,6 +203,10 @@ "sample_name.zarr/tables/table/obs/region/codes/.zarray", "sample_name.zarr/tables/table/obs/region/codes/.zattrs", "sample_name.zarr/tables/table/obs/region/codes/0", + "sample_name.zarr/tables/table/obs/scale", + "sample_name.zarr/tables/table/obs/scale/.zarray", + "sample_name.zarr/tables/table/obs/scale/.zattrs", + "sample_name.zarr/tables/table/obs/scale/0", "sample_name.zarr/tables/table/obs/slide", "sample_name.zarr/tables/table/obs/slide/.zattrs", "sample_name.zarr/tables/table/obs/slide/.zgroup", @@ -221,14 +218,10 @@ "sample_name.zarr/tables/table/obs/slide/codes/.zarray", "sample_name.zarr/tables/table/obs/slide/codes/.zattrs", "sample_name.zarr/tables/table/obs/slide/codes/0", - "sample_name.zarr/tables/table/obs/x", - "sample_name.zarr/tables/table/obs/x/.zarray", - "sample_name.zarr/tables/table/obs/x/.zattrs", - "sample_name.zarr/tables/table/obs/x/0", - "sample_name.zarr/tables/table/obs/y", - "sample_name.zarr/tables/table/obs/y/.zarray", - "sample_name.zarr/tables/table/obs/y/.zattrs", - "sample_name.zarr/tables/table/obs/y/0", + "sample_name.zarr/tables/table/obs/volume", + "sample_name.zarr/tables/table/obs/volume/.zarray", + "sample_name.zarr/tables/table/obs/volume/.zattrs", + "sample_name.zarr/tables/table/obs/volume/0", "sample_name.zarr/tables/table/obsm", "sample_name.zarr/tables/table/obsm/.zattrs", "sample_name.zarr/tables/table/obsm/.zgroup", @@ -295,10 +288,10 @@ "sample_name.zarr/tables/table/var", "sample_name.zarr/tables/table/var/.zattrs", "sample_name.zarr/tables/table/var/.zgroup", - "sample_name.zarr/tables/table/var/Name", - "sample_name.zarr/tables/table/var/Name/.zarray", - "sample_name.zarr/tables/table/var/Name/.zattrs", - "sample_name.zarr/tables/table/var/Name/0", + "sample_name.zarr/tables/table/var/_index", + "sample_name.zarr/tables/table/var/_index/.zarray", + "sample_name.zarr/tables/table/var/_index/.zattrs", + "sample_name.zarr/tables/table/var/_index/0", "sample_name.zarr/tables/table/varm", "sample_name.zarr/tables/table/varm/.zattrs", "sample_name.zarr/tables/table/varm/.zgroup", @@ -333,14 +326,13 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "zmetadata:md5,9d5c0fa793978ffc16fb325d7531da7f" + "zmetadata:md5,06fd879a23253fd69801595600ff95e3" ] ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-23T14:44:44.09277" + "timestamp": "2025-07-24T11:40:11.148096" } } \ No newline at end of file diff --git a/tests/sample1 b/tests/sample1 deleted file mode 100644 index f78b913..0000000 --- a/tests/sample1 +++ /dev/null @@ -1,2 +0,0 @@ -This is a fake sample -Tests datasets are generated on the fly by Sopa diff --git a/tests/sample2 b/tests/sample2 deleted file mode 100644 index f78b913..0000000 --- a/tests/sample2 +++ /dev/null @@ -1,2 +0,0 @@ -This is a fake sample -Tests datasets are generated on the fly by Sopa From fade57ea81d83b7427465b3473cfad05a8b18dd8 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 12:07:13 +0200 Subject: [PATCH 141/227] update ro-crate --- ro-crate-metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 43237f1..24d4edd 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "Stable", "datePublished": "2025-07-22T07:34:52+00:00", - "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n

    \n \"sopa_overview\"\n

    \n\n0. (Visium HD only) Raw data processing with Space Ranger\n1. (Optional) Tissue segmentation\n2. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n3. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n4. (Optional) Cell-type annotation **_- coming soon_**\n5. User-friendly output creation for visualization and quick analysis\n6. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://gustaveroussy.github.io/sopa/).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose a Sopa config file. You can find existing Sopa config files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n -params-file \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n

    \n \"sopa_overview\"\n

    \n\n0. (Visium HD only) Raw data processing with Space Ranger\n1. (Optional) Tissue segmentation\n2. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n3. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n4. (Optional) Cell-type annotation **_- coming soon_**\n5. User-friendly output creation for visualization and quick analysis\n6. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://gustaveroussy.github.io/sopa/).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose the Sopa parameters. You can find existing Sopa params files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n -params-file \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" From 77f991e820d8db3cc336b42642e3e056ec8e9f7a Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 13:06:04 +0200 Subject: [PATCH 142/227] cellpose: use docker.runOptions = '' --- conf/test_cellpose.config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conf/test_cellpose.config b/conf/test_cellpose.config index e02a7d5..9db08a4 100644 --- a/conf/test_cellpose.config +++ b/conf/test_cellpose.config @@ -18,6 +18,8 @@ process { ] } +docker.runOptions = '' + params { config_profile_name = 'Test profile with Cellpose' config_profile_description = 'Minimal test dataset to check pipeline function' From 11057c03725ffe1c5ca1dbdd53562697e7dfa044 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 13:29:06 +0200 Subject: [PATCH 143/227] use containerOptions and remove sopa_cache from snapshots --- conf/test_cellpose.config | 2 -- modules/local/cellpose/main.nf | 2 +- nextflow.config | 6 +++--- tests/.nftignore | 1 + tests/cellpose.nf.test | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/conf/test_cellpose.config b/conf/test_cellpose.config index 9db08a4..e02a7d5 100644 --- a/conf/test_cellpose.config +++ b/conf/test_cellpose.config @@ -18,8 +18,6 @@ process { ] } -docker.runOptions = '' - params { config_profile_name = 'Test profile with Cellpose' config_profile_description = 'Minimal test dataset to check pipeline function' diff --git a/modules/local/cellpose/main.nf b/modules/local/cellpose/main.nf index 5912b24..ccfa3e0 100644 --- a/modules/local/cellpose/main.nf +++ b/modules/local/cellpose/main.nf @@ -44,7 +44,7 @@ process RESOLVE_CELLPOSE { cat <<-END_VERSIONS > versions.yml "${task.process}": sopa: \$(sopa --version) - cellpose: \$(python -c "import cellpose; print(cellpose.version)" 2> /dev/null | tail -n 1) + cellpose: \$(cellpose --version | grep 'cellpose version:' | head -n1 | awk '{print \$3}') END_VERSIONS """ } diff --git a/nextflow.config b/nextflow.config index de15be3..988e752 100644 --- a/nextflow.config +++ b/nextflow.config @@ -86,10 +86,10 @@ profiles { shifter.enabled = false charliecloud.enabled = false apptainer.enabled = false - docker.runOptions = '-u $(id -u):$(id -g)' + process.containerOptions = '-u $(id -u):$(id -g)' } arm { - docker.runOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' + process.containerOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' } singularity { singularity.enabled = true @@ -158,7 +158,7 @@ profiles { } } gpu { - docker.runOptions = '-u $(id -u):$(id -g) --gpus all' + process.containerOptions = '-u $(id -u):$(id -g) --gpus all' apptainer.runOptions = '--nv' singularity.runOptions = '--nv' } diff --git a/tests/.nftignore b/tests/.nftignore index f7afaf5..5391c7d 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -13,3 +13,4 @@ pipeline_info/*.{html,json,txt,yml} **/1 **/2 **/3 +**/.sopa_cache/** diff --git a/tests/cellpose.nf.test b/tests/cellpose.nf.test index de7ed9c..7629ca1 100644 --- a/tests/cellpose.nf.test +++ b/tests/cellpose.nf.test @@ -15,7 +15,7 @@ nextflow_pipeline { then { // stable_name: All files + folders in ${params.outdir}/ with a stable name - def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', '**/.sopa_cache/**']) // stable_path: All files in ${params.outdir}/ with stable content def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') assertAll( From d89eea499bd3a260a7c00d6ef132e68743dda171 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 13:42:54 +0200 Subject: [PATCH 144/227] fix cellpose snapshot --- tests/.nftignore | 1 + tests/cellpose.nf.test.snap | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/.nftignore b/tests/.nftignore index 5391c7d..9fece7d 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -13,4 +13,5 @@ pipeline_info/*.{html,json,txt,yml} **/1 **/2 **/3 +**/.sopa_cache **/.sopa_cache/** diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 494554b..fc4847d 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -5,7 +5,7 @@ { "RESOLVE_CELLPOSE": { "sopa": "2.1.1", - "cellpose": "4.0.6" + "cellpose": null }, "TO_SPATIALDATA": { "sopa": "2.1.1", From d272f7b39a5b9689448965fd7c4cd3ffeabde15b Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 13:53:16 +0200 Subject: [PATCH 145/227] fix cellpose snapshot again --- tests/cellpose.nf.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cellpose.nf.test b/tests/cellpose.nf.test index 7629ca1..6fc0b0e 100644 --- a/tests/cellpose.nf.test +++ b/tests/cellpose.nf.test @@ -15,7 +15,7 @@ nextflow_pipeline { then { // stable_name: All files + folders in ${params.outdir}/ with a stable name - def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', '**/.sopa_cache/**']) + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', '**/.sopa_cache', '**/.sopa_cache/**']) // stable_path: All files in ${params.outdir}/ with stable content def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') assertAll( From efe0c636a13a47de0fcb9a223e8b00398d2cff0e Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 14:01:30 +0200 Subject: [PATCH 146/227] add cellpose version in snapshot --- modules/local/cellpose/main.nf | 4 ++-- tests/cellpose.nf.test.snap | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/local/cellpose/main.nf b/modules/local/cellpose/main.nf index ccfa3e0..55ce5c6 100644 --- a/modules/local/cellpose/main.nf +++ b/modules/local/cellpose/main.nf @@ -26,8 +26,8 @@ process RESOLVE_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + ? 'docker://quentinblampey/sopa:latest-cellpose' + : 'docker.io/quentinblampey/sopa:latest-cellpose'}" input: tuple val(meta), path(sdata_path) diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index fc4847d..494554b 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -5,7 +5,7 @@ { "RESOLVE_CELLPOSE": { "sopa": "2.1.1", - "cellpose": null + "cellpose": "4.0.6" }, "TO_SPATIALDATA": { "sopa": "2.1.1", From 6430dcf1b91d6e9f3e5757902d070e8b153a37ec Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 14:52:00 +0200 Subject: [PATCH 147/227] add yaml file for processes --- modules/local/baysor/meta.yaml | 8 ++++++++ modules/local/cellpose/meta.yaml | 8 ++++++++ modules/local/proseg/meta.yaml | 8 ++++++++ modules/local/sopa_core/meta.yaml | 8 ++++++++ modules/local/stardist/main.nf | 4 ++-- modules/local/stardist/meta.yaml | 8 ++++++++ 6 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 modules/local/baysor/meta.yaml create mode 100644 modules/local/cellpose/meta.yaml create mode 100644 modules/local/proseg/meta.yaml create mode 100644 modules/local/sopa_core/meta.yaml create mode 100644 modules/local/stardist/meta.yaml diff --git a/modules/local/baysor/meta.yaml b/modules/local/baysor/meta.yaml new file mode 100644 index 0000000..550408d --- /dev/null +++ b/modules/local/baysor/meta.yaml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.10 + - pip=24.3.1 + - pip: + - sopa[baysor]>=2.1.0 diff --git a/modules/local/cellpose/meta.yaml b/modules/local/cellpose/meta.yaml new file mode 100644 index 0000000..53ac2fe --- /dev/null +++ b/modules/local/cellpose/meta.yaml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.10 + - pip=24.3.1 + - pip: + - sopa[cellpose]>=2.1.0 diff --git a/modules/local/proseg/meta.yaml b/modules/local/proseg/meta.yaml new file mode 100644 index 0000000..4f963ad --- /dev/null +++ b/modules/local/proseg/meta.yaml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.10 + - pip=24.3.1 + - pip: + - sopa>=2.1.0 diff --git a/modules/local/sopa_core/meta.yaml b/modules/local/sopa_core/meta.yaml new file mode 100644 index 0000000..4f963ad --- /dev/null +++ b/modules/local/sopa_core/meta.yaml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.10 + - pip=24.3.1 + - pip: + - sopa>=2.1.0 diff --git a/modules/local/stardist/main.nf b/modules/local/stardist/main.nf index 9341991..7c33ac5 100644 --- a/modules/local/stardist/main.nf +++ b/modules/local/stardist/main.nf @@ -26,8 +26,8 @@ process RESOLVE_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + ? 'docker://quentinblampey/sopa:latest-stardist' + : 'docker.io/quentinblampey/sopa:latest-stardist'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/stardist/meta.yaml b/modules/local/stardist/meta.yaml new file mode 100644 index 0000000..233c322 --- /dev/null +++ b/modules/local/stardist/meta.yaml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.10 + - pip=24.3.1 + - pip: + - sopa[stardist]>=2.1.0 From 0fb195a1372c048c8bfc3187c816df58a28df9e0 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 16:24:56 +0200 Subject: [PATCH 148/227] rename meta -> environment --- modules/local/baysor/{meta.yaml => environment.yaml} | 0 modules/local/cellpose/{meta.yaml => environment.yaml} | 0 modules/local/proseg/{meta.yaml => environment.yaml} | 0 modules/local/sopa_core/{meta.yaml => environment.yaml} | 0 modules/local/stardist/{meta.yaml => environment.yaml} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename modules/local/baysor/{meta.yaml => environment.yaml} (100%) rename modules/local/cellpose/{meta.yaml => environment.yaml} (100%) rename modules/local/proseg/{meta.yaml => environment.yaml} (100%) rename modules/local/sopa_core/{meta.yaml => environment.yaml} (100%) rename modules/local/stardist/{meta.yaml => environment.yaml} (100%) diff --git a/modules/local/baysor/meta.yaml b/modules/local/baysor/environment.yaml similarity index 100% rename from modules/local/baysor/meta.yaml rename to modules/local/baysor/environment.yaml diff --git a/modules/local/cellpose/meta.yaml b/modules/local/cellpose/environment.yaml similarity index 100% rename from modules/local/cellpose/meta.yaml rename to modules/local/cellpose/environment.yaml diff --git a/modules/local/proseg/meta.yaml b/modules/local/proseg/environment.yaml similarity index 100% rename from modules/local/proseg/meta.yaml rename to modules/local/proseg/environment.yaml diff --git a/modules/local/sopa_core/meta.yaml b/modules/local/sopa_core/environment.yaml similarity index 100% rename from modules/local/sopa_core/meta.yaml rename to modules/local/sopa_core/environment.yaml diff --git a/modules/local/stardist/meta.yaml b/modules/local/stardist/environment.yaml similarity index 100% rename from modules/local/stardist/meta.yaml rename to modules/local/stardist/environment.yaml From 09e337671a3ddd693aed4ea6358332a49fdc4cf0 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 24 Jul 2025 16:28:11 +0200 Subject: [PATCH 149/227] rename yaml -> yml --- modules/local/baysor/{environment.yaml => environment.yml} | 0 modules/local/cellpose/{environment.yaml => environment.yml} | 0 modules/local/proseg/{environment.yaml => environment.yml} | 0 modules/local/sopa_core/{environment.yaml => environment.yml} | 0 modules/local/stardist/{environment.yaml => environment.yml} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename modules/local/baysor/{environment.yaml => environment.yml} (100%) rename modules/local/cellpose/{environment.yaml => environment.yml} (100%) rename modules/local/proseg/{environment.yaml => environment.yml} (100%) rename modules/local/sopa_core/{environment.yaml => environment.yml} (100%) rename modules/local/stardist/{environment.yaml => environment.yml} (100%) diff --git a/modules/local/baysor/environment.yaml b/modules/local/baysor/environment.yml similarity index 100% rename from modules/local/baysor/environment.yaml rename to modules/local/baysor/environment.yml diff --git a/modules/local/cellpose/environment.yaml b/modules/local/cellpose/environment.yml similarity index 100% rename from modules/local/cellpose/environment.yaml rename to modules/local/cellpose/environment.yml diff --git a/modules/local/proseg/environment.yaml b/modules/local/proseg/environment.yml similarity index 100% rename from modules/local/proseg/environment.yaml rename to modules/local/proseg/environment.yml diff --git a/modules/local/sopa_core/environment.yaml b/modules/local/sopa_core/environment.yml similarity index 100% rename from modules/local/sopa_core/environment.yaml rename to modules/local/sopa_core/environment.yml diff --git a/modules/local/stardist/environment.yaml b/modules/local/stardist/environment.yml similarity index 100% rename from modules/local/stardist/environment.yaml rename to modules/local/stardist/environment.yml From 3c3bf3367cdac60db927c228932423d430183509 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 28 Jul 2025 15:33:10 +0200 Subject: [PATCH 150/227] add optional cell type annotation --- README.md | 19 ++++--- conf/test.config | 11 ++++ conf/test_baysor.config | 8 +++ modules/local/annotation/environment.yml | 9 +++ modules/local/annotation/main.nf | 57 +++++++++++++++++++ nextflow_schema.json | 9 +++ .../local/utils_nfcore_sopa_pipeline/main.nf | 4 ++ workflows/sopa.nf | 22 ++++++- 8 files changed, 128 insertions(+), 11 deletions(-) create mode 100644 modules/local/annotation/environment.yml create mode 100644 modules/local/annotation/main.nf diff --git a/README.md b/README.md index f75c821..745a506 100644 --- a/README.md +++ b/README.md @@ -22,19 +22,22 @@ **nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization. +> [!WARNING] +> If you are interested in the main Sopa python package, refer to [this Sopa repository](https://github.com/gustaveroussy/sopa). Else, if you want to use Nextflow, you are in the good place. +

    sopa_overview

    -0. (Visium HD only) Raw data processing with Space Ranger -1. (Optional) Tissue segmentation -2. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ... -3. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells -4. (Optional) Cell-type annotation **_- coming soon_** -5. User-friendly output creation for visualization and quick analysis -6. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory +1. (Visium HD only) Raw data processing with Space Ranger +2. (Optional) Tissue segmentation +3. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ... +4. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells +5. (Optional) Cell-type annotation +6. User-friendly output creation for visualization and quick analysis +7. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory -After running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://gustaveroussy.github.io/sopa/). +After running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://github.com/gustaveroussy/sopa). ## Usage diff --git a/conf/test.config b/conf/test.config index 2c398ed..4ab64c4 100644 --- a/conf/test.config +++ b/conf/test.config @@ -44,6 +44,17 @@ params { min_transcripts: 5, ] + annotation = [ + method: "fluorescence", + args: [ + marker_cell_dict: [ + CK: "Tumoral cell", + CD3: "T cell", + CD20: "B cell", + ] + ], + ] + explorer = [ ram_threshold_gb: 4, pixel_size: 0.1, diff --git a/conf/test_baysor.config b/conf/test_baysor.config index c125885..62b721d 100644 --- a/conf/test_baysor.config +++ b/conf/test_baysor.config @@ -60,6 +60,14 @@ params { min_transcripts: 5, ] + // annotation = [ + // method: "tangram", + // args: [ + // sc_reference_path: "https://github.com/gustaveroussy/sopa/raw/refs/heads/main/tests/toy_tangram_ref.h5ad", + // cell_type_key: "ct", + // ], + // ] + explorer = [ ram_threshold_gb: 4, pixel_size: 0.1, diff --git a/modules/local/annotation/environment.yml b/modules/local/annotation/environment.yml new file mode 100644 index 0000000..3f61240 --- /dev/null +++ b/modules/local/annotation/environment.yml @@ -0,0 +1,9 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.10 + - pip=24.3.1 + - pip: + - sopa>=2.1.0 + - tangram-sc>=1.0.4 diff --git a/modules/local/annotation/main.nf b/modules/local/annotation/main.nf new file mode 100644 index 0000000..9fc4d7a --- /dev/null +++ b/modules/local/annotation/main.nf @@ -0,0 +1,57 @@ +process TANGRAM_ANNOTATION { + label "process_gpu" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path) + file sc_reference + val cli_arguments + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/tables/table/obs" + path "versions.yml" + + script: + """ + sopa annotate tangram ${sdata_path} --sc-reference-path ${sc_reference} ${cli_arguments} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sopa: \$(sopa --version) + tangram: \$(python -c "import tangram; print(tangram.__version__)" 2> /dev/null) + END_VERSIONS + """ +} + +process FLUO_ANNOTATION { + label "process_medium" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/tables/table/obs" + path "versions.yml" + + script: + """ + sopa annotate fluorescence ${sdata_path} ${cli_arguments} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sopa: \$(sopa --version) + END_VERSIONS + """ +} diff --git a/nextflow_schema.json b/nextflow_schema.json index e14c4f1..8426213 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -148,6 +148,15 @@ "type": "object", "description": "Cell type annotation arguments", "fa_icon": "fas fa-gear", + "properties": { + "marker_cell_dict": { + "type": "object", + "description": "Dictionary mapping cell type markers to their descriptions", + "additionalProperties": { + "type": "string" + } + } + }, "additionalProperties": true } }, diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index c24d2db..fbb7da5 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -273,6 +273,10 @@ def validateParams(params) { } } + // check annotation method + if (params.annotation && params.annotation.method == "tangram") { + assert params.annotation.args.containsKey('sc_reference_path') : "Provide 'annotation.args.sc_reference_path' for the tangram annotation method" + } return params } diff --git a/workflows/sopa.nf b/workflows/sopa.nf index d537bc8..dc9aebb 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -20,6 +20,7 @@ include { EXPLORER_RAW ; REPORT } from '../modules/local/sopa_core' +include { TANGRAM_ANNOTATION ; FLUO_ANNOTATION } from '../modules/local/annotation' include { ArgsCLI ; ArgsReaderCLI } from '../modules/local/utils' include { SPACERANGER } from '../subworkflows/local/spaceranger' /* @@ -92,10 +93,25 @@ workflow SOPA { (ch_aggregated, _out) = AGGREGATE(ch_resolved, ArgsCLI(params.aggregate)) - EXPLORER(ch_aggregated, ArgsCLI(params.explorer)) - REPORT(ch_aggregated) + if (params.annotation && params.annotation.method == "tangram") { + sc_reference = file(params.annotation.args.sc_reference_path) + params.annotation.args.remove('sc_reference_path') - PUBLISH(ch_aggregated.map { it[1] }) + (ch_annotated, _out, versions) = TANGRAM_ANNOTATION(ch_aggregated, sc_reference, ArgsCLI(params.annotation.args)) + ch_versions = ch_versions.mix(versions) + } + else if (params.annotation && params.annotation.method == "fluorescence") { + (ch_annotated, _out, versions) = FLUO_ANNOTATION(ch_aggregated, ArgsCLI(params.annotation.args)) + ch_versions = ch_versions.mix(versions) + } + else { + ch_annotated = ch_aggregated + } + + EXPLORER(ch_annotated, ArgsCLI(params.explorer)) + REPORT(ch_annotated) + + PUBLISH(ch_annotated.map { it[1] }) // From 4759bc8268b12999cfe5315b1a4e1b0457a664fb Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 1 Aug 2025 15:32:36 +0200 Subject: [PATCH 151/227] baysor threads + allow symlink for xenium raw files --- modules/local/baysor/main.nf | 4 +--- modules/local/sopa_core/main.nf | 2 +- workflows/sopa.nf | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/local/baysor/main.nf b/modules/local/baysor/main.nf index fad0e1d..a348e29 100644 --- a/modules/local/baysor/main.nf +++ b/modules/local/baysor/main.nf @@ -14,9 +14,7 @@ process PATCH_SEGMENTATION_BAYSOR { script: """ - if command -v module &> /dev/null; then - module purge - fi + export JULIA_NUM_THREADS=${task.cpus} # parallelize within each patch for Baysor >= v0.7 sopa segmentation baysor ${sdata_path} --patch-index ${index} ${cli_arguments} """ diff --git a/modules/local/sopa_core/main.nf b/modules/local/sopa_core/main.nf index f8c1201..5414d55 100644 --- a/modules/local/sopa_core/main.nf +++ b/modules/local/sopa_core/main.nf @@ -128,7 +128,7 @@ process EXPLORER_RAW { publishDir "${params.outdir}", mode: params.publish_dir_mode input: - tuple val(meta), path(sdata_path) + tuple val(meta), path(sdata_path), path(data_dir) val cli_arguments output: diff --git a/workflows/sopa.nf b/workflows/sopa.nf index dc9aebb..9b9d6ee 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -50,7 +50,7 @@ workflow SOPA { (ch_spatialdata, versions) = TO_SPATIALDATA(ch_input_spatialdata, params.read) ch_versions = ch_versions.mix(versions) - EXPLORER_RAW(ch_spatialdata, ArgsCLI(params.explorer)) + EXPLORER_RAW(ch_spatialdata.map { meta, sdata_path -> [meta, sdata_path, meta.data_dir] }, ArgsCLI(params.explorer)) if (params.segmentation.tissue) { (ch_tissue_seg, _out) = TISSUE_SEGMENTATION(ch_spatialdata, ArgsCLI(params.segmentation.tissue)) From 98511fc29ed2b10cbeeab57ea0ccfc836f79d369 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 1 Aug 2025 15:33:05 +0200 Subject: [PATCH 152/227] fix ro-crate --- ro-crate-metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 24d4edd..30ceed0 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "Stable", "datePublished": "2025-07-22T07:34:52+00:00", - "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n

    \n \"sopa_overview\"\n

    \n\n0. (Visium HD only) Raw data processing with Space Ranger\n1. (Optional) Tissue segmentation\n2. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n3. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n4. (Optional) Cell-type annotation **_- coming soon_**\n5. User-friendly output creation for visualization and quick analysis\n6. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://gustaveroussy.github.io/sopa/).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose the Sopa parameters. You can find existing Sopa params files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n -params-file \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n> [!WARNING]\n> If you are interested in the main Sopa python package, refer to [this Sopa repository](https://github.com/gustaveroussy/sopa). Else, if you want to use Nextflow, you are in the good place.\n\n

    \n \"sopa_overview\"\n

    \n\n1. (Visium HD only) Raw data processing with Space Ranger\n2. (Optional) Tissue segmentation\n3. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n4. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n5. (Optional) Cell-type annotation\n6. User-friendly output creation for visualization and quick analysis\n7. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://github.com/gustaveroussy/sopa).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose the Sopa parameters. You can find existing Sopa params files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n -params-file \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" From 6ea2d568bdd7ac296e6dc2da96e76a90c5f5b3fb Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 1 Aug 2025 16:16:41 +0200 Subject: [PATCH 153/227] re-run snapshots with fluo annotation --- tests/baysor.nf.test.snap | 2 +- tests/cellpose.nf.test.snap | 2 +- tests/default.nf.test.snap | 39 +++++++++++++++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index c246290..b58b0d4 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -341,6 +341,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-24T11:26:13.853161" + "timestamp": "2025-08-01T15:52:12.100609" } } \ No newline at end of file diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 494554b..99f0cc8 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -297,6 +297,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-24T12:01:34.518465" + "timestamp": "2025-08-01T16:10:22.8482" } } \ No newline at end of file diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index c7ed4b5..38ec665 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -1,8 +1,11 @@ { "-profile test": { "content": [ - 8, + 9, { + "FLUO_ANNOTATION": { + "sopa": "2.1.1" + }, "PATCH_SEGMENTATION_PROSEG": { "sopa": "2.1.1", "proseg": "2.0.4" @@ -164,6 +167,10 @@ "sample_name.zarr/tables/table/obs/cell_id/.zarray", "sample_name.zarr/tables/table/obs/cell_id/.zattrs", "sample_name.zarr/tables/table/obs/cell_id/0", + "sample_name.zarr/tables/table/obs/cell_type", + "sample_name.zarr/tables/table/obs/cell_type/.zarray", + "sample_name.zarr/tables/table/obs/cell_type/.zattrs", + "sample_name.zarr/tables/table/obs/cell_type/0", "sample_name.zarr/tables/table/obs/centroid_x", "sample_name.zarr/tables/table/obs/centroid_x/.zarray", "sample_name.zarr/tables/table/obs/centroid_x/.zattrs", @@ -253,6 +260,29 @@ "sample_name.zarr/tables/table/obsm/spatial/.zattrs", "sample_name.zarr/tables/table/obsm/spatial/0", "sample_name.zarr/tables/table/obsm/spatial/0/0", + "sample_name.zarr/tables/table/obsm/z_scores", + "sample_name.zarr/tables/table/obsm/z_scores/.zattrs", + "sample_name.zarr/tables/table/obsm/z_scores/.zgroup", + "sample_name.zarr/tables/table/obsm/z_scores/CD20", + "sample_name.zarr/tables/table/obsm/z_scores/CD20/.zarray", + "sample_name.zarr/tables/table/obsm/z_scores/CD20/.zattrs", + "sample_name.zarr/tables/table/obsm/z_scores/CD20/0", + "sample_name.zarr/tables/table/obsm/z_scores/CD3", + "sample_name.zarr/tables/table/obsm/z_scores/CD3/.zarray", + "sample_name.zarr/tables/table/obsm/z_scores/CD3/.zattrs", + "sample_name.zarr/tables/table/obsm/z_scores/CD3/0", + "sample_name.zarr/tables/table/obsm/z_scores/CK", + "sample_name.zarr/tables/table/obsm/z_scores/CK/.zarray", + "sample_name.zarr/tables/table/obsm/z_scores/CK/.zattrs", + "sample_name.zarr/tables/table/obsm/z_scores/CK/0", + "sample_name.zarr/tables/table/obsm/z_scores/DAPI", + "sample_name.zarr/tables/table/obsm/z_scores/DAPI/.zarray", + "sample_name.zarr/tables/table/obsm/z_scores/DAPI/.zattrs", + "sample_name.zarr/tables/table/obsm/z_scores/DAPI/0", + "sample_name.zarr/tables/table/obsm/z_scores/_index", + "sample_name.zarr/tables/table/obsm/z_scores/_index/.zarray", + "sample_name.zarr/tables/table/obsm/z_scores/_index/.zattrs", + "sample_name.zarr/tables/table/obsm/z_scores/_index/0", "sample_name.zarr/tables/table/obsp", "sample_name.zarr/tables/table/obsp/.zattrs", "sample_name.zarr/tables/table/obsp/.zgroup", @@ -262,6 +292,10 @@ "sample_name.zarr/tables/table/uns/sopa_attrs", "sample_name.zarr/tables/table/uns/sopa_attrs/.zattrs", "sample_name.zarr/tables/table/uns/sopa_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/0", "sample_name.zarr/tables/table/uns/sopa_attrs/intensities", "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", @@ -326,6 +360,7 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", "zmetadata:md5,06fd879a23253fd69801595600ff95e3" ] ], @@ -333,6 +368,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-24T11:40:11.148096" + "timestamp": "2025-08-01T16:12:05.246211" } } \ No newline at end of file From b9433120a9f7d2498e2cbae18f6c6b07c555ba8d Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 20 Aug 2025 09:22:10 +0200 Subject: [PATCH 154/227] add tangram to the tests --- conf/test_baysor.config | 14 +++++----- modules/local/annotation/main.nf | 4 +-- tests/baysor.nf.test.snap | 46 +++++++++++++++++++++++++++----- tests/cellpose.nf.test.snap | 8 +++--- tests/default.nf.test.snap | 10 +++---- 5 files changed, 57 insertions(+), 25 deletions(-) diff --git a/conf/test_baysor.config b/conf/test_baysor.config index 62b721d..292feab 100644 --- a/conf/test_baysor.config +++ b/conf/test_baysor.config @@ -60,13 +60,13 @@ params { min_transcripts: 5, ] - // annotation = [ - // method: "tangram", - // args: [ - // sc_reference_path: "https://github.com/gustaveroussy/sopa/raw/refs/heads/main/tests/toy_tangram_ref.h5ad", - // cell_type_key: "ct", - // ], - // ] + annotation = [ + method: "tangram", + args: [ + sc_reference_path: "https://github.com/gustaveroussy/sopa/raw/refs/heads/main/tests/toy_tangram_ref.h5ad", + cell_type_key: "ct", + ], + ] explorer = [ ram_threshold_gb: 4, diff --git a/modules/local/annotation/main.nf b/modules/local/annotation/main.nf index 9fc4d7a..b82d7aa 100644 --- a/modules/local/annotation/main.nf +++ b/modules/local/annotation/main.nf @@ -3,8 +3,8 @@ process TANGRAM_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + ? 'docker://quentinblampey/sopa:latest-tangram' + : 'docker.io/quentinblampey/sopa:latest-tangram'}" input: tuple val(meta), path(sdata_path) diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index b58b0d4..3230b6f 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -1,16 +1,20 @@ { "-profile test_baysor": { "content": [ - 9, + 10, { "RESOLVE_BAYSOR": { - "sopa": "2.1.1", + "sopa": "2.1.2", "baysor": "0.7.1" }, + "TANGRAM_ANNOTATION": { + "sopa": "2.1.2", + "tangram": "1.0.4" + }, "TO_SPATIALDATA": { - "sopa": "2.1.1", - "spatialdata": "0.4.0", - "spatialdata_io": "0.2.0", + "sopa": "2.1.2", + "spatialdata": "0.5.0", + "spatialdata_io": "0.3.0", "scanpy": "1.11.3" }, "Workflow": { @@ -179,6 +183,10 @@ "sample_name.zarr/tables/table/obs/cluster/.zarray", "sample_name.zarr/tables/table/obs/cluster/.zattrs", "sample_name.zarr/tables/table/obs/cluster/0", + "sample_name.zarr/tables/table/obs/ct", + "sample_name.zarr/tables/table/obs/ct/.zarray", + "sample_name.zarr/tables/table/obs/ct/.zattrs", + "sample_name.zarr/tables/table/obs/ct/0", "sample_name.zarr/tables/table/obs/density", "sample_name.zarr/tables/table/obs/density/.zarray", "sample_name.zarr/tables/table/obs/density/.zattrs", @@ -260,6 +268,25 @@ "sample_name.zarr/tables/table/obsm/spatial/.zattrs", "sample_name.zarr/tables/table/obsm/spatial/0", "sample_name.zarr/tables/table/obsm/spatial/0/0", + "sample_name.zarr/tables/table/obsm/tangram_pred", + "sample_name.zarr/tables/table/obsm/tangram_pred/.zattrs", + "sample_name.zarr/tables/table/obsm/tangram_pred/.zgroup", + "sample_name.zarr/tables/table/obsm/tangram_pred/B cell", + "sample_name.zarr/tables/table/obsm/tangram_pred/B cell/.zarray", + "sample_name.zarr/tables/table/obsm/tangram_pred/B cell/.zattrs", + "sample_name.zarr/tables/table/obsm/tangram_pred/B cell/0", + "sample_name.zarr/tables/table/obsm/tangram_pred/T cell", + "sample_name.zarr/tables/table/obsm/tangram_pred/T cell/.zarray", + "sample_name.zarr/tables/table/obsm/tangram_pred/T cell/.zattrs", + "sample_name.zarr/tables/table/obsm/tangram_pred/T cell/0", + "sample_name.zarr/tables/table/obsm/tangram_pred/Tumor", + "sample_name.zarr/tables/table/obsm/tangram_pred/Tumor/.zarray", + "sample_name.zarr/tables/table/obsm/tangram_pred/Tumor/.zattrs", + "sample_name.zarr/tables/table/obsm/tangram_pred/Tumor/0", + "sample_name.zarr/tables/table/obsm/tangram_pred/_index", + "sample_name.zarr/tables/table/obsm/tangram_pred/_index/.zarray", + "sample_name.zarr/tables/table/obsm/tangram_pred/_index/.zattrs", + "sample_name.zarr/tables/table/obsm/tangram_pred/_index/0", "sample_name.zarr/tables/table/obsp", "sample_name.zarr/tables/table/obsp/.zattrs", "sample_name.zarr/tables/table/obsp/.zgroup", @@ -269,6 +296,10 @@ "sample_name.zarr/tables/table/uns/sopa_attrs", "sample_name.zarr/tables/table/uns/sopa_attrs/.zattrs", "sample_name.zarr/tables/table/uns/sopa_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/0", "sample_name.zarr/tables/table/uns/sopa_attrs/intensities", "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", @@ -334,13 +365,14 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "zmetadata:md5,9d5c0fa793978ffc16fb325d7531da7f" + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + "zmetadata:md5,7d468a95240c306cad8ed692905a4f73" ] ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-08-01T15:52:12.100609" + "timestamp": "2025-08-20T09:18:31.146178" } } \ No newline at end of file diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 99f0cc8..d4c1517 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -4,13 +4,13 @@ 9, { "RESOLVE_CELLPOSE": { - "sopa": "2.1.1", + "sopa": "2.1.2", "cellpose": "4.0.6" }, "TO_SPATIALDATA": { - "sopa": "2.1.1", - "spatialdata": "0.4.0", - "spatialdata_io": "0.2.0", + "sopa": "2.1.2", + "spatialdata": "0.5.0", + "spatialdata_io": "0.3.0", "scanpy": "1.11.3" }, "Workflow": { diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 38ec665..ea9981c 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -4,16 +4,16 @@ 9, { "FLUO_ANNOTATION": { - "sopa": "2.1.1" + "sopa": "2.1.2" }, "PATCH_SEGMENTATION_PROSEG": { - "sopa": "2.1.1", + "sopa": "2.1.2", "proseg": "2.0.4" }, "TO_SPATIALDATA": { - "sopa": "2.1.1", - "spatialdata": "0.4.0", - "spatialdata_io": "0.2.0", + "sopa": "2.1.2", + "spatialdata": "0.5.0", + "spatialdata_io": "0.3.0", "scanpy": "1.11.3" }, "Workflow": { From cf6041185bf43da7677f49b7271aa52d67f4a049 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 20 Aug 2025 10:33:31 +0200 Subject: [PATCH 155/227] update snapshots --- modules/local/sopa_core/main.nf | 1 - tests/.nftignore | 1 + tests/baysor.nf.test.snap | 9 +++------ tests/cellpose.nf.test.snap | 9 +++------ tests/default.nf.test.snap | 9 +++------ 5 files changed, 10 insertions(+), 19 deletions(-) diff --git a/modules/local/sopa_core/main.nf b/modules/local/sopa_core/main.nf index 5414d55..7fc8ea2 100644 --- a/modules/local/sopa_core/main.nf +++ b/modules/local/sopa_core/main.nf @@ -25,7 +25,6 @@ process TO_SPATIALDATA { sopa: \$(sopa --version 2> /dev/null) spatialdata: \$(python -c "import spatialdata; print(spatialdata.__version__)" 2> /dev/null) spatialdata_io: \$(python -c "import spatialdata_io; print(spatialdata_io.__version__)" 2> /dev/null) - scanpy: \$(python -c "import scanpy; print(scanpy.__version__)" 2> /dev/null) END_VERSIONS """ } diff --git a/tests/.nftignore b/tests/.nftignore index 9fece7d..f1416d9 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -13,5 +13,6 @@ pipeline_info/*.{html,json,txt,yml} **/1 **/2 **/3 +**/zmetadata **/.sopa_cache **/.sopa_cache/** diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index 3230b6f..245115e 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -14,8 +14,7 @@ "TO_SPATIALDATA": { "sopa": "2.1.2", "spatialdata": "0.5.0", - "spatialdata_io": "0.3.0", - "scanpy": "1.11.3" + "spatialdata_io": "0.3.0" }, "Workflow": { "nf-core/sopa": "v1.0.0" @@ -335,8 +334,7 @@ "sample_name.zarr/tables/table/varm/.zgroup", "sample_name.zarr/tables/table/varp", "sample_name.zarr/tables/table/varp/.zattrs", - "sample_name.zarr/tables/table/varp/.zgroup", - "sample_name.zarr/zmetadata" + "sample_name.zarr/tables/table/varp/.zgroup" ], [ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", @@ -365,8 +363,7 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "zmetadata:md5,7d468a95240c306cad8ed692905a4f73" + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab" ] ], "meta": { diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index d4c1517..9a30e51 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -10,8 +10,7 @@ "TO_SPATIALDATA": { "sopa": "2.1.2", "spatialdata": "0.5.0", - "spatialdata_io": "0.3.0", - "scanpy": "1.11.3" + "spatialdata_io": "0.3.0" }, "Workflow": { "nf-core/sopa": "v1.0.0" @@ -260,8 +259,7 @@ "sample_name.zarr/tables/table/varm/.zgroup", "sample_name.zarr/tables/table/varp", "sample_name.zarr/tables/table/varp/.zattrs", - "sample_name.zarr/tables/table/varp/.zgroup", - "sample_name.zarr/zmetadata" + "sample_name.zarr/tables/table/varp/.zgroup" ], [ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", @@ -289,8 +287,7 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "zmetadata:md5,ab32569f52e288275cd8e5bbca2609af" + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab" ] ], "meta": { diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index ea9981c..59ecac1 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -13,8 +13,7 @@ "TO_SPATIALDATA": { "sopa": "2.1.2", "spatialdata": "0.5.0", - "spatialdata_io": "0.3.0", - "scanpy": "1.11.3" + "spatialdata_io": "0.3.0" }, "Workflow": { "nf-core/sopa": "v1.0.0" @@ -331,8 +330,7 @@ "sample_name.zarr/tables/table/varm/.zgroup", "sample_name.zarr/tables/table/varp", "sample_name.zarr/tables/table/varp/.zattrs", - "sample_name.zarr/tables/table/varp/.zgroup", - "sample_name.zarr/zmetadata" + "sample_name.zarr/tables/table/varp/.zgroup" ], [ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", @@ -360,8 +358,7 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - "zmetadata:md5,06fd879a23253fd69801595600ff95e3" + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab" ] ], "meta": { From 02e1d7e6d5467e5abcf75dc4a44cdd0b10ff9c27 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 20 Aug 2025 10:47:03 +0200 Subject: [PATCH 156/227] minor snapshot fix --- tests/baysor.nf.test.snap | 3 ++- tests/cellpose.nf.test.snap | 3 ++- tests/default.nf.test.snap | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index 245115e..94b09dd 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -334,7 +334,8 @@ "sample_name.zarr/tables/table/varm/.zgroup", "sample_name.zarr/tables/table/varp", "sample_name.zarr/tables/table/varp/.zattrs", - "sample_name.zarr/tables/table/varp/.zgroup" + "sample_name.zarr/tables/table/varp/.zgroup", + "sample_name.zarr/zmetadata" ], [ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 9a30e51..590934c 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -259,7 +259,8 @@ "sample_name.zarr/tables/table/varm/.zgroup", "sample_name.zarr/tables/table/varp", "sample_name.zarr/tables/table/varp/.zattrs", - "sample_name.zarr/tables/table/varp/.zgroup" + "sample_name.zarr/tables/table/varp/.zgroup", + "sample_name.zarr/zmetadata" ], [ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 59ecac1..8ac09c6 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -7,7 +7,7 @@ "sopa": "2.1.2" }, "PATCH_SEGMENTATION_PROSEG": { - "sopa": "2.1.2", + "sopa": "2.1.1", "proseg": "2.0.4" }, "TO_SPATIALDATA": { @@ -330,7 +330,8 @@ "sample_name.zarr/tables/table/varm/.zgroup", "sample_name.zarr/tables/table/varp", "sample_name.zarr/tables/table/varp/.zattrs", - "sample_name.zarr/tables/table/varp/.zgroup" + "sample_name.zarr/tables/table/varp/.zgroup", + "sample_name.zarr/zmetadata" ], [ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", From 1b2d16604554be15f6b0477337cdb1f3399e4c89 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 26 Aug 2025 15:56:00 +0200 Subject: [PATCH 157/227] add comseg support --- conf/test_comseg.config | 64 ++++++++++++++++++++++++++++ modules/local/comseg/environment.yml | 9 ++++ modules/local/comseg/main.nf | 50 ++++++++++++++++++++++ modules/local/sopa_core/main.nf | 2 +- nextflow.config | 1 + nextflow_schema.json | 21 +++++++++ workflows/sopa.nf | 54 +++++++++++++++++++++-- 7 files changed, 197 insertions(+), 4 deletions(-) create mode 100644 conf/test_comseg.config create mode 100644 modules/local/comseg/environment.yml create mode 100644 modules/local/comseg/main.nf diff --git a/conf/test_comseg.config b/conf/test_comseg.config new file mode 100644 index 0000000..72796c6 --- /dev/null +++ b/conf/test_comseg.config @@ -0,0 +1,64 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/sopa -profile test, --outdir + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h', + ] +} + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Input data + input = "${baseDir}/tests/samplesheet.csv" + + read.technology = "toy_dataset" + + + patchify = [ + patch_width_microns: 400, + patch_overlap_microns: 20, + ] + + segmentation.comseg = [ + min_area: 10, + prior_shapes_key: "cells", + config: [ + dict_scale: [ + x: 1, + y: 1, + z: 1, + ], + mean_cell_diameter: 15, + max_cell_radius: 25, + allow_disconnected_polygon: false, + alpha: 0.5, + min_rna_per_cell: 5, + gene_column: "genes", + norm_vector: false, + ], + ] + + aggregate = [ + aggregate_channels: true, + min_transcripts: 5, + ] + + explorer = [ + ram_threshold_gb: 4, + pixel_size: 0.1, + ] +} diff --git a/modules/local/comseg/environment.yml b/modules/local/comseg/environment.yml new file mode 100644 index 0000000..0b9f937 --- /dev/null +++ b/modules/local/comseg/environment.yml @@ -0,0 +1,9 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.10 + - pip=24.3.1 + - pip: + - sopa>=2.1.0 + - comseg>=1.8.2 diff --git a/modules/local/comseg/main.nf b/modules/local/comseg/main.nf new file mode 100644 index 0000000..9de281c --- /dev/null +++ b/modules/local/comseg/main.nf @@ -0,0 +1,50 @@ +process PATCH_SEGMENTATION_COMSEG { + label "process_long" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest-comseg' + : 'docker.io/quentinblampey/sopa:latest-comseg'}" + + input: + tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/transcript_patches/${index}/segmentation_counts.h5ad"), path("${sdata_path}/.sopa_cache/transcript_patches/${index}/segmentation_polygons.json"), val(n_patches) + + script: + """ + sopa segmentation comseg ${sdata_path} --patch-index ${index} ${cli_arguments} + """ +} + +process RESOLVE_COMSEG { + label "process_low" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest-comseg' + : 'docker.io/quentinblampey/sopa:latest-comseg'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/shapes/comseg_boundaries" + path "versions.yml" + + script: + """ + sopa resolve comseg ${sdata_path} ${cli_arguments} + + rm -r ${sdata_path}/.sopa_cache/transcript_patches || true # cleanup large comseg files + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sopa: \$(sopa --version) + comseg: \$(python -c "import comseg; print(comseg.__version__)" 2> /dev/null) + END_VERSIONS + """ +} diff --git a/modules/local/sopa_core/main.nf b/modules/local/sopa_core/main.nf index 7fc8ea2..50c7fac 100644 --- a/modules/local/sopa_core/main.nf +++ b/modules/local/sopa_core/main.nf @@ -22,7 +22,7 @@ process TO_SPATIALDATA { cat <<-END_VERSIONS > versions.yml "${task.process}": - sopa: \$(sopa --version 2> /dev/null) + sopa: \$(sopa --version) spatialdata: \$(python -c "import spatialdata; print(spatialdata.__version__)" 2> /dev/null) spatialdata_io: \$(python -c "import spatialdata_io; print(spatialdata_io.__version__)" 2> /dev/null) END_VERSIONS diff --git a/nextflow.config b/nextflow.config index 988e752..a902cf1 100644 --- a/nextflow.config +++ b/nextflow.config @@ -164,6 +164,7 @@ profiles { } test { includeConfig 'conf/test.config' } test_baysor { includeConfig 'conf/test_baysor.config' } + test_comseg { includeConfig 'conf/test_comseg.config' } test_cellpose { includeConfig 'conf/test_cellpose.config' } test_full { includeConfig 'conf/test_full.config' } } diff --git a/nextflow_schema.json b/nextflow_schema.json index 8426213..2146480 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -99,6 +99,27 @@ "additionalProperties": true, "description": "Dictionary of Baysor parameters." }, + "comseg": { + "type": "object", + "properties": { + "config": { + "type": "object", + "properties": { + "dict_scale": { + "type": "object", + "description": "Comseg dict scale section.", + "fa_icon": "fas fa-gear", + "additionalProperties": true + } + }, + "additionalProperties": true, + "description": "Comseg configuration parameters.", + "fa_icon": "fas fa-gear" + } + }, + "additionalProperties": true, + "description": "Dictionary of Comseg parameters." + }, "cellpose": { "type": "object", "additionalProperties": true, diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 9b9d6ee..377f33a 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -7,6 +7,7 @@ include { paramsSummaryMap } from 'plugin/nf-schema' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_sopa_pipeline' include { PATCH_SEGMENTATION_BAYSOR ; RESOLVE_BAYSOR } from '../modules/local/baysor' +include { PATCH_SEGMENTATION_COMSEG ; RESOLVE_COMSEG } from '../modules/local/comseg' include { PATCH_SEGMENTATION_CELLPOSE ; RESOLVE_CELLPOSE } from '../modules/local/cellpose' include { PATCH_SEGMENTATION_STARDIST ; RESOLVE_STARDIST } from '../modules/local/stardist' include { PATCH_SEGMENTATION_PROSEG } from '../modules/local/proseg' @@ -82,6 +83,15 @@ workflow SOPA { ch_versions = ch_versions.mix(versions) } + if (params.segmentation.comseg) { + ch_input_comseg = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg + + ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_comseg, transcriptPatchesArgs(params, "comseg")) + (ch_resolved, versions) = COMSEG(ch_transcripts_patches, params) + + ch_versions = ch_versions.mix(versions) + } + if (params.segmentation.proseg) { ch_input_proseg = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg @@ -251,15 +261,53 @@ workflow BAYSOR { ch_versions } +workflow COMSEG { + take: + ch_patches + config + + main: + ch_versions = Channel.empty() + + comseg_args = ArgsCLI(config.segmentation.comseg, null, ["config"]) + + ch_patches + .map { meta, sdata_path, patches_file_transcripts -> [meta, sdata_path, patches_file_transcripts.splitText()] } + .flatMap { meta, sdata_path, patches_indices -> patches_indices.collect { index -> [meta, sdata_path, comseg_args, index.trim().toInteger(), patches_indices.size] } } + .set { ch_comseg } + + ch_segmented = PATCH_SEGMENTATION_COMSEG(ch_comseg).map { meta, sdata_path, _out1, _out2, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } + + (ch_resolved, _out, versions) = RESOLVE_COMSEG(ch_segmented, resolveArgs(config)) + + ch_versions = ch_versions.mix(versions) + + emit: + ch_resolved + ch_versions +} + def transcriptPatchesArgs(Map config, String method) { def prior_args = ArgsCLI(config.segmentation[method], null, ["prior_shapes_key", "unassigned_value"]) - return ArgsCLI(config.patchify, "micron") + " " + prior_args + return ArgsCLI(config.patchify, "micron") + ("comseg" in config.segmentation ? " --write-cells-centroids " : " ") + prior_args } def resolveArgs(Map config) { - def gene_column = config.segmentation.baysor.config.data.gene - def min_area = config.segmentation.baysor.min_area ?: 0 + def gene_column + def min_area + + if ("comseg" in config.segmentation) { + gene_column = config.segmentation.comseg.config.gene_column + min_area = config.segmentation.comseg.min_area ?: 0 + } + else if ("baysor" in config.segmentation) { + gene_column = config.segmentation.baysor.config.data.gene + min_area = config.segmentation.baysor.min_area ?: 0 + } + else { + throw new IllegalArgumentException("Unknown segmentation method in config for resolveArgs") + } return "--gene-column ${gene_column} --min-area ${min_area}" } From e0a00849aab6990656c82817aae055277548d8c6 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 30 Sep 2025 09:29:06 +0200 Subject: [PATCH 158/227] singularity on disk large, and disable conda --- .github/workflows/nf-test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nf-test.yml b/.github/workflows/nf-test.yml index e7b5844..b97414c 100644 --- a/.github/workflows/nf-test.yml +++ b/.github/workflows/nf-test.yml @@ -64,11 +64,12 @@ jobs: runs-on: # use self-hosted runners - runs-on=${{ github.run_id }}-nf-test - runner=4cpu-linux-x64 + - disk=large strategy: fail-fast: false matrix: shard: ${{ fromJson(needs.nf-test-changes.outputs.shard) }} - profile: [conda, docker, singularity] + profile: [docker, singularity] # TODO: add conda back, but only for cellpose isMain: - ${{ github.base_ref == 'master' || github.base_ref == 'main' }} # Exclude conda and singularity on dev From a380894bca4f536aef3391add5ef9f5e35fcb9ea Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 30 Sep 2025 10:13:54 +0200 Subject: [PATCH 159/227] update snapshots and minor fixes --- modules/local/sopa_core/main.nf | 6 +-- nextflow.config | 2 +- tests/baysor.nf.test.snap | 6 +-- tests/cellpose.nf.test.snap | 4 +- tests/default.nf.test.snap | 76 ++++++++++++++++++++++----------- workflows/sopa.nf | 10 ++--- 6 files changed, 66 insertions(+), 38 deletions(-) diff --git a/modules/local/sopa_core/main.nf b/modules/local/sopa_core/main.nf index 50c7fac..5c93b27 100644 --- a/modules/local/sopa_core/main.nf +++ b/modules/local/sopa_core/main.nf @@ -9,7 +9,7 @@ process TO_SPATIALDATA { : 'docker.io/quentinblampey/sopa:latest'}" input: - tuple val(meta), path(input_files) + tuple val(meta), path(data_dir), path(other_input_files) val args output: @@ -18,7 +18,7 @@ process TO_SPATIALDATA { script: """ - sopa convert ${meta.data_dir} --sdata-path ${meta.sdata_dir} ${ArgsReaderCLI(args, meta)} + sopa convert ${data_dir} --sdata-path ${meta.sdata_dir} ${ArgsReaderCLI(args, meta)} cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -86,7 +86,7 @@ process MAKE_TRANSCRIPT_PATCHES { val cli_arguments output: - tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/patches_file_transcripts") + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/patches_file_transcripts"), path("${sdata_path}/.sopa_cache/transcript_patches") script: """ diff --git a/nextflow.config b/nextflow.config index a902cf1..aebb9cd 100644 --- a/nextflow.config +++ b/nextflow.config @@ -86,7 +86,7 @@ profiles { shifter.enabled = false charliecloud.enabled = false apptainer.enabled = false - process.containerOptions = '-u $(id -u):$(id -g)' + docker.runOptions = '-u $(id -u):$(id -g)' } arm { process.containerOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index 94b09dd..c6178a4 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -4,15 +4,15 @@ 10, { "RESOLVE_BAYSOR": { - "sopa": "2.1.2", + "sopa": "2.1.4", "baysor": "0.7.1" }, "TANGRAM_ANNOTATION": { - "sopa": "2.1.2", + "sopa": "2.1.4", "tangram": "1.0.4" }, "TO_SPATIALDATA": { - "sopa": "2.1.2", + "sopa": "2.1.4", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 590934c..4fb8f24 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -4,11 +4,11 @@ 9, { "RESOLVE_CELLPOSE": { - "sopa": "2.1.2", + "sopa": "2.1.4", "cellpose": "4.0.6" }, "TO_SPATIALDATA": { - "sopa": "2.1.2", + "sopa": "2.1.4", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 8ac09c6..490fcd2 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -4,14 +4,14 @@ 9, { "FLUO_ANNOTATION": { - "sopa": "2.1.2" + "sopa": "2.1.4" }, "PATCH_SEGMENTATION_PROSEG": { - "sopa": "2.1.1", - "proseg": "2.0.4" + "sopa": "2.1.4", + "proseg": "3.0.8" }, "TO_SPATIALDATA": { - "sopa": "2.1.2", + "sopa": "2.1.4", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, @@ -136,14 +136,17 @@ "sample_name.zarr/tables/table/.zattrs", "sample_name.zarr/tables/table/.zgroup", "sample_name.zarr/tables/table/X", - "sample_name.zarr/tables/table/X/.zarray", "sample_name.zarr/tables/table/X/.zattrs", - "sample_name.zarr/tables/table/X/0", - "sample_name.zarr/tables/table/X/0/0", - "sample_name.zarr/tables/table/X/0/1", - "sample_name.zarr/tables/table/X/1", - "sample_name.zarr/tables/table/X/1/0", - "sample_name.zarr/tables/table/X/1/1", + "sample_name.zarr/tables/table/X/.zgroup", + "sample_name.zarr/tables/table/X/data", + "sample_name.zarr/tables/table/X/data/.zarray", + "sample_name.zarr/tables/table/X/data/0", + "sample_name.zarr/tables/table/X/indices", + "sample_name.zarr/tables/table/X/indices/.zarray", + "sample_name.zarr/tables/table/X/indices/0", + "sample_name.zarr/tables/table/X/indptr", + "sample_name.zarr/tables/table/X/indptr/.zarray", + "sample_name.zarr/tables/table/X/indptr/0", "sample_name.zarr/tables/table/layers", "sample_name.zarr/tables/table/layers/.zattrs", "sample_name.zarr/tables/table/layers/.zgroup", @@ -182,22 +185,14 @@ "sample_name.zarr/tables/table/obs/centroid_z/.zarray", "sample_name.zarr/tables/table/obs/centroid_z/.zattrs", "sample_name.zarr/tables/table/obs/centroid_z/0", - "sample_name.zarr/tables/table/obs/cluster", - "sample_name.zarr/tables/table/obs/cluster/.zarray", - "sample_name.zarr/tables/table/obs/cluster/.zattrs", - "sample_name.zarr/tables/table/obs/cluster/0", - "sample_name.zarr/tables/table/obs/fov", - "sample_name.zarr/tables/table/obs/fov/.zarray", - "sample_name.zarr/tables/table/obs/fov/.zattrs", - "sample_name.zarr/tables/table/obs/fov/0", + "sample_name.zarr/tables/table/obs/component", + "sample_name.zarr/tables/table/obs/component/.zarray", + "sample_name.zarr/tables/table/obs/component/.zattrs", + "sample_name.zarr/tables/table/obs/component/0", "sample_name.zarr/tables/table/obs/original_cell_id", "sample_name.zarr/tables/table/obs/original_cell_id/.zarray", "sample_name.zarr/tables/table/obs/original_cell_id/.zattrs", "sample_name.zarr/tables/table/obs/original_cell_id/0", - "sample_name.zarr/tables/table/obs/population", - "sample_name.zarr/tables/table/obs/population/.zarray", - "sample_name.zarr/tables/table/obs/population/.zattrs", - "sample_name.zarr/tables/table/obs/population/0", "sample_name.zarr/tables/table/obs/region", "sample_name.zarr/tables/table/obs/region/.zattrs", "sample_name.zarr/tables/table/obs/region/.zgroup", @@ -224,6 +219,10 @@ "sample_name.zarr/tables/table/obs/slide/codes/.zarray", "sample_name.zarr/tables/table/obs/slide/codes/.zattrs", "sample_name.zarr/tables/table/obs/slide/codes/0", + "sample_name.zarr/tables/table/obs/surface_area", + "sample_name.zarr/tables/table/obs/surface_area/.zarray", + "sample_name.zarr/tables/table/obs/surface_area/.zattrs", + "sample_name.zarr/tables/table/obs/surface_area/0", "sample_name.zarr/tables/table/obs/volume", "sample_name.zarr/tables/table/obs/volume/.zarray", "sample_name.zarr/tables/table/obs/volume/.zattrs", @@ -288,6 +287,21 @@ "sample_name.zarr/tables/table/uns", "sample_name.zarr/tables/table/uns/.zattrs", "sample_name.zarr/tables/table/uns/.zgroup", + "sample_name.zarr/tables/table/uns/proseg_run", + "sample_name.zarr/tables/table/uns/proseg_run/.zattrs", + "sample_name.zarr/tables/table/uns/proseg_run/.zgroup", + "sample_name.zarr/tables/table/uns/proseg_run/args", + "sample_name.zarr/tables/table/uns/proseg_run/args/.zarray", + "sample_name.zarr/tables/table/uns/proseg_run/args/.zattrs", + "sample_name.zarr/tables/table/uns/proseg_run/args/0", + "sample_name.zarr/tables/table/uns/proseg_run/duration", + "sample_name.zarr/tables/table/uns/proseg_run/duration/.zarray", + "sample_name.zarr/tables/table/uns/proseg_run/duration/.zattrs", + "sample_name.zarr/tables/table/uns/proseg_run/duration/0", + "sample_name.zarr/tables/table/uns/proseg_run/version", + "sample_name.zarr/tables/table/uns/proseg_run/version/.zarray", + "sample_name.zarr/tables/table/uns/proseg_run/version/.zattrs", + "sample_name.zarr/tables/table/uns/proseg_run/version/0", "sample_name.zarr/tables/table/uns/sopa_attrs", "sample_name.zarr/tables/table/uns/sopa_attrs/.zattrs", "sample_name.zarr/tables/table/uns/sopa_attrs/.zgroup", @@ -325,6 +339,18 @@ "sample_name.zarr/tables/table/var/_index/.zarray", "sample_name.zarr/tables/table/var/_index/.zattrs", "sample_name.zarr/tables/table/var/_index/0", + "sample_name.zarr/tables/table/var/gene", + "sample_name.zarr/tables/table/var/gene/.zarray", + "sample_name.zarr/tables/table/var/gene/.zattrs", + "sample_name.zarr/tables/table/var/gene/0", + "sample_name.zarr/tables/table/var/lambda_bg_0", + "sample_name.zarr/tables/table/var/lambda_bg_0/.zarray", + "sample_name.zarr/tables/table/var/lambda_bg_0/.zattrs", + "sample_name.zarr/tables/table/var/lambda_bg_0/0", + "sample_name.zarr/tables/table/var/total_count", + "sample_name.zarr/tables/table/var/total_count/.zarray", + "sample_name.zarr/tables/table/var/total_count/.zattrs", + "sample_name.zarr/tables/table/var/total_count/0", "sample_name.zarr/tables/table/varm", "sample_name.zarr/tables/table/varm/.zattrs", "sample_name.zarr/tables/table/varm/.zgroup", @@ -359,6 +385,8 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab" ] ], @@ -366,6 +394,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-08-01T16:12:05.246211" + "timestamp": "2025-09-30T10:10:20.139347" } } \ No newline at end of file diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 377f33a..deae6a2 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -40,12 +40,12 @@ workflow SOPA { if (params.read.technology == "visium_hd") { (ch_input_spatialdata, versions) = SPACERANGER(ch_samplesheet) - ch_input_spatialdata = ch_input_spatialdata.map { meta, out -> [meta, [out[0].toString().replaceFirst(/(.*?outs).*/, '$1'), meta.image]] } + ch_input_spatialdata = ch_input_spatialdata.map { meta, out -> [meta, meta.data_dir, [out[0].toString().replaceFirst(/(.*?outs).*/, '$1'), meta.image]] } ch_versions = ch_versions.mix(versions) } else { - ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.data_dir] } + ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.data_dir, []] } } (ch_spatialdata, versions) = TO_SPATIALDATA(ch_input_spatialdata, params.read) @@ -96,7 +96,7 @@ workflow SOPA { ch_input_proseg = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, transcriptPatchesArgs(params, "proseg")) - (ch_resolved, versions) = PROSEG(ch_proseg_patches.map { meta, sdata_path, _file -> [meta, sdata_path] }, params) + (ch_resolved, versions) = PROSEG(ch_proseg_patches.map { meta, sdata_path, _file, _patches -> [meta, sdata_path] }, params) ch_versions = ch_versions.mix(versions) } @@ -246,7 +246,7 @@ workflow BAYSOR { baysor_args = ArgsCLI(config.segmentation.baysor, null, ["config"]) ch_patches - .map { meta, sdata_path, patches_file_transcripts -> [meta, sdata_path, patches_file_transcripts.splitText()] } + .map { meta, sdata_path, patches_file_transcripts, _patches -> [meta, sdata_path, patches_file_transcripts.splitText()] } .flatMap { meta, sdata_path, patches_indices -> patches_indices.collect { index -> [meta, sdata_path, baysor_args, index.trim().toInteger(), patches_indices.size] } } .set { ch_baysor } @@ -272,7 +272,7 @@ workflow COMSEG { comseg_args = ArgsCLI(config.segmentation.comseg, null, ["config"]) ch_patches - .map { meta, sdata_path, patches_file_transcripts -> [meta, sdata_path, patches_file_transcripts.splitText()] } + .map { meta, sdata_path, patches_file_transcripts, _patches -> [meta, sdata_path, patches_file_transcripts.splitText()] } .flatMap { meta, sdata_path, patches_indices -> patches_indices.collect { index -> [meta, sdata_path, comseg_args, index.trim().toInteger(), patches_indices.size] } } .set { ch_comseg } From 5d052eeb9c59cebc1592b51d3a8ed1ad1de3a534 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 30 Sep 2025 12:20:30 +0200 Subject: [PATCH 160/227] update regarding mashehu review --- README.md | 2 +- assets/schema_input.json | 24 +++++------ docs/output.md | 42 ++++++++++++++++--- docs/usage.md | 31 +++++++++++--- modules/local/baysor/environment.yml | 4 +- modules/local/cellpose/environment.yml | 4 +- modules/local/comseg/environment.yml | 6 +-- .../environment.yml | 5 +-- modules/local/fluo_annotation/main.nf | 27 ++++++++++++ modules/local/proseg/environment.yml | 4 +- modules/local/sopa_core/environment.yml | 4 +- modules/local/stardist/environment.yml | 4 +- .../local/tangram_annotation/environment.yml | 9 ++++ .../main.nf | 28 ------------- ro-crate-metadata.json | 2 +- workflows/environment.yml | 4 +- workflows/sopa.nf | 3 +- 17 files changed, 131 insertions(+), 72 deletions(-) rename modules/local/{annotation => fluo_annotation}/environment.yml (55%) create mode 100644 modules/local/fluo_annotation/main.nf create mode 100644 modules/local/tangram_annotation/environment.yml rename modules/local/{annotation => tangram_annotation}/main.nf (55%) diff --git a/README.md b/README.md index 745a506..fec8b1c 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ After running `nf-core/sopa`, you can continue analyzing your `SpatialData` obje > [!NOTE] > If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data. -First, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example: +First, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-of-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example: `samplesheet.csv`: diff --git a/assets/schema_input.json b/assets/schema_input.json index a829f96..0b60344 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -30,34 +30,34 @@ }, "cytaimage": { "type": "string", - "pattern": "^\\S+$", + "pattern": "^\\S+(tif|tiff)$", "format": "path", "exists": true, - "errorMessage": "Path to the cytaimage file must exist and not contain spaces", + "errorMessage": "Path to the cytaimage file must exist, not contain spaces, and be a .tif or .tiff file", "meta": ["cytaimage"] }, "colorizedimage": { "type": "string", - "pattern": "^\\S+$", + "pattern": "^\\S+(tif|tiff|jpg|jpeg)$", "format": "path", "exists": true, - "errorMessage": "Path to the colorizedimage file must exist and not contain spaces", + "errorMessage": "Path to the colorizedimage file must exist, not contain spaces, and be a .tif, .tiff, .jpg or .jpeg file", "meta": ["colorizedimage"] }, "darkimage": { "type": "string", - "pattern": "^\\S+$", + "pattern": "^\\S+(tif|tiff|jpg|jpeg)$", "format": "path", "exists": true, - "errorMessage": "Path to the darkimage file must exist and not contain spaces", + "errorMessage": "Path to the darkimage file must exist, not contain spaces, and be a .tif, .tiff, .jpg or .jpeg file", "meta": ["darkimage"] }, "image": { "type": "string", - "pattern": "^\\S+$", + "pattern": "^\\S+(tif|tiff|jpg|jpeg)$", "format": "path", "exists": true, - "errorMessage": "Path to the image must exist and not contain spaces", + "errorMessage": "Path to the image must exist, not contain spaces, and be a .tif, .tiff, .jpg or .jpeg file", "meta": ["image"] }, "slide": { @@ -74,18 +74,18 @@ }, "manual_alignment": { "type": "string", - "pattern": "^\\S+$", + "pattern": "^\\S+json$", "format": "path", "exists": true, - "errorMessage": "Path to the manual_alignment file must exist and not contain spaces", + "errorMessage": "Path to the manual_alignment must exist, not contain spaces, and be a .json file", "meta": ["manual_alignment"] }, "slidefile": { "type": "string", - "pattern": "^\\S+$", + "pattern": "^\\S+json$", "format": "path", "exists": true, - "errorMessage": "Path to the slidefile must exist and not contain spaces", + "errorMessage": "Path to the slidefile must exist, not contain spaces, and be a .json file", "meta": ["slidefile"] } } diff --git a/docs/output.md b/docs/output.md index a1099b8..bcf45e3 100644 --- a/docs/output.md +++ b/docs/output.md @@ -6,16 +6,48 @@ This document describes the output produced by the pipeline. The directories listed below will be created in the results directory after the pipeline has finished. All paths are relative to the top-level results directory. -1. A `{sample}.zarr` directory containing a [SpatialData](https://spatialdata.scverse.org/en/stable/) object, where the `sample` name is either (i) specified by the samplesheet, or (ii) based on the name of the corresponding input directory. Refer to the [SpatialData docs](https://spatialdata.scverse.org/en/stable/) for usage details, or to the [documentation of `sopa` as a Python package](https://gustaveroussy.github.io/sopa/). If you are not familiar with `SpatialData`, you can also use directly the extracted `AnnData` object (see below). -2. A `{sample}.explorer` for visualization and quick analysis. It contains a `report.html` with Sopa quality controls, `adata.h5ad` the AnnData object (extracted from the above SpatialData object), and `experiment.xenium` (double-click on it to open it on the Xenium Explorer ; you can download the software [here](https://www.10xgenomics.com/support/software/xenium-explorer/downloads)). The other files are data files related and required by the Xenium Explorer. -3. **(Only for Visium HD)** a `{sample}_spaceranger/outs` directory with the outputs of Space Ranger. - ## Pipeline overview -The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes data using the following steps: +The pipeline is built using [Nextflow](https://www.nextflow.io/) and outputs the following information: +- [SpatialData directory](#spatialdata-directory) - Full [SpatialData](https://spatialdata.scverse.org/en/stable/) object with the segmented and aggregated data. +- [Explorer directory](#explorer-directory) - Visualization and quick analysis directory +- [VisiumHD-specific outputs](#visiumhd-specific-outputs) - Outputs of Space Ranger - [Pipeline information](#pipeline-information) - Report metrics generated during the workflow execution +### SpatialData directory + +
    +Output files + +- `{sample}.zarr/` + - Spatial elements: `images/`, `shapes/`, `tables/`, `points/`, ... + +
    + +The `{sample}.zarr` directory contains a [SpatialData](https://spatialdata.scverse.org/en/stable/) object, where the `sample` name is either (i) specified by the samplesheet, or (ii) based on the name of the corresponding input directory. + +Refer to the [SpatialData docs](https://spatialdata.scverse.org/en/stable/) for usage details, or to the [documentation of `sopa` as a Python package](https://gustaveroussy.github.io/sopa/). If you are not familiar with `SpatialData`, you can also use directly the extracted `AnnData` object (see below). + +### Explorer directory + +
    +Output files + +- `{sample}.explorer/` + - Sopa quality controls: `report.html` + - AnnData object (extracted from the above SpatialData object): `adata.h5ad` + - Xenium Explorer file: `experiment.xenium`. Double-click on it to open it on the Xenium Explorer; you can download the software [here](https://www.10xgenomics.com/support/software/xenium-explorer/downloads). + - Other files related and required by the Xenium Explorer. + +
    + +The `{sample}.explorer` directory can be used for visualization and quick analysis. + +### VisiumHD-specific outputs + +**(Only for Visium HD)** a `{sample}_spaceranger/outs` directory with the outputs of Space Ranger. See [the official 10X Genomics documentation](https://www.10xgenomics.com/support/software/space-ranger/latest/analysis/outputs/output-overview) for more details. + ### Pipeline information
    diff --git a/docs/usage.md b/docs/usage.md index 1e35b82..e1f70e9 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -14,29 +14,48 @@ You will need to create a samplesheet with information about the samples you wou ### Main technologies -For most technologies (i.e., all technologies supported by Sopa except Visium HD), the samplesheet lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example: +For most technologies (i.e., all technologies supported by Sopa except Visium HD), the samplesheet lists the `data_path` to each sample data directory, and optionally a `sample` column to choose the name of the output directories. + +| Column | Description | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `data_path` | **Path to the raw data**; a directory containing the output of the Xenium/MERSCOPE/etc with the data of a single sample or region. Typically, this directory contains one or multiple image(s), and a transcript file (`.csv` or `.parquet`) for transcriptomics technologies. See more details [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-of-sopa)). _Required_ | +| `sample` | **Custom sample ID (optional)**; designates the sample ID; must be unique for each patient. It will be used in the output directories names: `{sample}.zarr` and `{sample}.explorer`. _Optional, Default: the basename of `data_path` (i.e., the last directory component of `data_path`)_ | + +Here is a samplesheet example for two samples: `samplesheet.csv`: ```csv title="samplesheet.csv" sample,data_path SAMPLE1,/path/to/one/merscope_directory -SAMPLE2,/path/to/one/merscope_directory +SAMPLE2,/path/to/another/merscope_directory ``` ### Visium HD -Some extra columns need to be provided specifically for Visium HD. This is because we need to run [Space Ranger](https://www.10xgenomics.com/support/software/space-ranger/latest) before running Sopa. +Some extra columns need to be provided specifically for Visium HD. This is because we need to run [Space Ranger](https://www.10xgenomics.com/support/software/space-ranger/latest) before running Sopa. Note that the `image` is the full-resolution microscopy image (not the cytassist image) and is **required** by Sopa as we'll run cell segmentation on the H&E full-resolution slide. For more details, see the [`spaceranger-count` arguments](https://nf-co.re/modules/spaceranger_count). + +| Column | Description | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `sample` | **Sample ID name**; designates the sample ID; must be unique for each slide. It will be used in the output directories names: `{sample}.zarr` and `{sample}.explorer`. _Required_ | +| `fastq_dir` | Path to directory where the sample FASTQ files are stored. May be a `.tar.gz` file instead of a directory. _Required_ | +| `image` | Brightfield microscopy image. _Required_ | +| `cytaimage` | Brightfield tissue image captured with Cytassist device. _Required_ | +| `slide` | The Visium slide ID used for the sequencing. _Required_ | +| `area` | Which slide area contains the tissue sample. _Required_ | +| `manual_alignment` | Path to the manual alignment file. _Optional_ | +| `slidefile` | Slide specification as JSON. Overrides `slide` and `area` if specified. _Optional_ | +| `colorizedimage` | A colour composite of one or more fluorescence image channels saved as a single-page, single-file colour TIFF or JPEG. _Optional_ | +| `darkimage` | Dark background fluorescence microscopy image. _Optional_ | -For each row, you'll need a `sample` name, its corresponding `fastq_dir`, `image`, `cytaimage`, `slide`, and `area`. Note that the `image` is the full-resolution microscopy image (not the cytassist image) and is **required** by Sopa as we'll run cell segmentation on the H&E full-resolution slide. -For more details, see the [`spaceranger-count` arguments](https://nf-co.re/modules/spaceranger_count). +Here is a samplesheet example for one sample: ```csv title="samplesheet.csv" sample,fastq_dir,image,cytaimage,slide,area Visium_HD_Human_Lung_Cancer_Fixed_Frozen,Visium_HD_Human_Lung_Cancer_Fixed_Frozen_fastqs,Visium_HD_Human_Lung_Cancer_Fixed_Frozen_tissue_image.btf,Visium_HD_Human_Lung_Cancer_Fixed_Frozen_image.tif,H1-TY834G7,D1 ``` -The above samplesheet is made for [this public sample](https://www.10xgenomics.com/datasets/visium-hd-cytassist-gene-expression-human-lung-cancer-fixed-frozen) (download all the "Input files" and untar the `fastq` zip file). +This samplesheet was made for [this public sample](https://www.10xgenomics.com/datasets/visium-hd-cytassist-gene-expression-human-lung-cancer-fixed-frozen) (download all the "Input files" and untar the `fastq` zip file to test it). ## Sopa parameters diff --git a/modules/local/baysor/environment.yml b/modules/local/baysor/environment.yml index 550408d..1fc290a 100644 --- a/modules/local/baysor/environment.yml +++ b/modules/local/baysor/environment.yml @@ -2,7 +2,7 @@ channels: - conda-forge - bioconda dependencies: - - python=3.10 + - python=3.11 - pip=24.3.1 - pip: - - sopa[baysor]>=2.1.0 + - sopa[baysor]==2.1.4 diff --git a/modules/local/cellpose/environment.yml b/modules/local/cellpose/environment.yml index 53ac2fe..6135203 100644 --- a/modules/local/cellpose/environment.yml +++ b/modules/local/cellpose/environment.yml @@ -2,7 +2,7 @@ channels: - conda-forge - bioconda dependencies: - - python=3.10 + - python=3.11 - pip=24.3.1 - pip: - - sopa[cellpose]>=2.1.0 + - sopa[cellpose]==2.1.4 diff --git a/modules/local/comseg/environment.yml b/modules/local/comseg/environment.yml index 0b9f937..15791ed 100644 --- a/modules/local/comseg/environment.yml +++ b/modules/local/comseg/environment.yml @@ -2,8 +2,8 @@ channels: - conda-forge - bioconda dependencies: - - python=3.10 + - python=3.11 - pip=24.3.1 - pip: - - sopa>=2.1.0 - - comseg>=1.8.2 + - sopa==2.1.4 + - comseg==1.8.2 diff --git a/modules/local/annotation/environment.yml b/modules/local/fluo_annotation/environment.yml similarity index 55% rename from modules/local/annotation/environment.yml rename to modules/local/fluo_annotation/environment.yml index 3f61240..c171fea 100644 --- a/modules/local/annotation/environment.yml +++ b/modules/local/fluo_annotation/environment.yml @@ -2,8 +2,7 @@ channels: - conda-forge - bioconda dependencies: - - python=3.10 + - python=3.11 - pip=24.3.1 - pip: - - sopa>=2.1.0 - - tangram-sc>=1.0.4 + - sopa==2.1.4 diff --git a/modules/local/fluo_annotation/main.nf b/modules/local/fluo_annotation/main.nf new file mode 100644 index 0000000..f70f66c --- /dev/null +++ b/modules/local/fluo_annotation/main.nf @@ -0,0 +1,27 @@ +process FLUO_ANNOTATION { + label "process_medium" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/tables/table/obs" + path "versions.yml" + + script: + """ + sopa annotate fluorescence ${sdata_path} ${cli_arguments} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sopa: \$(sopa --version) + END_VERSIONS + """ +} diff --git a/modules/local/proseg/environment.yml b/modules/local/proseg/environment.yml index 4f963ad..c171fea 100644 --- a/modules/local/proseg/environment.yml +++ b/modules/local/proseg/environment.yml @@ -2,7 +2,7 @@ channels: - conda-forge - bioconda dependencies: - - python=3.10 + - python=3.11 - pip=24.3.1 - pip: - - sopa>=2.1.0 + - sopa==2.1.4 diff --git a/modules/local/sopa_core/environment.yml b/modules/local/sopa_core/environment.yml index 4f963ad..c171fea 100644 --- a/modules/local/sopa_core/environment.yml +++ b/modules/local/sopa_core/environment.yml @@ -2,7 +2,7 @@ channels: - conda-forge - bioconda dependencies: - - python=3.10 + - python=3.11 - pip=24.3.1 - pip: - - sopa>=2.1.0 + - sopa==2.1.4 diff --git a/modules/local/stardist/environment.yml b/modules/local/stardist/environment.yml index 233c322..b044675 100644 --- a/modules/local/stardist/environment.yml +++ b/modules/local/stardist/environment.yml @@ -2,7 +2,7 @@ channels: - conda-forge - bioconda dependencies: - - python=3.10 + - python=3.11 - pip=24.3.1 - pip: - - sopa[stardist]>=2.1.0 + - sopa[stardist]==2.1.4 diff --git a/modules/local/tangram_annotation/environment.yml b/modules/local/tangram_annotation/environment.yml new file mode 100644 index 0000000..789aacf --- /dev/null +++ b/modules/local/tangram_annotation/environment.yml @@ -0,0 +1,9 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.11 + - pip=24.3.1 + - pip: + - sopa==2.1.4 + - tangram-sc==1.0.4 diff --git a/modules/local/annotation/main.nf b/modules/local/tangram_annotation/main.nf similarity index 55% rename from modules/local/annotation/main.nf rename to modules/local/tangram_annotation/main.nf index b82d7aa..2bab0fe 100644 --- a/modules/local/annotation/main.nf +++ b/modules/local/tangram_annotation/main.nf @@ -27,31 +27,3 @@ process TANGRAM_ANNOTATION { END_VERSIONS """ } - -process FLUO_ANNOTATION { - label "process_medium" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - input: - tuple val(meta), path(sdata_path) - val cli_arguments - - output: - tuple val(meta), path(sdata_path) - path "${sdata_path}/tables/table/obs" - path "versions.yml" - - script: - """ - sopa annotate fluorescence ${sdata_path} ${cli_arguments} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sopa: \$(sopa --version) - END_VERSIONS - """ -} diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 30ceed0..d8cbd98 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "Stable", "datePublished": "2025-07-22T07:34:52+00:00", - "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n> [!WARNING]\n> If you are interested in the main Sopa python package, refer to [this Sopa repository](https://github.com/gustaveroussy/sopa). Else, if you want to use Nextflow, you are in the good place.\n\n

    \n \"sopa_overview\"\n

    \n\n1. (Visium HD only) Raw data processing with Space Ranger\n2. (Optional) Tissue segmentation\n3. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n4. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n5. (Optional) Cell-type annotation\n6. User-friendly output creation for visualization and quick analysis\n7. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://github.com/gustaveroussy/sopa).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-or-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose the Sopa parameters. You can find existing Sopa params files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n -params-file \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n> [!WARNING]\n> If you are interested in the main Sopa python package, refer to [this Sopa repository](https://github.com/gustaveroussy/sopa). Else, if you want to use Nextflow, you are in the good place.\n\n

    \n \"sopa_overview\"\n

    \n\n1. (Visium HD only) Raw data processing with Space Ranger\n2. (Optional) Tissue segmentation\n3. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n4. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n5. (Optional) Cell-type annotation\n6. User-friendly output creation for visualization and quick analysis\n7. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://github.com/gustaveroussy/sopa).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-of-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose the Sopa parameters. You can find existing Sopa params files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n -params-file \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" diff --git a/workflows/environment.yml b/workflows/environment.yml index 1fd551b..c171fea 100644 --- a/workflows/environment.yml +++ b/workflows/environment.yml @@ -2,7 +2,7 @@ channels: - conda-forge - bioconda dependencies: - - python=3.10 + - python=3.11 - pip=24.3.1 - pip: - - sopa>=2.0.3 + - sopa==2.1.4 diff --git a/workflows/sopa.nf b/workflows/sopa.nf index deae6a2..71fd989 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -21,7 +21,8 @@ include { EXPLORER_RAW ; REPORT } from '../modules/local/sopa_core' -include { TANGRAM_ANNOTATION ; FLUO_ANNOTATION } from '../modules/local/annotation' +include { TANGRAM_ANNOTATION } from '../modules/local/tangram_annotation' +include { FLUO_ANNOTATION } from '../modules/local/fluo_annotation' include { ArgsCLI ; ArgsReaderCLI } from '../modules/local/utils' include { SPACERANGER } from '../subworkflows/local/spaceranger' /* From bcd298c245070b0985cc1e1ea17e4f674923de2a Mon Sep 17 00:00:00 2001 From: Quentin Blampey <33903498+quentinblampey@users.noreply.github.com> Date: Tue, 30 Sep 2025 12:20:56 +0200 Subject: [PATCH 161/227] Update conf/test.config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- conf/test.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/test.config b/conf/test.config index 4ab64c4..4c02f5c 100644 --- a/conf/test.config +++ b/conf/test.config @@ -19,8 +19,8 @@ process { } params { - config_profile_name = 'Test profile with Proseg' - config_profile_description = 'Minimal test dataset to check pipeline function' + config_profile_name = 'Test profile with Proseg' +config_profile_description = 'Minimal test dataset to check pipeline function' // Input data input = "${baseDir}/tests/samplesheet.csv" From 931a75bbe861fa203c5a8572531992818e5ddefa Mon Sep 17 00:00:00 2001 From: Quentin Blampey <33903498+quentinblampey@users.noreply.github.com> Date: Tue, 30 Sep 2025 12:21:06 +0200 Subject: [PATCH 162/227] Update conf/base.config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- conf/base.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/base.config b/conf/base.config index 93a3ee6..53ee460 100644 --- a/conf/base.config +++ b/conf/base.config @@ -44,7 +44,7 @@ process { memory = { 200.GB * task.attempt } } withName:PATCH_SEGMENTATION_PROSEG { - cpus = { 8 * task.attempt } + cpus = { 8 * task.attempt } memory = { 200.GB * task.attempt } time = { 10.d * task.attempt } } From e50c4054c8126bddd7d0c8a8e53d20dfd257f5e9 Mon Sep 17 00:00:00 2001 From: Quentin Blampey <33903498+quentinblampey@users.noreply.github.com> Date: Tue, 30 Sep 2025 12:21:20 +0200 Subject: [PATCH 163/227] Update conf/test_baysor.config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- conf/test_baysor.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test_baysor.config b/conf/test_baysor.config index 292feab..6b69dd4 100644 --- a/conf/test_baysor.config +++ b/conf/test_baysor.config @@ -5,7 +5,7 @@ Defines input files and everything required to run a fast and simple pipeline test. Use as follows: - nextflow run nf-core/sopa -profile test, --outdir + nextflow run nf-core/sopa -profile test_baysor, --outdir ---------------------------------------------------------------------------------------- */ From 59f8b5172f0da7dc5a2be01da453e6d6ded778ac Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 30 Sep 2025 12:23:34 +0200 Subject: [PATCH 164/227] minor cleanup: comment in test configs --- conf/test_baysor.config | 1 - conf/test_cellpose.config | 2 +- conf/test_comseg.config | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/conf/test_baysor.config b/conf/test_baysor.config index 6b69dd4..0f4a3b9 100644 --- a/conf/test_baysor.config +++ b/conf/test_baysor.config @@ -27,7 +27,6 @@ params { read.technology = "toy_dataset" - patchify = [ patch_width_microns: 400, patch_overlap_microns: 20, diff --git a/conf/test_cellpose.config b/conf/test_cellpose.config index e02a7d5..0351f7e 100644 --- a/conf/test_cellpose.config +++ b/conf/test_cellpose.config @@ -5,7 +5,7 @@ Defines input files and everything required to run a fast and simple pipeline test. Use as follows: - nextflow run nf-core/sopa -profile test, --outdir + nextflow run nf-core/sopa -profile test_cellpose, --outdir ---------------------------------------------------------------------------------------- */ diff --git a/conf/test_comseg.config b/conf/test_comseg.config index 72796c6..e79d265 100644 --- a/conf/test_comseg.config +++ b/conf/test_comseg.config @@ -5,7 +5,7 @@ Defines input files and everything required to run a fast and simple pipeline test. Use as follows: - nextflow run nf-core/sopa -profile test, --outdir + nextflow run nf-core/sopa -profile test_comseg, --outdir ---------------------------------------------------------------------------------------- */ @@ -19,7 +19,7 @@ process { } params { - config_profile_name = 'Test profile' + config_profile_name = 'Test profile with Comseg' config_profile_description = 'Minimal test dataset to check pipeline function' // Input data From a4d120485e8600800d4d48f932b61394d50f0bf5 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 30 Sep 2025 15:13:10 +0200 Subject: [PATCH 165/227] revert docker options --- nextflow.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nextflow.config b/nextflow.config index aebb9cd..a902cf1 100644 --- a/nextflow.config +++ b/nextflow.config @@ -86,7 +86,7 @@ profiles { shifter.enabled = false charliecloud.enabled = false apptainer.enabled = false - docker.runOptions = '-u $(id -u):$(id -g)' + process.containerOptions = '-u $(id -u):$(id -g)' } arm { process.containerOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' From c805c8057e9af6a693de6efafa8ec27941ecebca Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 30 Sep 2025 15:47:24 +0200 Subject: [PATCH 166/227] try containerOptions only for docker --- conf/modules.config | 4 ---- nextflow.config | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 8a3188e..8f67c34 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -19,8 +19,4 @@ process { saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } - - withName: PATCH_SEGMENTATION_CELLPOSE { - containerOptions = '' - } } diff --git a/nextflow.config b/nextflow.config index a902cf1..72c4d92 100644 --- a/nextflow.config +++ b/nextflow.config @@ -87,6 +87,11 @@ profiles { charliecloud.enabled = false apptainer.enabled = false process.containerOptions = '-u $(id -u):$(id -g)' + process { + withName: PATCH_SEGMENTATION_CELLPOSE { + containerOptions = '' + } + } } arm { process.containerOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' From e42156efbb8d7ffe59a408aca542e0a406218c4f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 30 Sep 2025 16:24:11 +0200 Subject: [PATCH 167/227] try make singularity writable --- conf/modules.config | 4 ++++ nextflow.config | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 8f67c34..8a3188e 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -19,4 +19,8 @@ process { saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } + + withName: PATCH_SEGMENTATION_CELLPOSE { + containerOptions = '' + } } diff --git a/nextflow.config b/nextflow.config index 72c4d92..97f44a2 100644 --- a/nextflow.config +++ b/nextflow.config @@ -87,11 +87,6 @@ profiles { charliecloud.enabled = false apptainer.enabled = false process.containerOptions = '-u $(id -u):$(id -g)' - process { - withName: PATCH_SEGMENTATION_CELLPOSE { - containerOptions = '' - } - } } arm { process.containerOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' @@ -105,6 +100,11 @@ profiles { shifter.enabled = false charliecloud.enabled = false apptainer.enabled = false + process { + withName: PATCH_SEGMENTATION_CELLPOSE { + containerOptions = '--writable-tmpfs' + } + } } podman { podman.enabled = true From 147b35ea2527c91a8de96eee6c39310a802d42a6 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 1 Oct 2025 10:02:00 +0200 Subject: [PATCH 168/227] try to specify the cellpose cache location --- conf/modules.config | 2 +- nextflow.config | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 8a3188e..f0aa4a1 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -21,6 +21,6 @@ process { } withName: PATCH_SEGMENTATION_CELLPOSE { - containerOptions = '' + containerOptions = '-e CELLPOSE_LOCAL_MODELS_PATH=/tmp/cellpose_cache' } } diff --git a/nextflow.config b/nextflow.config index 97f44a2..a902cf1 100644 --- a/nextflow.config +++ b/nextflow.config @@ -100,11 +100,6 @@ profiles { shifter.enabled = false charliecloud.enabled = false apptainer.enabled = false - process { - withName: PATCH_SEGMENTATION_CELLPOSE { - containerOptions = '--writable-tmpfs' - } - } } podman { podman.enabled = true From e4ded3953893e521ca387fb9e4036c4af339df0e Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 1 Oct 2025 10:21:29 +0200 Subject: [PATCH 169/227] try setting cellpose cache in cwd and give more precise proseg inputs --- conf/modules.config | 2 +- modules/local/proseg/main.nf | 2 +- workflows/sopa.nf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index f0aa4a1..709a680 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -21,6 +21,6 @@ process { } withName: PATCH_SEGMENTATION_CELLPOSE { - containerOptions = '-e CELLPOSE_LOCAL_MODELS_PATH=/tmp/cellpose_cache' + containerOptions = '-e CELLPOSE_LOCAL_MODELS_PATH=./cellpose_cache' } } diff --git a/modules/local/proseg/main.nf b/modules/local/proseg/main.nf index 71d61c6..788b8fb 100644 --- a/modules/local/proseg/main.nf +++ b/modules/local/proseg/main.nf @@ -10,7 +10,7 @@ process PATCH_SEGMENTATION_PROSEG { : 'docker.io/quentinblampey/sopa:latest-proseg'}" input: - tuple val(meta), path(sdata_path) + tuple val(meta), path(sdata_path), path(patches_file_transcripts), path(transcript_patches) val cli_arguments output: diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 71fd989..589d0a2 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -97,7 +97,7 @@ workflow SOPA { ch_input_proseg = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, transcriptPatchesArgs(params, "proseg")) - (ch_resolved, versions) = PROSEG(ch_proseg_patches.map { meta, sdata_path, _file, _patches -> [meta, sdata_path] }, params) + (ch_resolved, versions) = PROSEG(ch_proseg_patches, params) ch_versions = ch_versions.mix(versions) } From 06dbdc378b6efc4305f1e1e54c252a63b18ee589 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 1 Oct 2025 10:55:20 +0200 Subject: [PATCH 170/227] try using TMPDIR --- conf/modules.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index 709a680..77d607c 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -21,6 +21,6 @@ process { } withName: PATCH_SEGMENTATION_CELLPOSE { - containerOptions = '-e CELLPOSE_LOCAL_MODELS_PATH=./cellpose_cache' + containerOptions = '--env CELLPOSE_LOCAL_MODELS_PATH="$TMPDIR"' } } From 044bf8fc1f926ec1ecc364d4fe689a333a548a1a Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 1 Oct 2025 12:02:45 +0200 Subject: [PATCH 171/227] try containall option for singularity --- conf/modules.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index 77d607c..fcc57a6 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -21,6 +21,6 @@ process { } withName: PATCH_SEGMENTATION_CELLPOSE { - containerOptions = '--env CELLPOSE_LOCAL_MODELS_PATH="$TMPDIR"' + containerOptions = '--containall' } } From ed0659bf12534f6cd9b6d1c5a8d5bb74b4992405 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 1 Oct 2025 12:25:50 +0200 Subject: [PATCH 172/227] try export celpose cache loc in process --- conf/modules.config | 4 ---- modules/local/cellpose/main.nf | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index fcc57a6..8f67c34 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -19,8 +19,4 @@ process { saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } - - withName: PATCH_SEGMENTATION_CELLPOSE { - containerOptions = '--containall' - } } diff --git a/modules/local/cellpose/main.nf b/modules/local/cellpose/main.nf index 55ce5c6..00844ef 100644 --- a/modules/local/cellpose/main.nf +++ b/modules/local/cellpose/main.nf @@ -17,6 +17,9 @@ process PATCH_SEGMENTATION_CELLPOSE { script: """ + mkdir ./cellpose_cache + export CELLPOSE_LOCAL_MODELS_PATH=./cellpose_cache + sopa segmentation cellpose ${sdata_path} --patch-index ${index} ${cli_arguments} """ } From d83d49c1023e07d50c70cd47009a3524f320983f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 2 Oct 2025 17:33:24 +0200 Subject: [PATCH 173/227] split modules and start answer to the review --- docs/usage.md | 15 +- .../{proseg => aggregate}/environment.yml | 0 modules/local/aggregate/main.nf | 21 ++ modules/local/cellpose/main.nf | 53 ----- .../{sopa_core => explorer}/environment.yml | 0 modules/local/explorer/main.nf | 26 +++ .../local/explorer_raw}/environment.yml | 0 modules/local/explorer_raw/main.nf | 23 +++ .../local/make_image_patches/environment.yml | 8 + modules/local/make_image_patches/main.nf | 21 ++ .../make_transcript_patches/environment.yml | 8 + modules/local/make_transcript_patches/main.nf | 20 ++ .../environment.yml | 0 .../local/patch_segmentation_baysor/main.nf | 21 ++ .../environment.yml | 0 .../local/patch_segmentation_cellpose/main.nf | 22 ++ .../environment.yml | 0 .../local/patch_segmentation_comseg/main.nf | 19 ++ .../patch_segmentation_proseg/environment.yml | 8 + .../main.nf | 3 - .../environment.yml | 0 .../local/patch_segmentation_stardist/main.nf | 19 ++ modules/local/report/environment.yml | 8 + modules/local/report/main.nf | 23 +++ modules/local/resolve_baysor/environment.yml | 8 + .../local/{baysor => resolve_baysor}/main.nf | 22 -- .../local/resolve_cellpose/environment.yml | 8 + modules/local/resolve_cellpose/main.nf | 27 +++ modules/local/resolve_comseg/environment.yml | 9 + .../local/{comseg => resolve_comseg}/main.nf | 20 -- .../local/resolve_stardist/environment.yml | 8 + .../{stardist => resolve_stardist}/main.nf | 23 --- modules/local/sopa_core/main.nf | 192 ------------------ .../local/tissue_segmentation/environment.yml | 8 + modules/local/tissue_segmentation/main.nf | 21 ++ modules/local/to_spatialdata/environment.yml | 8 + modules/local/to_spatialdata/main.nf | 30 +++ nextflow.config | 6 +- nextflow_schema.json | 16 +- tests/README.md | 31 --- workflows/sopa.nf | 35 ++-- 41 files changed, 420 insertions(+), 370 deletions(-) rename modules/local/{proseg => aggregate}/environment.yml (100%) create mode 100644 modules/local/aggregate/main.nf delete mode 100644 modules/local/cellpose/main.nf rename modules/local/{sopa_core => explorer}/environment.yml (100%) create mode 100644 modules/local/explorer/main.nf rename {workflows => modules/local/explorer_raw}/environment.yml (100%) create mode 100644 modules/local/explorer_raw/main.nf create mode 100644 modules/local/make_image_patches/environment.yml create mode 100644 modules/local/make_image_patches/main.nf create mode 100644 modules/local/make_transcript_patches/environment.yml create mode 100644 modules/local/make_transcript_patches/main.nf rename modules/local/{baysor => patch_segmentation_baysor}/environment.yml (100%) create mode 100644 modules/local/patch_segmentation_baysor/main.nf rename modules/local/{cellpose => patch_segmentation_cellpose}/environment.yml (100%) create mode 100644 modules/local/patch_segmentation_cellpose/main.nf rename modules/local/{comseg => patch_segmentation_comseg}/environment.yml (100%) create mode 100644 modules/local/patch_segmentation_comseg/main.nf create mode 100644 modules/local/patch_segmentation_proseg/environment.yml rename modules/local/{proseg => patch_segmentation_proseg}/main.nf (93%) rename modules/local/{stardist => patch_segmentation_stardist}/environment.yml (100%) create mode 100644 modules/local/patch_segmentation_stardist/main.nf create mode 100644 modules/local/report/environment.yml create mode 100644 modules/local/report/main.nf create mode 100644 modules/local/resolve_baysor/environment.yml rename modules/local/{baysor => resolve_baysor}/main.nf (51%) create mode 100644 modules/local/resolve_cellpose/environment.yml create mode 100644 modules/local/resolve_cellpose/main.nf create mode 100644 modules/local/resolve_comseg/environment.yml rename modules/local/{comseg => resolve_comseg}/main.nf (53%) create mode 100644 modules/local/resolve_stardist/environment.yml rename modules/local/{stardist => resolve_stardist}/main.nf (50%) delete mode 100644 modules/local/sopa_core/main.nf create mode 100644 modules/local/tissue_segmentation/environment.yml create mode 100644 modules/local/tissue_segmentation/main.nf create mode 100644 modules/local/to_spatialdata/environment.yml create mode 100644 modules/local/to_spatialdata/main.nf delete mode 100644 tests/README.md diff --git a/docs/usage.md b/docs/usage.md index e1f70e9..7f26a40 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -14,12 +14,17 @@ You will need to create a samplesheet with information about the samples you wou ### Main technologies -For most technologies (i.e., all technologies supported by Sopa except Visium HD), the samplesheet lists the `data_path` to each sample data directory, and optionally a `sample` column to choose the name of the output directories. +For all technologies supported by Sopa, the samplesheet lists the `data_path` to each sample data directory, and optionally a `sample` column to choose the name of the output directories. -| Column | Description | -| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `data_path` | **Path to the raw data**; a directory containing the output of the Xenium/MERSCOPE/etc with the data of a single sample or region. Typically, this directory contains one or multiple image(s), and a transcript file (`.csv` or `.parquet`) for transcriptomics technologies. See more details [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-of-sopa)). _Required_ | -| `sample` | **Custom sample ID (optional)**; designates the sample ID; must be unique for each patient. It will be used in the output directories names: `{sample}.zarr` and `{sample}.explorer`. _Optional, Default: the basename of `data_path` (i.e., the last directory component of `data_path`)_ | +> [!NOTE] +> For **Visium HD only**, the samplesheet is different, please refer to the next section instead. + +The concerned technologies are: `xenium`, `merscope`, `cosmx`, `molecular_cartography`, `macsima`, `phenocycler`, `ome_tif`, and `hyperion`. + +| Column | Description | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `data_path` | **Path to the raw data**; a directory containing the output of the machine with the data of a single sample or region. Typically, this directory contains one or multiple image(s), and a transcript file (`.csv` or `.parquet`) for transcriptomics technologies. See more details [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-of-sopa)). _Required_ | +| `sample` | **Custom sample ID (optional)**; designates the sample ID; must be unique for each patient. It will be used in the output directories names: `{sample}.zarr` and `{sample}.explorer`. _Optional, Default: the basename of `data_path` (i.e., the last directory component of `data_path`)_ | Here is a samplesheet example for two samples: diff --git a/modules/local/proseg/environment.yml b/modules/local/aggregate/environment.yml similarity index 100% rename from modules/local/proseg/environment.yml rename to modules/local/aggregate/environment.yml diff --git a/modules/local/aggregate/main.nf b/modules/local/aggregate/main.nf new file mode 100644 index 0000000..8b79ce5 --- /dev/null +++ b/modules/local/aggregate/main.nf @@ -0,0 +1,21 @@ +process AGGREGATE { + label "process_medium" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/tables/table" + + script: + """ + sopa aggregate ${sdata_path} ${cli_arguments} + """ +} diff --git a/modules/local/cellpose/main.nf b/modules/local/cellpose/main.nf deleted file mode 100644 index 00844ef..0000000 --- a/modules/local/cellpose/main.nf +++ /dev/null @@ -1,53 +0,0 @@ -include { ArgsCLI } from '../../../modules/local/utils' - - -process PATCH_SEGMENTATION_CELLPOSE { - label "process_single" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-cellpose' - : 'docker.io/quentinblampey/sopa:latest-cellpose'}" - - input: - tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) - - output: - tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/cellpose_boundaries/${index}.parquet"), val(n_patches) - - script: - """ - mkdir ./cellpose_cache - export CELLPOSE_LOCAL_MODELS_PATH=./cellpose_cache - - sopa segmentation cellpose ${sdata_path} --patch-index ${index} ${cli_arguments} - """ -} - -process RESOLVE_CELLPOSE { - label "process_low" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-cellpose' - : 'docker.io/quentinblampey/sopa:latest-cellpose'}" - - input: - tuple val(meta), path(sdata_path) - - output: - tuple val(meta), path(sdata_path) - path "${sdata_path}/shapes/cellpose_boundaries" - path "versions.yml" - - script: - """ - sopa resolve cellpose ${sdata_path} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sopa: \$(sopa --version) - cellpose: \$(cellpose --version | grep 'cellpose version:' | head -n1 | awk '{print \$3}') - END_VERSIONS - """ -} diff --git a/modules/local/sopa_core/environment.yml b/modules/local/explorer/environment.yml similarity index 100% rename from modules/local/sopa_core/environment.yml rename to modules/local/explorer/environment.yml diff --git a/modules/local/explorer/main.nf b/modules/local/explorer/main.nf new file mode 100644 index 0000000..1a06e6e --- /dev/null +++ b/modules/local/explorer/main.nf @@ -0,0 +1,26 @@ +process EXPLORER { + label "process_high" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + publishDir "${params.outdir}", mode: params.publish_dir_mode + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + path "${meta.explorer_dir}/experiment.xenium" + path "${meta.explorer_dir}/analysis.zarr.zip" + path "${meta.explorer_dir}/cell_feature_matrix.zarr.zip" + path "${meta.explorer_dir}/adata.h5ad" + path "${meta.explorer_dir}/cells.zarr.zip" + + script: + """ + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "-it" + """ +} diff --git a/workflows/environment.yml b/modules/local/explorer_raw/environment.yml similarity index 100% rename from workflows/environment.yml rename to modules/local/explorer_raw/environment.yml diff --git a/modules/local/explorer_raw/main.nf b/modules/local/explorer_raw/main.nf new file mode 100644 index 0000000..f5abdf5 --- /dev/null +++ b/modules/local/explorer_raw/main.nf @@ -0,0 +1,23 @@ +process EXPLORER_RAW { + label "process_high" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + publishDir "${params.outdir}", mode: params.publish_dir_mode + + input: + tuple val(meta), path(sdata_path), path(data_dir) + val cli_arguments + + output: + path "${meta.explorer_dir}/morphology*" + path "${meta.explorer_dir}/transcripts*", optional: true + + script: + """ + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "+it" --no-save-h5ad + """ +} diff --git a/modules/local/make_image_patches/environment.yml b/modules/local/make_image_patches/environment.yml new file mode 100644 index 0000000..c171fea --- /dev/null +++ b/modules/local/make_image_patches/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.11 + - pip=24.3.1 + - pip: + - sopa==2.1.4 diff --git a/modules/local/make_image_patches/main.nf b/modules/local/make_image_patches/main.nf new file mode 100644 index 0000000..5ebd706 --- /dev/null +++ b/modules/local/make_image_patches/main.nf @@ -0,0 +1,21 @@ +process MAKE_IMAGE_PATCHES { + label "process_single" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/patches_file_image") + path "${sdata_path}/shapes/image_patches" + + script: + """ + sopa patchify image ${sdata_path} ${cli_arguments} + """ +} diff --git a/modules/local/make_transcript_patches/environment.yml b/modules/local/make_transcript_patches/environment.yml new file mode 100644 index 0000000..c171fea --- /dev/null +++ b/modules/local/make_transcript_patches/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.11 + - pip=24.3.1 + - pip: + - sopa==2.1.4 diff --git a/modules/local/make_transcript_patches/main.nf b/modules/local/make_transcript_patches/main.nf new file mode 100644 index 0000000..203e48e --- /dev/null +++ b/modules/local/make_transcript_patches/main.nf @@ -0,0 +1,20 @@ +process MAKE_TRANSCRIPT_PATCHES { + label "process_medium" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/patches_file_transcripts"), path("${sdata_path}/.sopa_cache/transcript_patches") + + script: + """ + sopa patchify transcripts ${sdata_path} ${cli_arguments} + """ +} diff --git a/modules/local/baysor/environment.yml b/modules/local/patch_segmentation_baysor/environment.yml similarity index 100% rename from modules/local/baysor/environment.yml rename to modules/local/patch_segmentation_baysor/environment.yml diff --git a/modules/local/patch_segmentation_baysor/main.nf b/modules/local/patch_segmentation_baysor/main.nf new file mode 100644 index 0000000..92c4966 --- /dev/null +++ b/modules/local/patch_segmentation_baysor/main.nf @@ -0,0 +1,21 @@ +process PATCH_SEGMENTATION_BAYSOR { + label "process_long" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest-baysor' + : 'docker.io/quentinblampey/sopa:latest-baysor'}" + + input: + tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/transcript_patches/${index}/segmentation_counts.loom"), val(n_patches) + + script: + """ + export JULIA_NUM_THREADS=${task.cpus} # parallelize within each patch for Baysor >= v0.7 + + sopa segmentation baysor ${sdata_path} --patch-index ${index} ${cli_arguments} + """ +} diff --git a/modules/local/cellpose/environment.yml b/modules/local/patch_segmentation_cellpose/environment.yml similarity index 100% rename from modules/local/cellpose/environment.yml rename to modules/local/patch_segmentation_cellpose/environment.yml diff --git a/modules/local/patch_segmentation_cellpose/main.nf b/modules/local/patch_segmentation_cellpose/main.nf new file mode 100644 index 0000000..9d6fa81 --- /dev/null +++ b/modules/local/patch_segmentation_cellpose/main.nf @@ -0,0 +1,22 @@ +process PATCH_SEGMENTATION_CELLPOSE { + label "process_single" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest-cellpose' + : 'docker.io/quentinblampey/sopa:latest-cellpose'}" + + input: + tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/cellpose_boundaries/${index}.parquet"), val(n_patches) + + script: + """ + mkdir ./cellpose_cache + export CELLPOSE_LOCAL_MODELS_PATH=./cellpose_cache + + sopa segmentation cellpose ${sdata_path} --patch-index ${index} ${cli_arguments} + """ +} diff --git a/modules/local/comseg/environment.yml b/modules/local/patch_segmentation_comseg/environment.yml similarity index 100% rename from modules/local/comseg/environment.yml rename to modules/local/patch_segmentation_comseg/environment.yml diff --git a/modules/local/patch_segmentation_comseg/main.nf b/modules/local/patch_segmentation_comseg/main.nf new file mode 100644 index 0000000..7f0d9fe --- /dev/null +++ b/modules/local/patch_segmentation_comseg/main.nf @@ -0,0 +1,19 @@ +process PATCH_SEGMENTATION_COMSEG { + label "process_long" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest-comseg' + : 'docker.io/quentinblampey/sopa:latest-comseg'}" + + input: + tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/transcript_patches/${index}/segmentation_counts.h5ad"), path("${sdata_path}/.sopa_cache/transcript_patches/${index}/segmentation_polygons.json"), val(n_patches) + + script: + """ + sopa segmentation comseg ${sdata_path} --patch-index ${index} ${cli_arguments} + """ +} diff --git a/modules/local/patch_segmentation_proseg/environment.yml b/modules/local/patch_segmentation_proseg/environment.yml new file mode 100644 index 0000000..c171fea --- /dev/null +++ b/modules/local/patch_segmentation_proseg/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.11 + - pip=24.3.1 + - pip: + - sopa==2.1.4 diff --git a/modules/local/proseg/main.nf b/modules/local/patch_segmentation_proseg/main.nf similarity index 93% rename from modules/local/proseg/main.nf rename to modules/local/patch_segmentation_proseg/main.nf index 788b8fb..bf35741 100644 --- a/modules/local/proseg/main.nf +++ b/modules/local/patch_segmentation_proseg/main.nf @@ -1,6 +1,3 @@ -include { ArgsCLI } from '../../../modules/local/utils' - - process PATCH_SEGMENTATION_PROSEG { label "process_high" diff --git a/modules/local/stardist/environment.yml b/modules/local/patch_segmentation_stardist/environment.yml similarity index 100% rename from modules/local/stardist/environment.yml rename to modules/local/patch_segmentation_stardist/environment.yml diff --git a/modules/local/patch_segmentation_stardist/main.nf b/modules/local/patch_segmentation_stardist/main.nf new file mode 100644 index 0000000..a95b7db --- /dev/null +++ b/modules/local/patch_segmentation_stardist/main.nf @@ -0,0 +1,19 @@ +process PATCH_SEGMENTATION_STARDIST { + label "process_single" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest-stardist' + : 'docker.io/quentinblampey/sopa:latest-stardist'}" + + input: + tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) + + output: + tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/stardist_boundaries/${index}.parquet"), val(n_patches) + + script: + """ + sopa segmentation stardist ${sdata_path} --patch-index ${index} ${cli_arguments} + """ +} diff --git a/modules/local/report/environment.yml b/modules/local/report/environment.yml new file mode 100644 index 0000000..c171fea --- /dev/null +++ b/modules/local/report/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.11 + - pip=24.3.1 + - pip: + - sopa==2.1.4 diff --git a/modules/local/report/main.nf b/modules/local/report/main.nf new file mode 100644 index 0000000..9b8e5a3 --- /dev/null +++ b/modules/local/report/main.nf @@ -0,0 +1,23 @@ +process REPORT { + label "process_medium" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + publishDir "${params.outdir}", mode: params.publish_dir_mode + + input: + tuple val(meta), path(sdata_path) + + output: + path "${meta.explorer_dir}/analysis_summary.html" + + script: + """ + mkdir -p ${meta.explorer_dir} + + sopa report ${sdata_path} ${meta.explorer_dir}/analysis_summary.html + """ +} diff --git a/modules/local/resolve_baysor/environment.yml b/modules/local/resolve_baysor/environment.yml new file mode 100644 index 0000000..1fc290a --- /dev/null +++ b/modules/local/resolve_baysor/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.11 + - pip=24.3.1 + - pip: + - sopa[baysor]==2.1.4 diff --git a/modules/local/baysor/main.nf b/modules/local/resolve_baysor/main.nf similarity index 51% rename from modules/local/baysor/main.nf rename to modules/local/resolve_baysor/main.nf index a348e29..b599b3e 100644 --- a/modules/local/baysor/main.nf +++ b/modules/local/resolve_baysor/main.nf @@ -1,25 +1,3 @@ -process PATCH_SEGMENTATION_BAYSOR { - label "process_long" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-baysor' - : 'docker.io/quentinblampey/sopa:latest-baysor'}" - - input: - tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) - - output: - tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/transcript_patches/${index}/segmentation_counts.loom"), val(n_patches) - - script: - """ - export JULIA_NUM_THREADS=${task.cpus} # parallelize within each patch for Baysor >= v0.7 - - sopa segmentation baysor ${sdata_path} --patch-index ${index} ${cli_arguments} - """ -} - process RESOLVE_BAYSOR { label "process_low" diff --git a/modules/local/resolve_cellpose/environment.yml b/modules/local/resolve_cellpose/environment.yml new file mode 100644 index 0000000..6135203 --- /dev/null +++ b/modules/local/resolve_cellpose/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.11 + - pip=24.3.1 + - pip: + - sopa[cellpose]==2.1.4 diff --git a/modules/local/resolve_cellpose/main.nf b/modules/local/resolve_cellpose/main.nf new file mode 100644 index 0000000..f05ce75 --- /dev/null +++ b/modules/local/resolve_cellpose/main.nf @@ -0,0 +1,27 @@ +process RESOLVE_CELLPOSE { + label "process_low" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest-cellpose' + : 'docker.io/quentinblampey/sopa:latest-cellpose'}" + + input: + tuple val(meta), path(sdata_path) + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/shapes/cellpose_boundaries" + path "versions.yml" + + script: + """ + sopa resolve cellpose ${sdata_path} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sopa: \$(sopa --version) + cellpose: \$(cellpose --version | grep 'cellpose version:' | head -n1 | awk '{print \$3}') + END_VERSIONS + """ +} diff --git a/modules/local/resolve_comseg/environment.yml b/modules/local/resolve_comseg/environment.yml new file mode 100644 index 0000000..15791ed --- /dev/null +++ b/modules/local/resolve_comseg/environment.yml @@ -0,0 +1,9 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.11 + - pip=24.3.1 + - pip: + - sopa==2.1.4 + - comseg==1.8.2 diff --git a/modules/local/comseg/main.nf b/modules/local/resolve_comseg/main.nf similarity index 53% rename from modules/local/comseg/main.nf rename to modules/local/resolve_comseg/main.nf index 9de281c..07f534c 100644 --- a/modules/local/comseg/main.nf +++ b/modules/local/resolve_comseg/main.nf @@ -1,23 +1,3 @@ -process PATCH_SEGMENTATION_COMSEG { - label "process_long" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-comseg' - : 'docker.io/quentinblampey/sopa:latest-comseg'}" - - input: - tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) - - output: - tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/transcript_patches/${index}/segmentation_counts.h5ad"), path("${sdata_path}/.sopa_cache/transcript_patches/${index}/segmentation_polygons.json"), val(n_patches) - - script: - """ - sopa segmentation comseg ${sdata_path} --patch-index ${index} ${cli_arguments} - """ -} - process RESOLVE_COMSEG { label "process_low" diff --git a/modules/local/resolve_stardist/environment.yml b/modules/local/resolve_stardist/environment.yml new file mode 100644 index 0000000..b044675 --- /dev/null +++ b/modules/local/resolve_stardist/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.11 + - pip=24.3.1 + - pip: + - sopa[stardist]==2.1.4 diff --git a/modules/local/stardist/main.nf b/modules/local/resolve_stardist/main.nf similarity index 50% rename from modules/local/stardist/main.nf rename to modules/local/resolve_stardist/main.nf index 7c33ac5..31ce7d9 100644 --- a/modules/local/stardist/main.nf +++ b/modules/local/resolve_stardist/main.nf @@ -1,26 +1,3 @@ -include { ArgsCLI } from '../../../modules/local/utils' - - -process PATCH_SEGMENTATION_STARDIST { - label "process_single" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-stardist' - : 'docker.io/quentinblampey/sopa:latest-stardist'}" - - input: - tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) - - output: - tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/stardist_boundaries/${index}.parquet"), val(n_patches) - - script: - """ - sopa segmentation stardist ${sdata_path} --patch-index ${index} ${cli_arguments} - """ -} - process RESOLVE_STARDIST { label "process_low" diff --git a/modules/local/sopa_core/main.nf b/modules/local/sopa_core/main.nf deleted file mode 100644 index 5c93b27..0000000 --- a/modules/local/sopa_core/main.nf +++ /dev/null @@ -1,192 +0,0 @@ -include { ArgsReaderCLI } from '../utils' - -process TO_SPATIALDATA { - label "process_high" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - input: - tuple val(meta), path(data_dir), path(other_input_files) - val args - - output: - tuple val(meta), path("${meta.sdata_dir}") - path "versions.yml" - - script: - """ - sopa convert ${data_dir} --sdata-path ${meta.sdata_dir} ${ArgsReaderCLI(args, meta)} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - sopa: \$(sopa --version) - spatialdata: \$(python -c "import spatialdata; print(spatialdata.__version__)" 2> /dev/null) - spatialdata_io: \$(python -c "import spatialdata_io; print(spatialdata_io.__version__)" 2> /dev/null) - END_VERSIONS - """ -} - -process TISSUE_SEGMENTATION { - label "process_low" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - input: - tuple val(meta), path(sdata_path) - val cli_arguments - - output: - tuple val(meta), path(sdata_path) - path "${sdata_path}/shapes/region_of_interest" - - script: - """ - sopa segmentation tissue ${sdata_path} ${cli_arguments} - """ -} - -process MAKE_IMAGE_PATCHES { - label "process_single" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - input: - tuple val(meta), path(sdata_path) - val cli_arguments - - output: - tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/patches_file_image") - path "${sdata_path}/shapes/image_patches" - - script: - """ - sopa patchify image ${sdata_path} ${cli_arguments} - """ -} - -process MAKE_TRANSCRIPT_PATCHES { - label "process_medium" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - input: - tuple val(meta), path(sdata_path) - val cli_arguments - - output: - tuple val(meta), path(sdata_path), path("${sdata_path}/.sopa_cache/patches_file_transcripts"), path("${sdata_path}/.sopa_cache/transcript_patches") - - script: - """ - sopa patchify transcripts ${sdata_path} ${cli_arguments} - """ -} - -process AGGREGATE { - label "process_medium" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - input: - tuple val(meta), path(sdata_path) - val cli_arguments - - output: - tuple val(meta), path(sdata_path) - path "${sdata_path}/tables/table" - - script: - """ - sopa aggregate ${sdata_path} ${cli_arguments} - """ -} - -process EXPLORER_RAW { - label "process_high" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - publishDir "${params.outdir}", mode: params.publish_dir_mode - - input: - tuple val(meta), path(sdata_path), path(data_dir) - val cli_arguments - - output: - path "${meta.explorer_dir}/morphology*" - path "${meta.explorer_dir}/transcripts*", optional: true - - script: - """ - sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "+it" --no-save-h5ad - """ -} - -process EXPLORER { - label "process_high" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - publishDir "${params.outdir}", mode: params.publish_dir_mode - - input: - tuple val(meta), path(sdata_path) - val cli_arguments - - output: - path "${meta.explorer_dir}/experiment.xenium" - path "${meta.explorer_dir}/analysis.zarr.zip" - path "${meta.explorer_dir}/cell_feature_matrix.zarr.zip" - path "${meta.explorer_dir}/adata.h5ad" - path "${meta.explorer_dir}/cells.zarr.zip" - - script: - """ - sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "-it" - """ -} - -process REPORT { - label "process_medium" - - conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" - - publishDir "${params.outdir}", mode: params.publish_dir_mode - - input: - tuple val(meta), path(sdata_path) - - output: - path "${meta.explorer_dir}/analysis_summary.html" - - script: - """ - mkdir -p ${meta.explorer_dir} - - sopa report ${sdata_path} ${meta.explorer_dir}/analysis_summary.html - """ -} diff --git a/modules/local/tissue_segmentation/environment.yml b/modules/local/tissue_segmentation/environment.yml new file mode 100644 index 0000000..c171fea --- /dev/null +++ b/modules/local/tissue_segmentation/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.11 + - pip=24.3.1 + - pip: + - sopa==2.1.4 diff --git a/modules/local/tissue_segmentation/main.nf b/modules/local/tissue_segmentation/main.nf new file mode 100644 index 0000000..3c6ea0f --- /dev/null +++ b/modules/local/tissue_segmentation/main.nf @@ -0,0 +1,21 @@ +process TISSUE_SEGMENTATION { + label "process_low" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/shapes/region_of_interest" + + script: + """ + sopa segmentation tissue ${sdata_path} ${cli_arguments} + """ +} diff --git a/modules/local/to_spatialdata/environment.yml b/modules/local/to_spatialdata/environment.yml new file mode 100644 index 0000000..c171fea --- /dev/null +++ b/modules/local/to_spatialdata/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.11 + - pip=24.3.1 + - pip: + - sopa==2.1.4 diff --git a/modules/local/to_spatialdata/main.nf b/modules/local/to_spatialdata/main.nf new file mode 100644 index 0000000..e38d521 --- /dev/null +++ b/modules/local/to_spatialdata/main.nf @@ -0,0 +1,30 @@ +include { ArgsReaderCLI } from '../utils' + +process TO_SPATIALDATA { + label "process_high" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:latest' + : 'docker.io/quentinblampey/sopa:latest'}" + + input: + tuple val(meta), path(data_dir), path(other_input_files) + val args + + output: + tuple val(meta), path("${meta.sdata_dir}") + path "versions.yml" + + script: + """ + sopa convert ${data_dir} --sdata-path ${meta.sdata_dir} ${ArgsReaderCLI(args, meta)} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sopa: \$(sopa --version) + spatialdata: \$(python -c "import spatialdata; print(spatialdata.__version__)" 2> /dev/null) + spatialdata_io: \$(python -c "import spatialdata_io; print(spatialdata_io.__version__)" 2> /dev/null) + END_VERSIONS + """ +} diff --git a/nextflow.config b/nextflow.config index a902cf1..d28e680 100644 --- a/nextflow.config +++ b/nextflow.config @@ -86,10 +86,10 @@ profiles { shifter.enabled = false charliecloud.enabled = false apptainer.enabled = false - process.containerOptions = '-u $(id -u):$(id -g)' + docker.runOptions = '-u $(id -u):$(id -g)' } arm { - process.containerOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' + docker.runOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' } singularity { singularity.enabled = true @@ -158,7 +158,7 @@ profiles { } } gpu { - process.containerOptions = '-u $(id -u):$(id -g) --gpus all' + docker.runOptions = '-u $(id -u):$(id -g) --gpus all' apptainer.runOptions = '--nv' singularity.runOptions = '--nv' } diff --git a/nextflow_schema.json b/nextflow_schema.json index 2146480..4060128 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -39,7 +39,7 @@ } }, "sopa_config": { - "title": "Sopa config (a.k.a. params file)", + "title": "Sopa config (or params file)", "type": "object", "fa_icon": "fas fa-rocket", "description": "Parameters related to Sopa", @@ -52,7 +52,19 @@ "technology": { "type": "string", "description": "Technology used for the spatial data, e.g., 'xenium', 'merscope', ...", - "fa_icon": "fas fa-microscope" + "fa_icon": "fas fa-microscope", + "enum": [ + "xenium", + "merscope", + "cosmx", + "visium_hd", + "molecular_cartography", + "macsima", + "phenocycler", + "hyperion", + "ome_tif", + "toy_dataset" + ] }, "kwargs": { "type": "object", diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 8c07078..0000000 --- a/tests/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# Tests - -> [!NOTE] -> The `samplesheet.csv` is technology-agnostic, and uses synthetic data generated when running the pipeline. The samplesheet uses a fake data path to make sure the path exists, but then it generates the dataset on-the-fly. - -## Visium HD specific case - -There is an exception for Visium HD data, as it requires to run SpaceRanger before Sopa, and the corresponding samplesheet require more arguments. - -The `samplesheet_visium_hd.csv` is made for [this sample](https://www.10xgenomics.com/datasets/visium-hd-cytassist-gene-expression-human-lung-cancer-fixed-frozen). The corresponding data can be downloading via: - -```sh -mkdir Visium_HD_Human_Lung_Cancer_Fixed_Frozen -cd Visium_HD_Human_Lung_Cancer_Fixed_Frozen - -# Input Files -curl -O https://cf.10xgenomics.com/samples/spatial-exp/3.1.1/Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_image.tif -curl -O https://cf.10xgenomics.com/samples/spatial-exp/3.1.1/Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_tissue_image.btf -curl -O https://cf.10xgenomics.com/samples/spatial-exp/3.1.1/Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_alignment_file.json -curl -O https://s3-us-west-2.amazonaws.com/10x.files/samples/spatial-exp/3.1.1/Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_fastqs.tar -curl -O https://cf.10xgenomics.com/samples/spatial-exp/3.1.1/Visium_HD_Human_Lung_Cancer_Fixed_Frozen/Visium_HD_Human_Lung_Cancer_Fixed_Frozen_probe_set.csv - -# untar FASTQs -tar xvf Visium_HD_Human_Lung_Cancer_Fixed_Frozen_fastqs.tar -``` - -You can download the official 10X Genomics probe sets [here](https://www.10xgenomics.com/support/software/space-ranger/downloads). - -``` -https://cf.10xgenomics.com/supp/spatial-exp/probeset/Visium_Human_Transcriptome_Probe_Set_v2.0_GRCh38-2020-A.csv -``` diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 589d0a2..54ea042 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -6,25 +6,28 @@ include { paramsSummaryMap } from 'plugin/nf-schema' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_sopa_pipeline' -include { PATCH_SEGMENTATION_BAYSOR ; RESOLVE_BAYSOR } from '../modules/local/baysor' -include { PATCH_SEGMENTATION_COMSEG ; RESOLVE_COMSEG } from '../modules/local/comseg' -include { PATCH_SEGMENTATION_CELLPOSE ; RESOLVE_CELLPOSE } from '../modules/local/cellpose' -include { PATCH_SEGMENTATION_STARDIST ; RESOLVE_STARDIST } from '../modules/local/stardist' -include { PATCH_SEGMENTATION_PROSEG } from '../modules/local/proseg' -include { - TO_SPATIALDATA ; - TISSUE_SEGMENTATION ; - MAKE_IMAGE_PATCHES ; - MAKE_TRANSCRIPT_PATCHES ; - AGGREGATE ; - EXPLORER ; - EXPLORER_RAW ; - REPORT -} from '../modules/local/sopa_core' + +include { TO_SPATIALDATA } from '../modules/local/to_spatialdata' +include { MAKE_IMAGE_PATCHES } from '../modules/local/make_image_patches' +include { MAKE_TRANSCRIPT_PATCHES } from '../modules/local/make_transcript_patches' +include { TISSUE_SEGMENTATION } from '../modules/local/tissue_segmentation' +include { PATCH_SEGMENTATION_BAYSOR } from '../modules/local/patch_segmentation_baysor' +include { PATCH_SEGMENTATION_COMSEG } from '../modules/local/patch_segmentation_comseg' +include { PATCH_SEGMENTATION_CELLPOSE } from '../modules/local/patch_segmentation_cellpose' +include { PATCH_SEGMENTATION_STARDIST } from '../modules/local/patch_segmentation_stardist' +include { PATCH_SEGMENTATION_PROSEG } from '../modules/local/patch_segmentation_proseg' +include { RESOLVE_BAYSOR } from '../modules/local/resolve_baysor' +include { RESOLVE_COMSEG } from '../modules/local/resolve_comseg' +include { RESOLVE_CELLPOSE } from '../modules/local/resolve_cellpose' +include { RESOLVE_STARDIST } from '../modules/local/resolve_stardist' +include { AGGREGATE } from '../modules/local/aggregate' +include { EXPLORER } from '../modules/local/explorer' +include { EXPLORER_RAW } from '../modules/local/explorer_raw' +include { REPORT } from '../modules/local/report' include { TANGRAM_ANNOTATION } from '../modules/local/tangram_annotation' include { FLUO_ANNOTATION } from '../modules/local/fluo_annotation' -include { ArgsCLI ; ArgsReaderCLI } from '../modules/local/utils' include { SPACERANGER } from '../subworkflows/local/spaceranger' +include { ArgsCLI ; ArgsReaderCLI } from '../modules/local/utils' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW From 3e39d972ce9713e637341bf5e95d39f3ac63eb0f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 2 Oct 2025 17:45:10 +0200 Subject: [PATCH 174/227] point to another dummy input for the tests as dataset is created on the fly --- tests/samplesheet.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/samplesheet.csv b/tests/samplesheet.csv index e88d6f7..5f0dd9c 100644 --- a/tests/samplesheet.csv +++ b/tests/samplesheet.csv @@ -1,2 +1,2 @@ sample,data_path -sample_name,https://github.com/nf-core/sopa/blob/dev/tests/README.md +sample_name,https://github.com/nf-core/sopa/blob/dev/tests/samplesheet.csv From ff0a3652c526d361275b148cea0d201e72139709 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 14 Oct 2025 09:36:51 +0200 Subject: [PATCH 175/227] set sopa version 2.1.5 and add scanpy_preprocess + remove publish --- modules/local/aggregate/environment.yml | 2 +- modules/local/aggregate/main.nf | 4 +-- modules/local/explorer/environment.yml | 2 +- modules/local/explorer/main.nf | 4 +-- modules/local/explorer_raw/environment.yml | 2 +- modules/local/explorer_raw/main.nf | 4 +-- modules/local/fluo_annotation/environment.yml | 2 +- modules/local/fluo_annotation/main.nf | 4 +-- .../local/make_image_patches/environment.yml | 2 +- modules/local/make_image_patches/main.nf | 4 +-- .../make_transcript_patches/environment.yml | 2 +- modules/local/make_transcript_patches/main.nf | 4 +-- .../patch_segmentation_baysor/environment.yml | 2 +- .../local/patch_segmentation_baysor/main.nf | 4 +-- .../environment.yml | 2 +- .../local/patch_segmentation_cellpose/main.nf | 4 +-- .../patch_segmentation_comseg/environment.yml | 2 +- .../local/patch_segmentation_comseg/main.nf | 4 +-- .../patch_segmentation_proseg/environment.yml | 2 +- .../local/patch_segmentation_proseg/main.nf | 4 +-- .../environment.yml | 2 +- .../local/patch_segmentation_stardist/main.nf | 4 +-- modules/local/report/environment.yml | 2 +- modules/local/report/main.nf | 7 ++-- modules/local/resolve_baysor/environment.yml | 2 +- modules/local/resolve_baysor/main.nf | 4 +-- .../local/resolve_cellpose/environment.yml | 2 +- modules/local/resolve_cellpose/main.nf | 4 +-- modules/local/resolve_comseg/environment.yml | 2 +- modules/local/resolve_comseg/main.nf | 4 +-- .../local/resolve_stardist/environment.yml | 2 +- modules/local/resolve_stardist/main.nf | 4 +-- .../local/scanpy_preprocess/environment.yml | 8 +++++ modules/local/scanpy_preprocess/main.nf | 28 ++++++++++++++++ .../local/tangram_annotation/environment.yml | 2 +- modules/local/tangram_annotation/main.nf | 4 +-- .../local/tissue_segmentation/environment.yml | 2 +- modules/local/tissue_segmentation/main.nf | 4 +-- modules/local/to_spatialdata/environment.yml | 2 +- modules/local/to_spatialdata/main.nf | 4 +-- nextflow_schema.json | 18 +++++++++++ tests/baysor.nf.test.snap | 6 ++-- tests/cellpose.nf.test.snap | 4 +-- tests/default.nf.test.snap | 6 ++-- workflows/sopa.nf | 32 ++++++------------- 45 files changed, 132 insertions(+), 87 deletions(-) create mode 100644 modules/local/scanpy_preprocess/environment.yml create mode 100644 modules/local/scanpy_preprocess/main.nf diff --git a/modules/local/aggregate/environment.yml b/modules/local/aggregate/environment.yml index c171fea..1c9b41f 100644 --- a/modules/local/aggregate/environment.yml +++ b/modules/local/aggregate/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 diff --git a/modules/local/aggregate/main.nf b/modules/local/aggregate/main.nf index 8b79ce5..ad1504b 100644 --- a/modules/local/aggregate/main.nf +++ b/modules/local/aggregate/main.nf @@ -3,8 +3,8 @@ process AGGREGATE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.1.5' + : 'docker.io/quentinblampey/sopa:2.1.5'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/explorer/environment.yml b/modules/local/explorer/environment.yml index c171fea..1c9b41f 100644 --- a/modules/local/explorer/environment.yml +++ b/modules/local/explorer/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 diff --git a/modules/local/explorer/main.nf b/modules/local/explorer/main.nf index 1a06e6e..b0a7a41 100644 --- a/modules/local/explorer/main.nf +++ b/modules/local/explorer/main.nf @@ -3,8 +3,8 @@ process EXPLORER { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.1.5' + : 'docker.io/quentinblampey/sopa:2.1.5'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/explorer_raw/environment.yml b/modules/local/explorer_raw/environment.yml index c171fea..1c9b41f 100644 --- a/modules/local/explorer_raw/environment.yml +++ b/modules/local/explorer_raw/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 diff --git a/modules/local/explorer_raw/main.nf b/modules/local/explorer_raw/main.nf index f5abdf5..d977080 100644 --- a/modules/local/explorer_raw/main.nf +++ b/modules/local/explorer_raw/main.nf @@ -3,8 +3,8 @@ process EXPLORER_RAW { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.1.5' + : 'docker.io/quentinblampey/sopa:2.1.5'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/fluo_annotation/environment.yml b/modules/local/fluo_annotation/environment.yml index c171fea..1c9b41f 100644 --- a/modules/local/fluo_annotation/environment.yml +++ b/modules/local/fluo_annotation/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 diff --git a/modules/local/fluo_annotation/main.nf b/modules/local/fluo_annotation/main.nf index f70f66c..b6cc4b4 100644 --- a/modules/local/fluo_annotation/main.nf +++ b/modules/local/fluo_annotation/main.nf @@ -3,8 +3,8 @@ process FLUO_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.1.5' + : 'docker.io/quentinblampey/sopa:2.1.5'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_image_patches/environment.yml b/modules/local/make_image_patches/environment.yml index c171fea..1c9b41f 100644 --- a/modules/local/make_image_patches/environment.yml +++ b/modules/local/make_image_patches/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 diff --git a/modules/local/make_image_patches/main.nf b/modules/local/make_image_patches/main.nf index 5ebd706..d2c7a8f 100644 --- a/modules/local/make_image_patches/main.nf +++ b/modules/local/make_image_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_IMAGE_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.1.5' + : 'docker.io/quentinblampey/sopa:2.1.5'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_transcript_patches/environment.yml b/modules/local/make_transcript_patches/environment.yml index c171fea..1c9b41f 100644 --- a/modules/local/make_transcript_patches/environment.yml +++ b/modules/local/make_transcript_patches/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 diff --git a/modules/local/make_transcript_patches/main.nf b/modules/local/make_transcript_patches/main.nf index 203e48e..f2dddb2 100644 --- a/modules/local/make_transcript_patches/main.nf +++ b/modules/local/make_transcript_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_TRANSCRIPT_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.1.5' + : 'docker.io/quentinblampey/sopa:2.1.5'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/patch_segmentation_baysor/environment.yml b/modules/local/patch_segmentation_baysor/environment.yml index 1fc290a..5e7bc0a 100644 --- a/modules/local/patch_segmentation_baysor/environment.yml +++ b/modules/local/patch_segmentation_baysor/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa[baysor]==2.1.4 + - sopa[baysor]==2.1.5 diff --git a/modules/local/patch_segmentation_baysor/main.nf b/modules/local/patch_segmentation_baysor/main.nf index 92c4966..c609cfe 100644 --- a/modules/local/patch_segmentation_baysor/main.nf +++ b/modules/local/patch_segmentation_baysor/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-baysor' - : 'docker.io/quentinblampey/sopa:latest-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.5-baysor' + : 'docker.io/quentinblampey/sopa:2.1.5-baysor'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_cellpose/environment.yml b/modules/local/patch_segmentation_cellpose/environment.yml index 6135203..74f437b 100644 --- a/modules/local/patch_segmentation_cellpose/environment.yml +++ b/modules/local/patch_segmentation_cellpose/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa[cellpose]==2.1.4 + - sopa[cellpose]==2.1.5 diff --git a/modules/local/patch_segmentation_cellpose/main.nf b/modules/local/patch_segmentation_cellpose/main.nf index 9d6fa81..c7b14cb 100644 --- a/modules/local/patch_segmentation_cellpose/main.nf +++ b/modules/local/patch_segmentation_cellpose/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-cellpose' - : 'docker.io/quentinblampey/sopa:latest-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.5-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.5-cellpose'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_comseg/environment.yml b/modules/local/patch_segmentation_comseg/environment.yml index 15791ed..9b94154 100644 --- a/modules/local/patch_segmentation_comseg/environment.yml +++ b/modules/local/patch_segmentation_comseg/environment.yml @@ -5,5 +5,5 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 - comseg==1.8.2 diff --git a/modules/local/patch_segmentation_comseg/main.nf b/modules/local/patch_segmentation_comseg/main.nf index 7f0d9fe..0199af7 100644 --- a/modules/local/patch_segmentation_comseg/main.nf +++ b/modules/local/patch_segmentation_comseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-comseg' - : 'docker.io/quentinblampey/sopa:latest-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.5-comseg' + : 'docker.io/quentinblampey/sopa:2.1.5-comseg'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_proseg/environment.yml b/modules/local/patch_segmentation_proseg/environment.yml index c171fea..1c9b41f 100644 --- a/modules/local/patch_segmentation_proseg/environment.yml +++ b/modules/local/patch_segmentation_proseg/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 diff --git a/modules/local/patch_segmentation_proseg/main.nf b/modules/local/patch_segmentation_proseg/main.nf index bf35741..47afbdf 100644 --- a/modules/local/patch_segmentation_proseg/main.nf +++ b/modules/local/patch_segmentation_proseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_PROSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-proseg' - : 'docker.io/quentinblampey/sopa:latest-proseg'}" + ? 'docker://quentinblampey/sopa:2.1.5-proseg' + : 'docker.io/quentinblampey/sopa:2.1.5-proseg'}" input: tuple val(meta), path(sdata_path), path(patches_file_transcripts), path(transcript_patches) diff --git a/modules/local/patch_segmentation_stardist/environment.yml b/modules/local/patch_segmentation_stardist/environment.yml index b044675..0d2babc 100644 --- a/modules/local/patch_segmentation_stardist/environment.yml +++ b/modules/local/patch_segmentation_stardist/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa[stardist]==2.1.4 + - sopa[stardist]==2.1.5 diff --git a/modules/local/patch_segmentation_stardist/main.nf b/modules/local/patch_segmentation_stardist/main.nf index a95b7db..a2e8c45 100644 --- a/modules/local/patch_segmentation_stardist/main.nf +++ b/modules/local/patch_segmentation_stardist/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-stardist' - : 'docker.io/quentinblampey/sopa:latest-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.5-stardist' + : 'docker.io/quentinblampey/sopa:2.1.5-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/report/environment.yml b/modules/local/report/environment.yml index c171fea..1c9b41f 100644 --- a/modules/local/report/environment.yml +++ b/modules/local/report/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 diff --git a/modules/local/report/main.nf b/modules/local/report/main.nf index 9b8e5a3..25629ca 100644 --- a/modules/local/report/main.nf +++ b/modules/local/report/main.nf @@ -3,8 +3,8 @@ process REPORT { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.1.5' + : 'docker.io/quentinblampey/sopa:2.1.5'}" publishDir "${params.outdir}", mode: params.publish_dir_mode @@ -12,6 +12,7 @@ process REPORT { tuple val(meta), path(sdata_path) output: + path sdata_path path "${meta.explorer_dir}/analysis_summary.html" script: @@ -19,5 +20,7 @@ process REPORT { mkdir -p ${meta.explorer_dir} sopa report ${sdata_path} ${meta.explorer_dir}/analysis_summary.html + + rm -r ${sdata_path}/.sopa_cache || true # clean up cache if existing """ } diff --git a/modules/local/resolve_baysor/environment.yml b/modules/local/resolve_baysor/environment.yml index 1fc290a..5e7bc0a 100644 --- a/modules/local/resolve_baysor/environment.yml +++ b/modules/local/resolve_baysor/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa[baysor]==2.1.4 + - sopa[baysor]==2.1.5 diff --git a/modules/local/resolve_baysor/main.nf b/modules/local/resolve_baysor/main.nf index b599b3e..2a07494 100644 --- a/modules/local/resolve_baysor/main.nf +++ b/modules/local/resolve_baysor/main.nf @@ -3,8 +3,8 @@ process RESOLVE_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-baysor' - : 'docker.io/quentinblampey/sopa:latest-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.5-baysor' + : 'docker.io/quentinblampey/sopa:2.1.5-baysor'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_cellpose/environment.yml b/modules/local/resolve_cellpose/environment.yml index 6135203..74f437b 100644 --- a/modules/local/resolve_cellpose/environment.yml +++ b/modules/local/resolve_cellpose/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa[cellpose]==2.1.4 + - sopa[cellpose]==2.1.5 diff --git a/modules/local/resolve_cellpose/main.nf b/modules/local/resolve_cellpose/main.nf index f05ce75..f12498c 100644 --- a/modules/local/resolve_cellpose/main.nf +++ b/modules/local/resolve_cellpose/main.nf @@ -3,8 +3,8 @@ process RESOLVE_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-cellpose' - : 'docker.io/quentinblampey/sopa:latest-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.5-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.5-cellpose'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_comseg/environment.yml b/modules/local/resolve_comseg/environment.yml index 15791ed..9b94154 100644 --- a/modules/local/resolve_comseg/environment.yml +++ b/modules/local/resolve_comseg/environment.yml @@ -5,5 +5,5 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 - comseg==1.8.2 diff --git a/modules/local/resolve_comseg/main.nf b/modules/local/resolve_comseg/main.nf index 07f534c..77383b5 100644 --- a/modules/local/resolve_comseg/main.nf +++ b/modules/local/resolve_comseg/main.nf @@ -3,8 +3,8 @@ process RESOLVE_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-comseg' - : 'docker.io/quentinblampey/sopa:latest-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.5-comseg' + : 'docker.io/quentinblampey/sopa:2.1.5-comseg'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_stardist/environment.yml b/modules/local/resolve_stardist/environment.yml index b044675..0d2babc 100644 --- a/modules/local/resolve_stardist/environment.yml +++ b/modules/local/resolve_stardist/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa[stardist]==2.1.4 + - sopa[stardist]==2.1.5 diff --git a/modules/local/resolve_stardist/main.nf b/modules/local/resolve_stardist/main.nf index 31ce7d9..4616464 100644 --- a/modules/local/resolve_stardist/main.nf +++ b/modules/local/resolve_stardist/main.nf @@ -3,8 +3,8 @@ process RESOLVE_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-stardist' - : 'docker.io/quentinblampey/sopa:latest-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.5-stardist' + : 'docker.io/quentinblampey/sopa:2.1.5-stardist'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/scanpy_preprocess/environment.yml b/modules/local/scanpy_preprocess/environment.yml new file mode 100644 index 0000000..1c9b41f --- /dev/null +++ b/modules/local/scanpy_preprocess/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - python=3.11 + - pip=24.3.1 + - pip: + - sopa==2.1.5 diff --git a/modules/local/scanpy_preprocess/main.nf b/modules/local/scanpy_preprocess/main.nf new file mode 100644 index 0000000..2233d2c --- /dev/null +++ b/modules/local/scanpy_preprocess/main.nf @@ -0,0 +1,28 @@ +process SCANPY_PREPROCESS { + label "process_high" + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container + ? 'docker://quentinblampey/sopa:2.1.5' + : 'docker.io/quentinblampey/sopa:2.1.5'}" + + input: + tuple val(meta), path(sdata_path) + val cli_arguments + + output: + tuple val(meta), path(sdata_path) + path "${sdata_path}/tables/table" + path "versions.yml" + + script: + """ + sopa scanpy-preprocess ${sdata_path} ${cli_arguments} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sopa: \$(sopa --version) + scanpy: \$(python -c "import scanpy; print(scanpy.__version__)" 2> /dev/null) + END_VERSIONS + """ +} diff --git a/modules/local/tangram_annotation/environment.yml b/modules/local/tangram_annotation/environment.yml index 789aacf..57774ea 100644 --- a/modules/local/tangram_annotation/environment.yml +++ b/modules/local/tangram_annotation/environment.yml @@ -5,5 +5,5 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 - tangram-sc==1.0.4 diff --git a/modules/local/tangram_annotation/main.nf b/modules/local/tangram_annotation/main.nf index 2bab0fe..f6ff21a 100644 --- a/modules/local/tangram_annotation/main.nf +++ b/modules/local/tangram_annotation/main.nf @@ -3,8 +3,8 @@ process TANGRAM_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest-tangram' - : 'docker.io/quentinblampey/sopa:latest-tangram'}" + ? 'docker://quentinblampey/sopa:2.1.5-tangram' + : 'docker.io/quentinblampey/sopa:2.1.5-tangram'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tissue_segmentation/environment.yml b/modules/local/tissue_segmentation/environment.yml index c171fea..1c9b41f 100644 --- a/modules/local/tissue_segmentation/environment.yml +++ b/modules/local/tissue_segmentation/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 diff --git a/modules/local/tissue_segmentation/main.nf b/modules/local/tissue_segmentation/main.nf index 3c6ea0f..bbef25b 100644 --- a/modules/local/tissue_segmentation/main.nf +++ b/modules/local/tissue_segmentation/main.nf @@ -3,8 +3,8 @@ process TISSUE_SEGMENTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.1.5' + : 'docker.io/quentinblampey/sopa:2.1.5'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/to_spatialdata/environment.yml b/modules/local/to_spatialdata/environment.yml index c171fea..1c9b41f 100644 --- a/modules/local/to_spatialdata/environment.yml +++ b/modules/local/to_spatialdata/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.4 + - sopa==2.1.5 diff --git a/modules/local/to_spatialdata/main.nf b/modules/local/to_spatialdata/main.nf index e38d521..23547aa 100644 --- a/modules/local/to_spatialdata/main.nf +++ b/modules/local/to_spatialdata/main.nf @@ -5,8 +5,8 @@ process TO_SPATIALDATA { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:latest' - : 'docker.io/quentinblampey/sopa:latest'}" + ? 'docker://quentinblampey/sopa:2.1.5' + : 'docker.io/quentinblampey/sopa:2.1.5'}" input: tuple val(meta), path(data_dir), path(other_input_files) diff --git a/nextflow_schema.json b/nextflow_schema.json index 4060128..fabb78c 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -197,6 +197,24 @@ "description": "Dictionary of annotation parameters.", "fa_icon": "fas fa-gear" }, + "scanpy_preprocess": { + "type": "object", + "properties": { + "resolution": { + "type": "number", + "description": "Resolution parameter for the Leiden clustering algorithm.", + "fa_icon": "fas fa-sliders-h" + }, + "check_counts": { + "type": "boolean", + "description": "Whether to check counts in Scanpy preprocessing.", + "fa_icon": "fas fa-check" + } + }, + "additionalProperties": true, + "description": "Dictionary of Scanpy preprocessing parameters.", + "fa_icon": "fas fa-gear" + }, "explorer": { "type": "object", "additionalProperties": true, diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index c6178a4..e74fb48 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -4,15 +4,15 @@ 10, { "RESOLVE_BAYSOR": { - "sopa": "2.1.4", + "sopa": "2.1.5", "baysor": "0.7.1" }, "TANGRAM_ANNOTATION": { - "sopa": "2.1.4", + "sopa": "2.1.5", "tangram": "1.0.4" }, "TO_SPATIALDATA": { - "sopa": "2.1.4", + "sopa": "2.1.5", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 4fb8f24..520f4f3 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -4,11 +4,11 @@ 9, { "RESOLVE_CELLPOSE": { - "sopa": "2.1.4", + "sopa": "2.1.5", "cellpose": "4.0.6" }, "TO_SPATIALDATA": { - "sopa": "2.1.4", + "sopa": "2.1.5", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 490fcd2..9f651d1 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -4,14 +4,14 @@ 9, { "FLUO_ANNOTATION": { - "sopa": "2.1.4" + "sopa": "2.1.5" }, "PATCH_SEGMENTATION_PROSEG": { - "sopa": "2.1.4", + "sopa": "2.1.5", "proseg": "3.0.8" }, "TO_SPATIALDATA": { - "sopa": "2.1.4", + "sopa": "2.1.5", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 54ea042..d1d7773 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -23,6 +23,7 @@ include { RESOLVE_STARDIST } from '../modules/local/resolve_stardist' include { AGGREGATE } from '../modules/local/aggregate' include { EXPLORER } from '../modules/local/explorer' include { EXPLORER_RAW } from '../modules/local/explorer_raw' +include { SCANPY_PREPROCESS } from '../modules/local/scanpy_preprocess' include { REPORT } from '../modules/local/report' include { TANGRAM_ANNOTATION } from '../modules/local/tangram_annotation' include { FLUO_ANNOTATION } from '../modules/local/fluo_annotation' @@ -122,11 +123,17 @@ workflow SOPA { ch_annotated = ch_aggregated } - EXPLORER(ch_annotated, ArgsCLI(params.explorer)) - REPORT(ch_annotated) + if (params?.containsKey('scanpy_preprocess')) { + (ch_preprocessed, _out, versions) = SCANPY_PREPROCESS(ch_annotated, ArgsCLI(params.scanpy_preprocess)) + ch_versions = ch_versions.mix(versions) + } + else { + ch_preprocessed = ch_annotated + } - PUBLISH(ch_annotated.map { it[1] }) + EXPLORER(ch_preprocessed, ArgsCLI(params.explorer)) + REPORT(ch_preprocessed) // // Collate and save software versions @@ -142,25 +149,6 @@ workflow SOPA { versions = ch_versions // channel: [ path(versions.yml) ] } -process PUBLISH { - label "process_single" - - publishDir "${params.outdir}", mode: params.publish_dir_mode - - input: - path sdata_path - - output: - path sdata_path - - script: - """ - rm -r ${sdata_path}/.sopa_cache || true - - echo "Publishing ${sdata_path}" - """ -} - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SEGMENTATION WORKFLOWS From 6059ba14a5c5d61f77d45280faf55d3393710fc8 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 14 Oct 2025 09:42:21 +0200 Subject: [PATCH 176/227] fix linting --- nextflow.config | 1 + workflows/sopa.nf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/nextflow.config b/nextflow.config index d28e680..f770fc6 100644 --- a/nextflow.config +++ b/nextflow.config @@ -16,6 +16,7 @@ params { patchify = null aggregate = null annotation = null + scanpy_preprocess = null explorer = null // Spaceranger options diff --git a/workflows/sopa.nf b/workflows/sopa.nf index d1d7773..095f6f2 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -123,7 +123,7 @@ workflow SOPA { ch_annotated = ch_aggregated } - if (params?.containsKey('scanpy_preprocess')) { + if (params.scanpy_preprocess) { (ch_preprocessed, _out, versions) = SCANPY_PREPROCESS(ch_annotated, ArgsCLI(params.scanpy_preprocess)) ch_versions = ch_versions.mix(versions) } From 411a566ad330fc3717ab26c6b38750db390b76cc Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 14 Oct 2025 09:51:38 +0200 Subject: [PATCH 177/227] update snapshots --- tests/baysor.nf.test.snap | 2 +- tests/cellpose.nf.test.snap | 4 ++-- tests/default.nf.test.snap | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index e74fb48..935f8de 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -1,7 +1,7 @@ { "-profile test_baysor": { "content": [ - 10, + 9, { "RESOLVE_BAYSOR": { "sopa": "2.1.5", diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 520f4f3..aeccf92 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -1,11 +1,11 @@ { "-profile test_cellpose": { "content": [ - 9, + 8, { "RESOLVE_CELLPOSE": { "sopa": "2.1.5", - "cellpose": "4.0.6" + "cellpose": "4.0.7" }, "TO_SPATIALDATA": { "sopa": "2.1.5", diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 9f651d1..c610278 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -1,7 +1,7 @@ { "-profile test": { "content": [ - 9, + 8, { "FLUO_ANNOTATION": { "sopa": "2.1.5" From c530413a32a08e7e236e39acc80d4143f0279831 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 14 Oct 2025 15:08:45 +0200 Subject: [PATCH 178/227] update credits --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fec8b1c..8cd0934 100644 --- a/README.md +++ b/README.md @@ -82,11 +82,12 @@ For more details about the output files and reports, please refer to the ## Credits -nf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSupélec, Gustave Roussy Institute, and Université Paris-Saclay. +nf-core/sopa was originally written by [Quentin Blampey](https://github.com/quentinblampey) during his work at the following institutions: CentraleSupélec, Gustave Roussy Institute, Université Paris-Saclay, and Cure51. We thank the following people for their extensive assistance in the development of this pipeline: - +- [Matthias Hörtenhuber](https://github.com/mashehu) +- [Kevin Weiss](https://github.com/kweisscure51) ## Contributions and Support From 95bce9162219c0d11e8757ae45c3b2af0aeed54f Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 14 Oct 2025 15:23:40 +0200 Subject: [PATCH 179/227] fix ro-crate and update usage docs --- docs/usage.md | 21 +++++++++++++++++---- ro-crate-metadata.json | 2 +- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 7f26a40..028336a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -21,10 +21,10 @@ For all technologies supported by Sopa, the samplesheet lists the `data_path` to The concerned technologies are: `xenium`, `merscope`, `cosmx`, `molecular_cartography`, `macsima`, `phenocycler`, `ome_tif`, and `hyperion`. -| Column | Description | -| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `data_path` | **Path to the raw data**; a directory containing the output of the machine with the data of a single sample or region. Typically, this directory contains one or multiple image(s), and a transcript file (`.csv` or `.parquet`) for transcriptomics technologies. See more details [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-of-sopa)). _Required_ | -| `sample` | **Custom sample ID (optional)**; designates the sample ID; must be unique for each patient. It will be used in the output directories names: `{sample}.zarr` and `{sample}.explorer`. _Optional, Default: the basename of `data_path` (i.e., the last directory component of `data_path`)_ | +| Column | Description | +| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `data_path` | **Path to the raw data**; a directory containing the output of the machine with the data of a single sample or region. Typically, this directory contains one or multiple image(s), and a transcript file (`.csv` or `.parquet`) for transcriptomics technologies. See more details below. _Required_ | +| `sample` | **Custom sample ID (optional)**; designates the sample ID; must be unique for each patient. It will be used in the output directories names: `{sample}.zarr` and `{sample}.explorer`. _Optional, Default: the basename of `data_path` (i.e., the last directory component of `data_path`)_ | Here is a samplesheet example for two samples: @@ -36,6 +36,19 @@ SAMPLE1,/path/to/one/merscope_directory SAMPLE2,/path/to/another/merscope_directory ``` +We also provide a detailed description of what `data_path` should contain, depending on the technologies: + +| Technology | `data_path` directory content | +| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| xenium | `transcripts.parquet`, `experiment.xenium`, and `morphology_focus.ome.tif` or a morphology directory. | +| merscope | `detected_transcripts.csv`, all the images under the `images` subdirectory, and `images/micron_to_mosaic_pixel_transform.csv` (affine transformation) | +| cosmx | `*_fov_positions_file.csv` or `*_fov_positions_file.csv.gz` (FOV locations),`Morphology2D` (directory with all the FOVs morphology images), and `*_tx_file.csv.gz` or `*_tx_file.csv` (transcripts location and names) | +| molecular_cartography | Multiple `.tiff` images and `_results.txt` files. | +| macsima | Multiple `.tif` images | +| phenocycler | For this technology, `data_path` is not a directory, but a `.qptiff` or `.tif` file containing all channels for a given sample. | +| hyperion | Multiple `.tif` images | +| ome_tif | Generic reader for which `data_path` is not a directory, but a `.ome.tif` file containing all channels for a given sample. | + ### Visium HD Some extra columns need to be provided specifically for Visium HD. This is because we need to run [Space Ranger](https://www.10xgenomics.com/support/software/space-ranger/latest) before running Sopa. Note that the `image` is the full-resolution microscopy image (not the cytassist image) and is **required** by Sopa as we'll run cell segmentation on the H&E full-resolution slide. For more details, see the [`spaceranger-count` arguments](https://nf-co.re/modules/spaceranger_count). diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index d8cbd98..5a4cc61 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "Stable", "datePublished": "2025-07-22T07:34:52+00:00", - "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n> [!WARNING]\n> If you are interested in the main Sopa python package, refer to [this Sopa repository](https://github.com/gustaveroussy/sopa). Else, if you want to use Nextflow, you are in the good place.\n\n

    \n \"sopa_overview\"\n

    \n\n1. (Visium HD only) Raw data processing with Space Ranger\n2. (Optional) Tissue segmentation\n3. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n4. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n5. (Optional) Cell-type annotation\n6. User-friendly output creation for visualization and quick analysis\n7. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://github.com/gustaveroussy/sopa).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-of-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose the Sopa parameters. You can find existing Sopa params files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n -params-file \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, and Universit\u00e9 Paris-Saclay.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.3.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n> [!WARNING]\n> If you are interested in the main Sopa python package, refer to [this Sopa repository](https://github.com/gustaveroussy/sopa). Else, if you want to use Nextflow, you are in the good place.\n\n

    \n \"sopa_overview\"\n

    \n\n1. (Visium HD only) Raw data processing with Space Ranger\n2. (Optional) Tissue segmentation\n3. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n4. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n5. (Optional) Cell-type annotation\n6. User-friendly output creation for visualization and quick analysis\n7. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://github.com/gustaveroussy/sopa).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-of-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose the Sopa parameters. You can find existing Sopa params files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n -params-file \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by [Quentin Blampey](https://github.com/quentinblampey) during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, Universit\u00e9 Paris-Saclay, and Cure51.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n- [Matthias H\u00f6rtenhuber](https://github.com/mashehu)\n- [Kevin Weiss](https://github.com/kweisscure51)\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" From 228ba3433466e679207fcc73e2a610f9a2da36c8 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 14 Oct 2025 16:29:44 +0200 Subject: [PATCH 180/227] fixes for visium hd data --- modules/local/to_spatialdata/main.nf | 6 +++--- modules/local/utils.nf | 6 ++---- workflows/sopa.nf | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/modules/local/to_spatialdata/main.nf b/modules/local/to_spatialdata/main.nf index 23547aa..cb28174 100644 --- a/modules/local/to_spatialdata/main.nf +++ b/modules/local/to_spatialdata/main.nf @@ -9,8 +9,8 @@ process TO_SPATIALDATA { : 'docker.io/quentinblampey/sopa:2.1.5'}" input: - tuple val(meta), path(data_dir), path(other_input_files) - val args + tuple val(meta), path(data_dir), path(fullres_image_file) + val read_params output: tuple val(meta), path("${meta.sdata_dir}") @@ -18,7 +18,7 @@ process TO_SPATIALDATA { script: """ - sopa convert ${data_dir} --sdata-path ${meta.sdata_dir} ${ArgsReaderCLI(args, meta)} + sopa convert ${data_dir} --sdata-path ${meta.sdata_dir} ${ArgsReaderCLI(read_params, meta, fullres_image_file.toString())} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 68a9b29..8024ba4 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -45,7 +45,7 @@ def ArgsCLI(Map params, String contains = null, List keys = null) { .join(" ") } -def ArgsReaderCLI(Map args, Map meta) { +def ArgsReaderCLI(Map args, Map meta, String fullres_image_file) { if (args.technology == "visium_hd") { args = deepCopyCollection(args) @@ -56,9 +56,7 @@ def ArgsReaderCLI(Map args, Map meta) { args.kwargs["dataset_id"] = meta.id } - if (meta.image) { - args.kwargs["fullres_image_file"] = meta.image - } + args.kwargs["fullres_image_file"] = fullres_image_file } return ArgsCLI(args) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 095f6f2..200e38c 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -45,7 +45,7 @@ workflow SOPA { if (params.read.technology == "visium_hd") { (ch_input_spatialdata, versions) = SPACERANGER(ch_samplesheet) - ch_input_spatialdata = ch_input_spatialdata.map { meta, out -> [meta, meta.data_dir, [out[0].toString().replaceFirst(/(.*?outs).*/, '$1'), meta.image]] } + ch_input_spatialdata = ch_input_spatialdata.map { meta, out -> [meta, out[0].toString().replaceFirst(/(.*?outs).*/, '$1'), meta.image] } ch_versions = ch_versions.mix(versions) } From 2009639ce39185f57818eda2d838962ee5cb0fc6 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 14 Oct 2025 16:34:46 +0200 Subject: [PATCH 181/227] allow .btf for visium hd data --- assets/schema_input.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/assets/schema_input.json b/assets/schema_input.json index 0b60344..320bb9d 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -38,26 +38,26 @@ }, "colorizedimage": { "type": "string", - "pattern": "^\\S+(tif|tiff|jpg|jpeg)$", + "pattern": "^\\S+(tif|tiff|jpg|jpeg|btf)$", "format": "path", "exists": true, - "errorMessage": "Path to the colorizedimage file must exist, not contain spaces, and be a .tif, .tiff, .jpg or .jpeg file", + "errorMessage": "Path to the colorizedimage file must exist, not contain spaces, and be a .tif, .tiff, .btf, .jpg or .jpeg file", "meta": ["colorizedimage"] }, "darkimage": { "type": "string", - "pattern": "^\\S+(tif|tiff|jpg|jpeg)$", + "pattern": "^\\S+(tif|tiff|jpg|jpeg|btf)$", "format": "path", "exists": true, - "errorMessage": "Path to the darkimage file must exist, not contain spaces, and be a .tif, .tiff, .jpg or .jpeg file", + "errorMessage": "Path to the darkimage file must exist, not contain spaces, and be a .tif, .tiff, .btf, .jpg or .jpeg file", "meta": ["darkimage"] }, "image": { "type": "string", - "pattern": "^\\S+(tif|tiff|jpg|jpeg)$", + "pattern": "^\\S+(tif|tiff|jpg|jpeg|btf)$", "format": "path", "exists": true, - "errorMessage": "Path to the image must exist, not contain spaces, and be a .tif, .tiff, .jpg or .jpeg file", + "errorMessage": "Path to the image must exist, not contain spaces, and be a .tif, .tiff, .btf, .jpg or .jpeg file", "meta": ["image"] }, "slide": { From d4e4823fd2ff93ce76941b9004865727f73302b3 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 14 Oct 2025 16:55:12 +0200 Subject: [PATCH 182/227] provide data_dir in explorer_raw only for xenium --- workflows/sopa.nf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 200e38c..4f70f6e 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -56,7 +56,8 @@ workflow SOPA { (ch_spatialdata, versions) = TO_SPATIALDATA(ch_input_spatialdata, params.read) ch_versions = ch_versions.mix(versions) - EXPLORER_RAW(ch_spatialdata.map { meta, sdata_path -> [meta, sdata_path, meta.data_dir] }, ArgsCLI(params.explorer)) + ch_explorer_raw = ch_spatialdata.map { meta, sdata_path -> [meta, sdata_path, params.read.technology == "xenium" ? meta.data_dir : []] } + EXPLORER_RAW(ch_explorer_raw, ArgsCLI(params.explorer)) if (params.segmentation.tissue) { (ch_tissue_seg, _out) = TISSUE_SEGMENTATION(ch_spatialdata, ArgsCLI(params.segmentation.tissue)) From fe771904c76af5a54a5295d7c943c2b4e4edf010 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 15 Oct 2025 09:33:12 +0200 Subject: [PATCH 183/227] pass raw xenium data to explorer_raw --- modules/local/explorer_raw/main.nf | 5 +++-- modules/local/to_spatialdata/main.nf | 5 ++--- modules/local/utils.nf | 16 +++++++++++++--- workflows/sopa.nf | 6 +++--- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/modules/local/explorer_raw/main.nf b/modules/local/explorer_raw/main.nf index d977080..5eee67a 100644 --- a/modules/local/explorer_raw/main.nf +++ b/modules/local/explorer_raw/main.nf @@ -1,3 +1,5 @@ +include { ArgsExplorerRaw } from '../utils' + process EXPLORER_RAW { label "process_high" @@ -10,7 +12,6 @@ process EXPLORER_RAW { input: tuple val(meta), path(sdata_path), path(data_dir) - val cli_arguments output: path "${meta.explorer_dir}/morphology*" @@ -18,6 +19,6 @@ process EXPLORER_RAW { script: """ - sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "+it" --no-save-h5ad + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${ArgsExplorerRaw(params, data_dir.toString())} --mode "+it" --no-save-h5ad """ } diff --git a/modules/local/to_spatialdata/main.nf b/modules/local/to_spatialdata/main.nf index cb28174..e8727b4 100644 --- a/modules/local/to_spatialdata/main.nf +++ b/modules/local/to_spatialdata/main.nf @@ -1,4 +1,4 @@ -include { ArgsReaderCLI } from '../utils' +include { ArgsToSpatialData } from '../utils' process TO_SPATIALDATA { label "process_high" @@ -10,7 +10,6 @@ process TO_SPATIALDATA { input: tuple val(meta), path(data_dir), path(fullres_image_file) - val read_params output: tuple val(meta), path("${meta.sdata_dir}") @@ -18,7 +17,7 @@ process TO_SPATIALDATA { script: """ - sopa convert ${data_dir} --sdata-path ${meta.sdata_dir} ${ArgsReaderCLI(read_params, meta, fullres_image_file.toString())} + sopa convert ${data_dir} --sdata-path ${meta.sdata_dir} ${ArgsToSpatialData(params, meta, fullres_image_file.toString())} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 8024ba4..6768692 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -45,10 +45,10 @@ def ArgsCLI(Map params, String contains = null, List keys = null) { .join(" ") } -def ArgsReaderCLI(Map args, Map meta, String fullres_image_file) { - if (args.technology == "visium_hd") { - args = deepCopyCollection(args) +def ArgsToSpatialData(Map params, Map meta, String fullres_image_file) { + def args = deepCopyCollection(params.read) + if (args.technology == "visium_hd") { if (!args.kwargs) { args.kwargs = ["dataset_id": meta.id] } @@ -62,6 +62,16 @@ def ArgsReaderCLI(Map args, Map meta, String fullres_image_file) { return ArgsCLI(args) } +def ArgsExplorerRaw(Map params, String raw_data_path) { + def args = deepCopyCollection(params.explorer ?: [:]) + + if (params.read.technology == "xenium") { + args["raw_data_path"] = raw_data_path + } + + return ArgsCLI(args) +} + def deepCopyCollection(object) { if (object instanceof Map) { object.collectEntries { key, value -> diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 4f70f6e..33c20e4 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -28,7 +28,7 @@ include { REPORT } from '../modules/local/report' include { TANGRAM_ANNOTATION } from '../modules/local/tangram_annotation' include { FLUO_ANNOTATION } from '../modules/local/fluo_annotation' include { SPACERANGER } from '../subworkflows/local/spaceranger' -include { ArgsCLI ; ArgsReaderCLI } from '../modules/local/utils' +include { ArgsCLI } from '../modules/local/utils' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -53,11 +53,11 @@ workflow SOPA { ch_input_spatialdata = ch_samplesheet.map { meta -> [meta, meta.data_dir, []] } } - (ch_spatialdata, versions) = TO_SPATIALDATA(ch_input_spatialdata, params.read) + (ch_spatialdata, versions) = TO_SPATIALDATA(ch_input_spatialdata) ch_versions = ch_versions.mix(versions) ch_explorer_raw = ch_spatialdata.map { meta, sdata_path -> [meta, sdata_path, params.read.technology == "xenium" ? meta.data_dir : []] } - EXPLORER_RAW(ch_explorer_raw, ArgsCLI(params.explorer)) + EXPLORER_RAW(ch_explorer_raw) if (params.segmentation.tissue) { (ch_tissue_seg, _out) = TISSUE_SEGMENTATION(ch_spatialdata, ArgsCLI(params.segmentation.tissue)) From e2aa87f2574dbac336f06088af71be0db1eca4b2 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 15 Oct 2025 11:47:38 +0200 Subject: [PATCH 184/227] move to 2.1.6 and add tests for scanpy_preprocess --- conf/test.config | 8 +- modules/local/aggregate/environment.yml | 2 +- modules/local/aggregate/main.nf | 4 +- modules/local/explorer/environment.yml | 2 +- modules/local/explorer/main.nf | 4 +- modules/local/explorer_raw/environment.yml | 2 +- modules/local/explorer_raw/main.nf | 4 +- modules/local/fluo_annotation/environment.yml | 2 +- modules/local/fluo_annotation/main.nf | 4 +- .../local/make_image_patches/environment.yml | 2 +- modules/local/make_image_patches/main.nf | 4 +- .../make_transcript_patches/environment.yml | 2 +- modules/local/make_transcript_patches/main.nf | 4 +- .../patch_segmentation_baysor/environment.yml | 2 +- .../local/patch_segmentation_baysor/main.nf | 4 +- .../environment.yml | 2 +- .../local/patch_segmentation_cellpose/main.nf | 4 +- .../patch_segmentation_comseg/environment.yml | 2 +- .../local/patch_segmentation_comseg/main.nf | 4 +- .../patch_segmentation_proseg/environment.yml | 2 +- .../local/patch_segmentation_proseg/main.nf | 4 +- .../environment.yml | 2 +- .../local/patch_segmentation_stardist/main.nf | 4 +- modules/local/report/environment.yml | 2 +- modules/local/report/main.nf | 4 +- modules/local/resolve_baysor/environment.yml | 2 +- modules/local/resolve_baysor/main.nf | 4 +- .../local/resolve_cellpose/environment.yml | 2 +- modules/local/resolve_cellpose/main.nf | 4 +- modules/local/resolve_comseg/environment.yml | 2 +- modules/local/resolve_comseg/main.nf | 4 +- .../local/resolve_stardist/environment.yml | 2 +- modules/local/resolve_stardist/main.nf | 4 +- .../local/scanpy_preprocess/environment.yml | 2 +- modules/local/scanpy_preprocess/main.nf | 4 +- .../local/tangram_annotation/environment.yml | 2 +- modules/local/tangram_annotation/main.nf | 4 +- .../local/tissue_segmentation/environment.yml | 2 +- modules/local/tissue_segmentation/main.nf | 4 +- modules/local/to_spatialdata/environment.yml | 2 +- modules/local/to_spatialdata/main.nf | 4 +- nextflow_schema.json | 2 +- tests/.nftignore | 1 + tests/baysor.nf.test.snap | 24 +- tests/cellpose.nf.test.snap | 4 +- tests/default.nf.test.snap | 205 ++++++++++++++++-- 46 files changed, 258 insertions(+), 106 deletions(-) diff --git a/conf/test.config b/conf/test.config index 4c02f5c..0befa9f 100644 --- a/conf/test.config +++ b/conf/test.config @@ -19,8 +19,8 @@ process { } params { - config_profile_name = 'Test profile with Proseg' -config_profile_description = 'Minimal test dataset to check pipeline function' + config_profile_name = 'Test profile with Proseg' + config_profile_description = 'Minimal test dataset to check pipeline function' // Input data input = "${baseDir}/tests/samplesheet.csv" @@ -55,6 +55,10 @@ config_profile_description = 'Minimal test dataset to check pipeline function' ], ] + scanpy_preprocess = [ + check_counts: false + ] + explorer = [ ram_threshold_gb: 4, pixel_size: 0.1, diff --git a/modules/local/aggregate/environment.yml b/modules/local/aggregate/environment.yml index 1c9b41f..0f643ba 100644 --- a/modules/local/aggregate/environment.yml +++ b/modules/local/aggregate/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 diff --git a/modules/local/aggregate/main.nf b/modules/local/aggregate/main.nf index ad1504b..36325cb 100644 --- a/modules/local/aggregate/main.nf +++ b/modules/local/aggregate/main.nf @@ -3,8 +3,8 @@ process AGGREGATE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5' - : 'docker.io/quentinblampey/sopa:2.1.5'}" + ? 'docker://quentinblampey/sopa:2.1.6' + : 'docker.io/quentinblampey/sopa:2.1.6'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/explorer/environment.yml b/modules/local/explorer/environment.yml index 1c9b41f..0f643ba 100644 --- a/modules/local/explorer/environment.yml +++ b/modules/local/explorer/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 diff --git a/modules/local/explorer/main.nf b/modules/local/explorer/main.nf index b0a7a41..3367f73 100644 --- a/modules/local/explorer/main.nf +++ b/modules/local/explorer/main.nf @@ -3,8 +3,8 @@ process EXPLORER { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5' - : 'docker.io/quentinblampey/sopa:2.1.5'}" + ? 'docker://quentinblampey/sopa:2.1.6' + : 'docker.io/quentinblampey/sopa:2.1.6'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/explorer_raw/environment.yml b/modules/local/explorer_raw/environment.yml index 1c9b41f..0f643ba 100644 --- a/modules/local/explorer_raw/environment.yml +++ b/modules/local/explorer_raw/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 diff --git a/modules/local/explorer_raw/main.nf b/modules/local/explorer_raw/main.nf index 5eee67a..e0e3fe3 100644 --- a/modules/local/explorer_raw/main.nf +++ b/modules/local/explorer_raw/main.nf @@ -5,8 +5,8 @@ process EXPLORER_RAW { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5' - : 'docker.io/quentinblampey/sopa:2.1.5'}" + ? 'docker://quentinblampey/sopa:2.1.6' + : 'docker.io/quentinblampey/sopa:2.1.6'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/fluo_annotation/environment.yml b/modules/local/fluo_annotation/environment.yml index 1c9b41f..0f643ba 100644 --- a/modules/local/fluo_annotation/environment.yml +++ b/modules/local/fluo_annotation/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 diff --git a/modules/local/fluo_annotation/main.nf b/modules/local/fluo_annotation/main.nf index b6cc4b4..16ef797 100644 --- a/modules/local/fluo_annotation/main.nf +++ b/modules/local/fluo_annotation/main.nf @@ -3,8 +3,8 @@ process FLUO_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5' - : 'docker.io/quentinblampey/sopa:2.1.5'}" + ? 'docker://quentinblampey/sopa:2.1.6' + : 'docker.io/quentinblampey/sopa:2.1.6'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_image_patches/environment.yml b/modules/local/make_image_patches/environment.yml index 1c9b41f..0f643ba 100644 --- a/modules/local/make_image_patches/environment.yml +++ b/modules/local/make_image_patches/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 diff --git a/modules/local/make_image_patches/main.nf b/modules/local/make_image_patches/main.nf index d2c7a8f..d20a7cd 100644 --- a/modules/local/make_image_patches/main.nf +++ b/modules/local/make_image_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_IMAGE_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5' - : 'docker.io/quentinblampey/sopa:2.1.5'}" + ? 'docker://quentinblampey/sopa:2.1.6' + : 'docker.io/quentinblampey/sopa:2.1.6'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_transcript_patches/environment.yml b/modules/local/make_transcript_patches/environment.yml index 1c9b41f..0f643ba 100644 --- a/modules/local/make_transcript_patches/environment.yml +++ b/modules/local/make_transcript_patches/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 diff --git a/modules/local/make_transcript_patches/main.nf b/modules/local/make_transcript_patches/main.nf index f2dddb2..2334747 100644 --- a/modules/local/make_transcript_patches/main.nf +++ b/modules/local/make_transcript_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_TRANSCRIPT_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5' - : 'docker.io/quentinblampey/sopa:2.1.5'}" + ? 'docker://quentinblampey/sopa:2.1.6' + : 'docker.io/quentinblampey/sopa:2.1.6'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/patch_segmentation_baysor/environment.yml b/modules/local/patch_segmentation_baysor/environment.yml index 5e7bc0a..3a43072 100644 --- a/modules/local/patch_segmentation_baysor/environment.yml +++ b/modules/local/patch_segmentation_baysor/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa[baysor]==2.1.5 + - sopa[baysor]==2.1.6 diff --git a/modules/local/patch_segmentation_baysor/main.nf b/modules/local/patch_segmentation_baysor/main.nf index c609cfe..8d22841 100644 --- a/modules/local/patch_segmentation_baysor/main.nf +++ b/modules/local/patch_segmentation_baysor/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5-baysor' - : 'docker.io/quentinblampey/sopa:2.1.5-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.6-baysor' + : 'docker.io/quentinblampey/sopa:2.1.6-baysor'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_cellpose/environment.yml b/modules/local/patch_segmentation_cellpose/environment.yml index 74f437b..91faa94 100644 --- a/modules/local/patch_segmentation_cellpose/environment.yml +++ b/modules/local/patch_segmentation_cellpose/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa[cellpose]==2.1.5 + - sopa[cellpose]==2.1.6 diff --git a/modules/local/patch_segmentation_cellpose/main.nf b/modules/local/patch_segmentation_cellpose/main.nf index c7b14cb..2693bb8 100644 --- a/modules/local/patch_segmentation_cellpose/main.nf +++ b/modules/local/patch_segmentation_cellpose/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.5-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.6-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.6-cellpose'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_comseg/environment.yml b/modules/local/patch_segmentation_comseg/environment.yml index 9b94154..2654b07 100644 --- a/modules/local/patch_segmentation_comseg/environment.yml +++ b/modules/local/patch_segmentation_comseg/environment.yml @@ -5,5 +5,5 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 - comseg==1.8.2 diff --git a/modules/local/patch_segmentation_comseg/main.nf b/modules/local/patch_segmentation_comseg/main.nf index 0199af7..316e36e 100644 --- a/modules/local/patch_segmentation_comseg/main.nf +++ b/modules/local/patch_segmentation_comseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5-comseg' - : 'docker.io/quentinblampey/sopa:2.1.5-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.6-comseg' + : 'docker.io/quentinblampey/sopa:2.1.6-comseg'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_proseg/environment.yml b/modules/local/patch_segmentation_proseg/environment.yml index 1c9b41f..0f643ba 100644 --- a/modules/local/patch_segmentation_proseg/environment.yml +++ b/modules/local/patch_segmentation_proseg/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 diff --git a/modules/local/patch_segmentation_proseg/main.nf b/modules/local/patch_segmentation_proseg/main.nf index 47afbdf..a0323cb 100644 --- a/modules/local/patch_segmentation_proseg/main.nf +++ b/modules/local/patch_segmentation_proseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_PROSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5-proseg' - : 'docker.io/quentinblampey/sopa:2.1.5-proseg'}" + ? 'docker://quentinblampey/sopa:2.1.6-proseg' + : 'docker.io/quentinblampey/sopa:2.1.6-proseg'}" input: tuple val(meta), path(sdata_path), path(patches_file_transcripts), path(transcript_patches) diff --git a/modules/local/patch_segmentation_stardist/environment.yml b/modules/local/patch_segmentation_stardist/environment.yml index 0d2babc..71db8a5 100644 --- a/modules/local/patch_segmentation_stardist/environment.yml +++ b/modules/local/patch_segmentation_stardist/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa[stardist]==2.1.5 + - sopa[stardist]==2.1.6 diff --git a/modules/local/patch_segmentation_stardist/main.nf b/modules/local/patch_segmentation_stardist/main.nf index a2e8c45..2f62bd5 100644 --- a/modules/local/patch_segmentation_stardist/main.nf +++ b/modules/local/patch_segmentation_stardist/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5-stardist' - : 'docker.io/quentinblampey/sopa:2.1.5-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.6-stardist' + : 'docker.io/quentinblampey/sopa:2.1.6-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/report/environment.yml b/modules/local/report/environment.yml index 1c9b41f..0f643ba 100644 --- a/modules/local/report/environment.yml +++ b/modules/local/report/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 diff --git a/modules/local/report/main.nf b/modules/local/report/main.nf index 25629ca..8d2bfb3 100644 --- a/modules/local/report/main.nf +++ b/modules/local/report/main.nf @@ -3,8 +3,8 @@ process REPORT { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5' - : 'docker.io/quentinblampey/sopa:2.1.5'}" + ? 'docker://quentinblampey/sopa:2.1.6' + : 'docker.io/quentinblampey/sopa:2.1.6'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/resolve_baysor/environment.yml b/modules/local/resolve_baysor/environment.yml index 5e7bc0a..3a43072 100644 --- a/modules/local/resolve_baysor/environment.yml +++ b/modules/local/resolve_baysor/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa[baysor]==2.1.5 + - sopa[baysor]==2.1.6 diff --git a/modules/local/resolve_baysor/main.nf b/modules/local/resolve_baysor/main.nf index 2a07494..5fba376 100644 --- a/modules/local/resolve_baysor/main.nf +++ b/modules/local/resolve_baysor/main.nf @@ -3,8 +3,8 @@ process RESOLVE_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5-baysor' - : 'docker.io/quentinblampey/sopa:2.1.5-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.6-baysor' + : 'docker.io/quentinblampey/sopa:2.1.6-baysor'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_cellpose/environment.yml b/modules/local/resolve_cellpose/environment.yml index 74f437b..91faa94 100644 --- a/modules/local/resolve_cellpose/environment.yml +++ b/modules/local/resolve_cellpose/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa[cellpose]==2.1.5 + - sopa[cellpose]==2.1.6 diff --git a/modules/local/resolve_cellpose/main.nf b/modules/local/resolve_cellpose/main.nf index f12498c..ad13026 100644 --- a/modules/local/resolve_cellpose/main.nf +++ b/modules/local/resolve_cellpose/main.nf @@ -3,8 +3,8 @@ process RESOLVE_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.5-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.6-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.6-cellpose'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_comseg/environment.yml b/modules/local/resolve_comseg/environment.yml index 9b94154..2654b07 100644 --- a/modules/local/resolve_comseg/environment.yml +++ b/modules/local/resolve_comseg/environment.yml @@ -5,5 +5,5 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 - comseg==1.8.2 diff --git a/modules/local/resolve_comseg/main.nf b/modules/local/resolve_comseg/main.nf index 77383b5..0c4403e 100644 --- a/modules/local/resolve_comseg/main.nf +++ b/modules/local/resolve_comseg/main.nf @@ -3,8 +3,8 @@ process RESOLVE_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5-comseg' - : 'docker.io/quentinblampey/sopa:2.1.5-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.6-comseg' + : 'docker.io/quentinblampey/sopa:2.1.6-comseg'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_stardist/environment.yml b/modules/local/resolve_stardist/environment.yml index 0d2babc..71db8a5 100644 --- a/modules/local/resolve_stardist/environment.yml +++ b/modules/local/resolve_stardist/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa[stardist]==2.1.5 + - sopa[stardist]==2.1.6 diff --git a/modules/local/resolve_stardist/main.nf b/modules/local/resolve_stardist/main.nf index 4616464..678a24b 100644 --- a/modules/local/resolve_stardist/main.nf +++ b/modules/local/resolve_stardist/main.nf @@ -3,8 +3,8 @@ process RESOLVE_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5-stardist' - : 'docker.io/quentinblampey/sopa:2.1.5-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.6-stardist' + : 'docker.io/quentinblampey/sopa:2.1.6-stardist'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/scanpy_preprocess/environment.yml b/modules/local/scanpy_preprocess/environment.yml index 1c9b41f..0f643ba 100644 --- a/modules/local/scanpy_preprocess/environment.yml +++ b/modules/local/scanpy_preprocess/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 diff --git a/modules/local/scanpy_preprocess/main.nf b/modules/local/scanpy_preprocess/main.nf index 2233d2c..7639b4b 100644 --- a/modules/local/scanpy_preprocess/main.nf +++ b/modules/local/scanpy_preprocess/main.nf @@ -3,8 +3,8 @@ process SCANPY_PREPROCESS { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5' - : 'docker.io/quentinblampey/sopa:2.1.5'}" + ? 'docker://quentinblampey/sopa:2.1.6' + : 'docker.io/quentinblampey/sopa:2.1.6'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tangram_annotation/environment.yml b/modules/local/tangram_annotation/environment.yml index 57774ea..650c28b 100644 --- a/modules/local/tangram_annotation/environment.yml +++ b/modules/local/tangram_annotation/environment.yml @@ -5,5 +5,5 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 - tangram-sc==1.0.4 diff --git a/modules/local/tangram_annotation/main.nf b/modules/local/tangram_annotation/main.nf index f6ff21a..26b251b 100644 --- a/modules/local/tangram_annotation/main.nf +++ b/modules/local/tangram_annotation/main.nf @@ -3,8 +3,8 @@ process TANGRAM_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5-tangram' - : 'docker.io/quentinblampey/sopa:2.1.5-tangram'}" + ? 'docker://quentinblampey/sopa:2.1.6-tangram' + : 'docker.io/quentinblampey/sopa:2.1.6-tangram'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tissue_segmentation/environment.yml b/modules/local/tissue_segmentation/environment.yml index 1c9b41f..0f643ba 100644 --- a/modules/local/tissue_segmentation/environment.yml +++ b/modules/local/tissue_segmentation/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 diff --git a/modules/local/tissue_segmentation/main.nf b/modules/local/tissue_segmentation/main.nf index bbef25b..169f393 100644 --- a/modules/local/tissue_segmentation/main.nf +++ b/modules/local/tissue_segmentation/main.nf @@ -3,8 +3,8 @@ process TISSUE_SEGMENTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5' - : 'docker.io/quentinblampey/sopa:2.1.5'}" + ? 'docker://quentinblampey/sopa:2.1.6' + : 'docker.io/quentinblampey/sopa:2.1.6'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/to_spatialdata/environment.yml b/modules/local/to_spatialdata/environment.yml index 1c9b41f..0f643ba 100644 --- a/modules/local/to_spatialdata/environment.yml +++ b/modules/local/to_spatialdata/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.5 + - sopa==2.1.6 diff --git a/modules/local/to_spatialdata/main.nf b/modules/local/to_spatialdata/main.nf index e8727b4..237de06 100644 --- a/modules/local/to_spatialdata/main.nf +++ b/modules/local/to_spatialdata/main.nf @@ -5,8 +5,8 @@ process TO_SPATIALDATA { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.5' - : 'docker.io/quentinblampey/sopa:2.1.5'}" + ? 'docker://quentinblampey/sopa:2.1.6' + : 'docker.io/quentinblampey/sopa:2.1.6'}" input: tuple val(meta), path(data_dir), path(fullres_image_file) diff --git a/nextflow_schema.json b/nextflow_schema.json index fabb78c..2924d8d 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -39,7 +39,7 @@ } }, "sopa_config": { - "title": "Sopa config (or params file)", + "title": "Sopa config (or params file) - we recommend providing an existing `-params-file` as detailed in the usage section", "type": "object", "fa_icon": "fas fa-rocket", "description": "Parameters related to Sopa", diff --git a/tests/.nftignore b/tests/.nftignore index f1416d9..7d01b42 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -16,3 +16,4 @@ pipeline_info/*.{html,json,txt,yml} **/zmetadata **/.sopa_cache **/.sopa_cache/** +**/table/** diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index 935f8de..1608095 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -4,15 +4,15 @@ 9, { "RESOLVE_BAYSOR": { - "sopa": "2.1.5", + "sopa": "2.1.6", "baysor": "0.7.1" }, "TANGRAM_ANNOTATION": { - "sopa": "2.1.5", + "sopa": "2.1.6", "tangram": "1.0.4" }, "TO_SPATIALDATA": { - "sopa": "2.1.5", + "sopa": "2.1.6", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, @@ -338,22 +338,6 @@ "sample_name.zarr/zmetadata" ], [ - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", @@ -371,6 +355,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-08-20T09:18:31.146178" + "timestamp": "2025-10-15T11:14:18.110413" } } \ No newline at end of file diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index aeccf92..e84939e 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -4,11 +4,11 @@ 8, { "RESOLVE_CELLPOSE": { - "sopa": "2.1.5", + "sopa": "2.1.6", "cellpose": "4.0.7" }, "TO_SPATIALDATA": { - "sopa": "2.1.5", + "sopa": "2.1.6", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index c610278..9e9d7b5 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -4,14 +4,18 @@ 8, { "FLUO_ANNOTATION": { - "sopa": "2.1.5" + "sopa": "2.1.6" }, "PATCH_SEGMENTATION_PROSEG": { - "sopa": "2.1.5", + "sopa": "2.1.6", "proseg": "3.0.8" }, + "SCANPY_PREPROCESS": { + "sopa": "2.1.6", + "scanpy": "1.11.4" + }, "TO_SPATIALDATA": { - "sopa": "2.1.5", + "sopa": "2.1.6", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, @@ -150,6 +154,18 @@ "sample_name.zarr/tables/table/layers", "sample_name.zarr/tables/table/layers/.zattrs", "sample_name.zarr/tables/table/layers/.zgroup", + "sample_name.zarr/tables/table/layers/counts", + "sample_name.zarr/tables/table/layers/counts/.zattrs", + "sample_name.zarr/tables/table/layers/counts/.zgroup", + "sample_name.zarr/tables/table/layers/counts/data", + "sample_name.zarr/tables/table/layers/counts/data/.zarray", + "sample_name.zarr/tables/table/layers/counts/data/0", + "sample_name.zarr/tables/table/layers/counts/indices", + "sample_name.zarr/tables/table/layers/counts/indices/.zarray", + "sample_name.zarr/tables/table/layers/counts/indices/0", + "sample_name.zarr/tables/table/layers/counts/indptr", + "sample_name.zarr/tables/table/layers/counts/indptr/.zarray", + "sample_name.zarr/tables/table/layers/counts/indptr/0", "sample_name.zarr/tables/table/obs", "sample_name.zarr/tables/table/obs/.zattrs", "sample_name.zarr/tables/table/obs/.zgroup", @@ -189,6 +205,17 @@ "sample_name.zarr/tables/table/obs/component/.zarray", "sample_name.zarr/tables/table/obs/component/.zattrs", "sample_name.zarr/tables/table/obs/component/0", + "sample_name.zarr/tables/table/obs/leiden", + "sample_name.zarr/tables/table/obs/leiden/.zattrs", + "sample_name.zarr/tables/table/obs/leiden/.zgroup", + "sample_name.zarr/tables/table/obs/leiden/categories", + "sample_name.zarr/tables/table/obs/leiden/categories/.zarray", + "sample_name.zarr/tables/table/obs/leiden/categories/.zattrs", + "sample_name.zarr/tables/table/obs/leiden/categories/0", + "sample_name.zarr/tables/table/obs/leiden/codes", + "sample_name.zarr/tables/table/obs/leiden/codes/.zarray", + "sample_name.zarr/tables/table/obs/leiden/codes/.zattrs", + "sample_name.zarr/tables/table/obs/leiden/codes/0", "sample_name.zarr/tables/table/obs/original_cell_id", "sample_name.zarr/tables/table/obs/original_cell_id/.zarray", "sample_name.zarr/tables/table/obs/original_cell_id/.zattrs", @@ -230,6 +257,16 @@ "sample_name.zarr/tables/table/obsm", "sample_name.zarr/tables/table/obsm/.zattrs", "sample_name.zarr/tables/table/obsm/.zgroup", + "sample_name.zarr/tables/table/obsm/X_pca", + "sample_name.zarr/tables/table/obsm/X_pca/.zarray", + "sample_name.zarr/tables/table/obsm/X_pca/.zattrs", + "sample_name.zarr/tables/table/obsm/X_pca/0", + "sample_name.zarr/tables/table/obsm/X_pca/0/0", + "sample_name.zarr/tables/table/obsm/X_umap", + "sample_name.zarr/tables/table/obsm/X_umap/.zarray", + "sample_name.zarr/tables/table/obsm/X_umap/.zattrs", + "sample_name.zarr/tables/table/obsm/X_umap/0", + "sample_name.zarr/tables/table/obsm/X_umap/0/0", "sample_name.zarr/tables/table/obsm/intensities", "sample_name.zarr/tables/table/obsm/intensities/.zattrs", "sample_name.zarr/tables/table/obsm/intensities/.zgroup", @@ -284,9 +321,117 @@ "sample_name.zarr/tables/table/obsp", "sample_name.zarr/tables/table/obsp/.zattrs", "sample_name.zarr/tables/table/obsp/.zgroup", + "sample_name.zarr/tables/table/obsp/connectivities", + "sample_name.zarr/tables/table/obsp/connectivities/.zattrs", + "sample_name.zarr/tables/table/obsp/connectivities/.zgroup", + "sample_name.zarr/tables/table/obsp/connectivities/data", + "sample_name.zarr/tables/table/obsp/connectivities/data/.zarray", + "sample_name.zarr/tables/table/obsp/connectivities/data/0", + "sample_name.zarr/tables/table/obsp/connectivities/indices", + "sample_name.zarr/tables/table/obsp/connectivities/indices/.zarray", + "sample_name.zarr/tables/table/obsp/connectivities/indices/0", + "sample_name.zarr/tables/table/obsp/connectivities/indptr", + "sample_name.zarr/tables/table/obsp/connectivities/indptr/.zarray", + "sample_name.zarr/tables/table/obsp/connectivities/indptr/0", + "sample_name.zarr/tables/table/obsp/distances", + "sample_name.zarr/tables/table/obsp/distances/.zattrs", + "sample_name.zarr/tables/table/obsp/distances/.zgroup", + "sample_name.zarr/tables/table/obsp/distances/data", + "sample_name.zarr/tables/table/obsp/distances/data/.zarray", + "sample_name.zarr/tables/table/obsp/distances/data/0", + "sample_name.zarr/tables/table/obsp/distances/indices", + "sample_name.zarr/tables/table/obsp/distances/indices/.zarray", + "sample_name.zarr/tables/table/obsp/distances/indices/0", + "sample_name.zarr/tables/table/obsp/distances/indptr", + "sample_name.zarr/tables/table/obsp/distances/indptr/.zarray", + "sample_name.zarr/tables/table/obsp/distances/indptr/0", "sample_name.zarr/tables/table/uns", "sample_name.zarr/tables/table/uns/.zattrs", "sample_name.zarr/tables/table/uns/.zgroup", + "sample_name.zarr/tables/table/uns/hvg", + "sample_name.zarr/tables/table/uns/hvg/.zattrs", + "sample_name.zarr/tables/table/uns/hvg/.zgroup", + "sample_name.zarr/tables/table/uns/hvg/flavor", + "sample_name.zarr/tables/table/uns/hvg/flavor/.zarray", + "sample_name.zarr/tables/table/uns/hvg/flavor/.zattrs", + "sample_name.zarr/tables/table/uns/hvg/flavor/0", + "sample_name.zarr/tables/table/uns/leiden", + "sample_name.zarr/tables/table/uns/leiden/.zattrs", + "sample_name.zarr/tables/table/uns/leiden/.zgroup", + "sample_name.zarr/tables/table/uns/leiden/params", + "sample_name.zarr/tables/table/uns/leiden/params/.zattrs", + "sample_name.zarr/tables/table/uns/leiden/params/.zgroup", + "sample_name.zarr/tables/table/uns/leiden/params/n_iterations", + "sample_name.zarr/tables/table/uns/leiden/params/n_iterations/.zarray", + "sample_name.zarr/tables/table/uns/leiden/params/n_iterations/.zattrs", + "sample_name.zarr/tables/table/uns/leiden/params/n_iterations/0", + "sample_name.zarr/tables/table/uns/leiden/params/random_state", + "sample_name.zarr/tables/table/uns/leiden/params/random_state/.zarray", + "sample_name.zarr/tables/table/uns/leiden/params/random_state/.zattrs", + "sample_name.zarr/tables/table/uns/leiden/params/random_state/0", + "sample_name.zarr/tables/table/uns/leiden/params/resolution", + "sample_name.zarr/tables/table/uns/leiden/params/resolution/.zarray", + "sample_name.zarr/tables/table/uns/leiden/params/resolution/.zattrs", + "sample_name.zarr/tables/table/uns/leiden/params/resolution/0", + "sample_name.zarr/tables/table/uns/log1p", + "sample_name.zarr/tables/table/uns/log1p/.zattrs", + "sample_name.zarr/tables/table/uns/log1p/.zgroup", + "sample_name.zarr/tables/table/uns/neighbors", + "sample_name.zarr/tables/table/uns/neighbors/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/.zgroup", + "sample_name.zarr/tables/table/uns/neighbors/connectivities_key", + "sample_name.zarr/tables/table/uns/neighbors/connectivities_key/.zarray", + "sample_name.zarr/tables/table/uns/neighbors/connectivities_key/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/connectivities_key/0", + "sample_name.zarr/tables/table/uns/neighbors/distances_key", + "sample_name.zarr/tables/table/uns/neighbors/distances_key/.zarray", + "sample_name.zarr/tables/table/uns/neighbors/distances_key/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/distances_key/0", + "sample_name.zarr/tables/table/uns/neighbors/params", + "sample_name.zarr/tables/table/uns/neighbors/params/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/params/.zgroup", + "sample_name.zarr/tables/table/uns/neighbors/params/method", + "sample_name.zarr/tables/table/uns/neighbors/params/method/.zarray", + "sample_name.zarr/tables/table/uns/neighbors/params/method/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/params/method/0", + "sample_name.zarr/tables/table/uns/neighbors/params/metric", + "sample_name.zarr/tables/table/uns/neighbors/params/metric/.zarray", + "sample_name.zarr/tables/table/uns/neighbors/params/metric/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/params/metric/0", + "sample_name.zarr/tables/table/uns/neighbors/params/n_neighbors", + "sample_name.zarr/tables/table/uns/neighbors/params/n_neighbors/.zarray", + "sample_name.zarr/tables/table/uns/neighbors/params/n_neighbors/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/params/n_neighbors/0", + "sample_name.zarr/tables/table/uns/neighbors/params/random_state", + "sample_name.zarr/tables/table/uns/neighbors/params/random_state/.zarray", + "sample_name.zarr/tables/table/uns/neighbors/params/random_state/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/params/random_state/0", + "sample_name.zarr/tables/table/uns/pca", + "sample_name.zarr/tables/table/uns/pca/.zattrs", + "sample_name.zarr/tables/table/uns/pca/.zgroup", + "sample_name.zarr/tables/table/uns/pca/params", + "sample_name.zarr/tables/table/uns/pca/params/.zattrs", + "sample_name.zarr/tables/table/uns/pca/params/.zgroup", + "sample_name.zarr/tables/table/uns/pca/params/mask_var", + "sample_name.zarr/tables/table/uns/pca/params/mask_var/.zarray", + "sample_name.zarr/tables/table/uns/pca/params/mask_var/.zattrs", + "sample_name.zarr/tables/table/uns/pca/params/mask_var/0", + "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable", + "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/.zarray", + "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/.zattrs", + "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/0", + "sample_name.zarr/tables/table/uns/pca/params/zero_center", + "sample_name.zarr/tables/table/uns/pca/params/zero_center/.zarray", + "sample_name.zarr/tables/table/uns/pca/params/zero_center/.zattrs", + "sample_name.zarr/tables/table/uns/pca/params/zero_center/0", + "sample_name.zarr/tables/table/uns/pca/variance", + "sample_name.zarr/tables/table/uns/pca/variance/.zarray", + "sample_name.zarr/tables/table/uns/pca/variance/.zattrs", + "sample_name.zarr/tables/table/uns/pca/variance/0", + "sample_name.zarr/tables/table/uns/pca/variance_ratio", + "sample_name.zarr/tables/table/uns/pca/variance_ratio/.zarray", + "sample_name.zarr/tables/table/uns/pca/variance_ratio/.zattrs", + "sample_name.zarr/tables/table/uns/pca/variance_ratio/0", "sample_name.zarr/tables/table/uns/proseg_run", "sample_name.zarr/tables/table/uns/proseg_run/.zattrs", "sample_name.zarr/tables/table/uns/proseg_run/.zgroup", @@ -332,6 +477,20 @@ "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/0", + "sample_name.zarr/tables/table/uns/umap", + "sample_name.zarr/tables/table/uns/umap/.zattrs", + "sample_name.zarr/tables/table/uns/umap/.zgroup", + "sample_name.zarr/tables/table/uns/umap/params", + "sample_name.zarr/tables/table/uns/umap/params/.zattrs", + "sample_name.zarr/tables/table/uns/umap/params/.zgroup", + "sample_name.zarr/tables/table/uns/umap/params/a", + "sample_name.zarr/tables/table/uns/umap/params/a/.zarray", + "sample_name.zarr/tables/table/uns/umap/params/a/.zattrs", + "sample_name.zarr/tables/table/uns/umap/params/a/0", + "sample_name.zarr/tables/table/uns/umap/params/b", + "sample_name.zarr/tables/table/uns/umap/params/b/.zarray", + "sample_name.zarr/tables/table/uns/umap/params/b/.zattrs", + "sample_name.zarr/tables/table/uns/umap/params/b/0", "sample_name.zarr/tables/table/var", "sample_name.zarr/tables/table/var/.zattrs", "sample_name.zarr/tables/table/var/.zgroup", @@ -339,14 +498,30 @@ "sample_name.zarr/tables/table/var/_index/.zarray", "sample_name.zarr/tables/table/var/_index/.zattrs", "sample_name.zarr/tables/table/var/_index/0", + "sample_name.zarr/tables/table/var/dispersions", + "sample_name.zarr/tables/table/var/dispersions/.zarray", + "sample_name.zarr/tables/table/var/dispersions/.zattrs", + "sample_name.zarr/tables/table/var/dispersions/0", + "sample_name.zarr/tables/table/var/dispersions_norm", + "sample_name.zarr/tables/table/var/dispersions_norm/.zarray", + "sample_name.zarr/tables/table/var/dispersions_norm/.zattrs", + "sample_name.zarr/tables/table/var/dispersions_norm/0", "sample_name.zarr/tables/table/var/gene", "sample_name.zarr/tables/table/var/gene/.zarray", "sample_name.zarr/tables/table/var/gene/.zattrs", "sample_name.zarr/tables/table/var/gene/0", + "sample_name.zarr/tables/table/var/highly_variable", + "sample_name.zarr/tables/table/var/highly_variable/.zarray", + "sample_name.zarr/tables/table/var/highly_variable/.zattrs", + "sample_name.zarr/tables/table/var/highly_variable/0", "sample_name.zarr/tables/table/var/lambda_bg_0", "sample_name.zarr/tables/table/var/lambda_bg_0/.zarray", "sample_name.zarr/tables/table/var/lambda_bg_0/.zattrs", "sample_name.zarr/tables/table/var/lambda_bg_0/0", + "sample_name.zarr/tables/table/var/means", + "sample_name.zarr/tables/table/var/means/.zarray", + "sample_name.zarr/tables/table/var/means/.zattrs", + "sample_name.zarr/tables/table/var/means/0", "sample_name.zarr/tables/table/var/total_count", "sample_name.zarr/tables/table/var/total_count/.zarray", "sample_name.zarr/tables/table/var/total_count/.zattrs", @@ -354,29 +529,17 @@ "sample_name.zarr/tables/table/varm", "sample_name.zarr/tables/table/varm/.zattrs", "sample_name.zarr/tables/table/varm/.zgroup", + "sample_name.zarr/tables/table/varm/PCs", + "sample_name.zarr/tables/table/varm/PCs/.zarray", + "sample_name.zarr/tables/table/varm/PCs/.zattrs", + "sample_name.zarr/tables/table/varm/PCs/0", + "sample_name.zarr/tables/table/varm/PCs/0/0", "sample_name.zarr/tables/table/varp", "sample_name.zarr/tables/table/varp/.zattrs", "sample_name.zarr/tables/table/varp/.zgroup", "sample_name.zarr/zmetadata" ], [ - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", @@ -394,6 +557,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-09-30T10:10:20.139347" + "timestamp": "2025-10-15T11:11:22.043613" } } \ No newline at end of file From a3d1ef662a258035fa3b90a9cf85c3c434fac590 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 15 Oct 2025 12:07:06 +0200 Subject: [PATCH 185/227] update snapshots --- tests/cellpose.nf.test.snap | 15 --------------- tests/default.nf.test.snap | 4 ++-- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index e84939e..8c54764 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -274,21 +274,6 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab" ] ], "meta": { diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 9e9d7b5..30936da 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -1,14 +1,14 @@ { "-profile test": { "content": [ - 8, + 9, { "FLUO_ANNOTATION": { "sopa": "2.1.6" }, "PATCH_SEGMENTATION_PROSEG": { "sopa": "2.1.6", - "proseg": "3.0.8" + "proseg": "3.0.10" }, "SCANPY_PREPROCESS": { "sopa": "2.1.6", From a7bbf8db6ad4f80ecea44610f152d4bf1545edd7 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 15 Oct 2025 13:04:29 +0200 Subject: [PATCH 186/227] fix cellpose snapshot --- tests/cellpose.nf.test.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 8c54764..783b1d3 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -273,7 +273,7 @@ ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", - ".zgroup:md5,e20297935e73dd0154104d4ea53040ab", + ".zgroup:md5,e20297935e73dd0154104d4ea53040ab" ] ], "meta": { From aa37eb72bbb44ab48604099a8c0412ddd214edee Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 15 Oct 2025 15:09:55 +0200 Subject: [PATCH 187/227] use process_low for PATCH_SEGMENTATION_STARDIST --- modules/local/patch_segmentation_stardist/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/patch_segmentation_stardist/main.nf b/modules/local/patch_segmentation_stardist/main.nf index 2f62bd5..3857672 100644 --- a/modules/local/patch_segmentation_stardist/main.nf +++ b/modules/local/patch_segmentation_stardist/main.nf @@ -1,5 +1,5 @@ process PATCH_SEGMENTATION_STARDIST { - label "process_single" + label "process_low" conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container From ec92fc766ddafbc4a2e4673cfe0b3ddda5574476 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 15 Oct 2025 15:57:15 +0200 Subject: [PATCH 188/227] can use a visium hd ID different than the sample name --- assets/schema_input.json | 6 +++++ conf/modules.config | 2 +- docs/usage.md | 25 ++++++++++--------- .../local/utils_nfcore_sopa_pipeline/main.nf | 18 +++++++------ 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/assets/schema_input.json b/assets/schema_input.json index 320bb9d..6f93309 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -11,6 +11,12 @@ "type": "string", "pattern": "^\\S+$", "errorMessage": "Sample name cannot contain spaces", + "meta": ["sample"] + }, + "id": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "ID cannot contain spaces", "meta": ["id"] }, "data_path": { diff --git a/conf/modules.config b/conf/modules.config index 8f67c34..6cb190b 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -14,7 +14,7 @@ process { withName: SPACERANGER_COUNT { ext.args = '--create-bam="false"' publishDir = [ - path: { "${params.outdir}/${meta.id}_spaceranger" }, + path: { "${params.outdir}/${meta.sample}_spaceranger" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] diff --git a/docs/usage.md b/docs/usage.md index 028336a..eaf20ff 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -53,18 +53,19 @@ We also provide a detailed description of what `data_path` should contain, depen Some extra columns need to be provided specifically for Visium HD. This is because we need to run [Space Ranger](https://www.10xgenomics.com/support/software/space-ranger/latest) before running Sopa. Note that the `image` is the full-resolution microscopy image (not the cytassist image) and is **required** by Sopa as we'll run cell segmentation on the H&E full-resolution slide. For more details, see the [`spaceranger-count` arguments](https://nf-co.re/modules/spaceranger_count). -| Column | Description | -| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `sample` | **Sample ID name**; designates the sample ID; must be unique for each slide. It will be used in the output directories names: `{sample}.zarr` and `{sample}.explorer`. _Required_ | -| `fastq_dir` | Path to directory where the sample FASTQ files are stored. May be a `.tar.gz` file instead of a directory. _Required_ | -| `image` | Brightfield microscopy image. _Required_ | -| `cytaimage` | Brightfield tissue image captured with Cytassist device. _Required_ | -| `slide` | The Visium slide ID used for the sequencing. _Required_ | -| `area` | Which slide area contains the tissue sample. _Required_ | -| `manual_alignment` | Path to the manual alignment file. _Optional_ | -| `slidefile` | Slide specification as JSON. Overrides `slide` and `area` if specified. _Optional_ | -| `colorizedimage` | A colour composite of one or more fluorescence image channels saved as a single-page, single-file colour TIFF or JPEG. _Optional_ | -| `darkimage` | Dark background fluorescence microscopy image. _Optional_ | +| Column | Description | +| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `sample` | **Sample ID name**; designates the sample ID; must be unique for each slide. It will be used in the output directories names: `{sample}.zarr` and `{sample}.explorer`. _Required_ | +| `id` | Name of the slide to be provided to Space Ranger. The sample can be deduced from the fastq*dir, as the fastq files should have the format `\_S\_L001*_001.fastq.gz`(where N is a number, and XX can be R1, R2, I1 or I2). By default, use the`sample` name. \_Optional_ | +| `fastq_dir` | Path to directory where the sample FASTQ files are stored. May be a `.tar.gz` file instead of a directory. _Required_ | +| `image` | Brightfield microscopy image. _Required_ | +| `cytaimage` | Brightfield tissue image captured with Cytassist device. _Required_ | +| `slide` | The Visium slide ID used for the sequencing. _Required_ | +| `area` | Which slide area contains the tissue sample. _Required_ | +| `manual_alignment` | Path to the manual alignment file. _Optional_ | +| `slidefile` | Slide specification as JSON. Overrides `slide` and `area` if specified. _Optional_ | +| `colorizedimage` | A colour composite of one or more fluorescence image channels saved as a single-page, single-file colour TIFF or JPEG. _Optional_ | +| `darkimage` | Dark background fluorescence microscopy image. _Optional_ | Here is a samplesheet example for one sample: diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index fbb7da5..0cd3b57 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -70,11 +70,11 @@ workflow PIPELINE_INITIALISATION { .map { meta, data_path -> if (!meta.fastq_dir) { if (!data_path) { - error("The data_path must be provided (path to the raw inputs)") + error("The `data_path` must be provided (path to the raw inputs), except when running on Visium HD data (in that case, the `fastq_dir` is required)") } - if (!meta.id) { - meta.id = file(data_path).baseName + if (!meta.sample) { + meta.sample = file(data_path).baseName } meta.data_dir = data_path @@ -83,16 +83,20 @@ workflow PIPELINE_INITIALISATION { // spaceranger output directory meta.data_dir = "outs" + if (!meta.sample) { + error("The `sample` column must be provided when running on Visium HD data") + } + if (!meta.id) { - error("The id must be provided when running on Visium HD data") + meta.id = meta.sample } if (!meta.image) { - error("The image (full resolution image) must be provided when running Sopa on Visium HD data - it is required for the cell segmentation") + error("The `image` column (full resolution image) must be provided when running Sopa on Visium HD data - it is required for the cell segmentation") } } - meta.sdata_dir = "${meta.id}.zarr" - meta.explorer_dir = "${meta.id}.explorer" + meta.sdata_dir = "${meta.sample}.zarr" + meta.explorer_dir = "${meta.sample}.explorer" return meta } From a14a2e86daa5c394519ab1c5512fe82c9b3c5e56 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 17 Oct 2025 17:26:41 +0200 Subject: [PATCH 189/227] fix ci --- ro-crate-metadata.json | 11 ++++++++--- tests/default.nf.test.snap | 1 - 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index a812c12..2591a6f 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "Stable", "datePublished": "2025-10-16T13:38:45+00:00", - "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new/nf-core/sopa)\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.04.0-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.4.1-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.4.1)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is a bioinformatics pipeline that ...\n\n\n\n\n\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\n\n\nNow, you can run the pipeline using:\n\n\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new/nf-core/sopa)\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.04.0-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.4.1-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.4.1)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n> [!WARNING]\n> If you are interested in the main Sopa python package, refer to [this Sopa repository](https://github.com/gustaveroussy/sopa). Else, if you want to use Nextflow, you are in the good place.\n\n

    \n \"sopa_overview\"\n

    \n\n1. (Visium HD only) Raw data processing with Space Ranger\n2. (Optional) Tissue segmentation\n3. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n4. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n5. (Optional) Cell-type annotation\n6. User-friendly output creation for visualization and quick analysis\n7. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://github.com/gustaveroussy/sopa).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-of-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose the Sopa parameters. You can find existing Sopa params files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n -params-file \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by [Quentin Blampey](https://github.com/quentinblampey) during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, Universit\u00e9 Paris-Saclay, and Cure51.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n- [Matthias H\u00f6rtenhuber](https://github.com/mashehu)\n- [Kevin Weiss](https://github.com/kweisscure51)\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" @@ -163,8 +163,13 @@ "sdPublisher": { "@id": "https://nf-co.re/" }, - "url": ["https://github.com/nf-core/sopa", "https://nf-co.re/sopa/1.0.0/"], - "version": ["1.0.0"] + "url": [ + "https://github.com/nf-core/sopa", + "https://nf-co.re/sopa/1.0.0/" + ], + "version": [ + "1.0.0" + ] }, { "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow", diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 30936da..05bf7f3 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -1,7 +1,6 @@ { "-profile test": { "content": [ - 9, { "FLUO_ANNOTATION": { "sopa": "2.1.6" From 39c8881ed8622ffb959f9df8758853d16cd7721e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Mon, 3 Nov 2025 16:53:26 +0100 Subject: [PATCH 190/227] Update to new runner size syntax See https://nfcore.slack.com/archives/C050DNB6K5H/p1762184179238379 for details --- .github/workflows/nf-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nf-test.yml b/.github/workflows/nf-test.yml index 7a5bb7f..8886f92 100644 --- a/.github/workflows/nf-test.yml +++ b/.github/workflows/nf-test.yml @@ -64,7 +64,7 @@ jobs: runs-on: # use self-hosted runners - runs-on=${{ github.run_id }}-nf-test - runner=4cpu-linux-x64 - - disk=large + - volume=80gb strategy: fail-fast: false matrix: From c7210c9217ddf7609050b1400e2227219451f6b4 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 4 Nov 2025 16:42:36 +0100 Subject: [PATCH 191/227] upgrade to sopa 2.1.7 --- modules/local/aggregate/main.nf | 4 ++-- modules/local/explorer/main.nf | 4 ++-- modules/local/explorer_raw/main.nf | 4 ++-- modules/local/fluo_annotation/main.nf | 4 ++-- modules/local/make_image_patches/main.nf | 4 ++-- modules/local/make_transcript_patches/main.nf | 4 ++-- modules/local/patch_segmentation_baysor/main.nf | 4 ++-- modules/local/patch_segmentation_cellpose/main.nf | 4 ++-- modules/local/patch_segmentation_comseg/main.nf | 4 ++-- modules/local/patch_segmentation_proseg/main.nf | 4 ++-- modules/local/patch_segmentation_stardist/main.nf | 4 ++-- modules/local/report/main.nf | 4 ++-- modules/local/resolve_baysor/main.nf | 4 ++-- modules/local/resolve_cellpose/main.nf | 4 ++-- modules/local/resolve_comseg/main.nf | 4 ++-- modules/local/resolve_stardist/main.nf | 4 ++-- modules/local/scanpy_preprocess/main.nf | 4 ++-- modules/local/tangram_annotation/main.nf | 4 ++-- modules/local/tissue_segmentation/main.nf | 4 ++-- modules/local/to_spatialdata/main.nf | 4 ++-- tests/baysor.nf.test.snap | 6 +++--- tests/cellpose.nf.test.snap | 4 ++-- tests/default.nf.test.snap | 8 ++++---- 23 files changed, 49 insertions(+), 49 deletions(-) diff --git a/modules/local/aggregate/main.nf b/modules/local/aggregate/main.nf index 36325cb..55c60e4 100644 --- a/modules/local/aggregate/main.nf +++ b/modules/local/aggregate/main.nf @@ -3,8 +3,8 @@ process AGGREGATE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6' - : 'docker.io/quentinblampey/sopa:2.1.6'}" + ? 'docker://quentinblampey/sopa:2.1.7' + : 'docker.io/quentinblampey/sopa:2.1.7'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/explorer/main.nf b/modules/local/explorer/main.nf index 3367f73..01426a5 100644 --- a/modules/local/explorer/main.nf +++ b/modules/local/explorer/main.nf @@ -3,8 +3,8 @@ process EXPLORER { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6' - : 'docker.io/quentinblampey/sopa:2.1.6'}" + ? 'docker://quentinblampey/sopa:2.1.7' + : 'docker.io/quentinblampey/sopa:2.1.7'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/explorer_raw/main.nf b/modules/local/explorer_raw/main.nf index e0e3fe3..3cccf87 100644 --- a/modules/local/explorer_raw/main.nf +++ b/modules/local/explorer_raw/main.nf @@ -5,8 +5,8 @@ process EXPLORER_RAW { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6' - : 'docker.io/quentinblampey/sopa:2.1.6'}" + ? 'docker://quentinblampey/sopa:2.1.7' + : 'docker.io/quentinblampey/sopa:2.1.7'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/fluo_annotation/main.nf b/modules/local/fluo_annotation/main.nf index 16ef797..94c4365 100644 --- a/modules/local/fluo_annotation/main.nf +++ b/modules/local/fluo_annotation/main.nf @@ -3,8 +3,8 @@ process FLUO_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6' - : 'docker.io/quentinblampey/sopa:2.1.6'}" + ? 'docker://quentinblampey/sopa:2.1.7' + : 'docker.io/quentinblampey/sopa:2.1.7'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_image_patches/main.nf b/modules/local/make_image_patches/main.nf index d20a7cd..453ab6a 100644 --- a/modules/local/make_image_patches/main.nf +++ b/modules/local/make_image_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_IMAGE_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6' - : 'docker.io/quentinblampey/sopa:2.1.6'}" + ? 'docker://quentinblampey/sopa:2.1.7' + : 'docker.io/quentinblampey/sopa:2.1.7'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_transcript_patches/main.nf b/modules/local/make_transcript_patches/main.nf index 2334747..1cad0ab 100644 --- a/modules/local/make_transcript_patches/main.nf +++ b/modules/local/make_transcript_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_TRANSCRIPT_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6' - : 'docker.io/quentinblampey/sopa:2.1.6'}" + ? 'docker://quentinblampey/sopa:2.1.7' + : 'docker.io/quentinblampey/sopa:2.1.7'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/patch_segmentation_baysor/main.nf b/modules/local/patch_segmentation_baysor/main.nf index 8d22841..83cdf5b 100644 --- a/modules/local/patch_segmentation_baysor/main.nf +++ b/modules/local/patch_segmentation_baysor/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6-baysor' - : 'docker.io/quentinblampey/sopa:2.1.6-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.7-baysor' + : 'docker.io/quentinblampey/sopa:2.1.7-baysor'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_cellpose/main.nf b/modules/local/patch_segmentation_cellpose/main.nf index 2693bb8..7878d4d 100644 --- a/modules/local/patch_segmentation_cellpose/main.nf +++ b/modules/local/patch_segmentation_cellpose/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.6-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.7-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.7-cellpose'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_comseg/main.nf b/modules/local/patch_segmentation_comseg/main.nf index 316e36e..9fc1956 100644 --- a/modules/local/patch_segmentation_comseg/main.nf +++ b/modules/local/patch_segmentation_comseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6-comseg' - : 'docker.io/quentinblampey/sopa:2.1.6-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.7-comseg' + : 'docker.io/quentinblampey/sopa:2.1.7-comseg'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_proseg/main.nf b/modules/local/patch_segmentation_proseg/main.nf index a0323cb..aa64d76 100644 --- a/modules/local/patch_segmentation_proseg/main.nf +++ b/modules/local/patch_segmentation_proseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_PROSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6-proseg' - : 'docker.io/quentinblampey/sopa:2.1.6-proseg'}" + ? 'docker://quentinblampey/sopa:2.1.7-proseg' + : 'docker.io/quentinblampey/sopa:2.1.7-proseg'}" input: tuple val(meta), path(sdata_path), path(patches_file_transcripts), path(transcript_patches) diff --git a/modules/local/patch_segmentation_stardist/main.nf b/modules/local/patch_segmentation_stardist/main.nf index 3857672..a61d7d2 100644 --- a/modules/local/patch_segmentation_stardist/main.nf +++ b/modules/local/patch_segmentation_stardist/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6-stardist' - : 'docker.io/quentinblampey/sopa:2.1.6-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.7-stardist' + : 'docker.io/quentinblampey/sopa:2.1.7-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/report/main.nf b/modules/local/report/main.nf index 8d2bfb3..42faef3 100644 --- a/modules/local/report/main.nf +++ b/modules/local/report/main.nf @@ -3,8 +3,8 @@ process REPORT { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6' - : 'docker.io/quentinblampey/sopa:2.1.6'}" + ? 'docker://quentinblampey/sopa:2.1.7' + : 'docker.io/quentinblampey/sopa:2.1.7'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/resolve_baysor/main.nf b/modules/local/resolve_baysor/main.nf index 5fba376..b7db6af 100644 --- a/modules/local/resolve_baysor/main.nf +++ b/modules/local/resolve_baysor/main.nf @@ -3,8 +3,8 @@ process RESOLVE_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6-baysor' - : 'docker.io/quentinblampey/sopa:2.1.6-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.7-baysor' + : 'docker.io/quentinblampey/sopa:2.1.7-baysor'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_cellpose/main.nf b/modules/local/resolve_cellpose/main.nf index ad13026..ed2dee5 100644 --- a/modules/local/resolve_cellpose/main.nf +++ b/modules/local/resolve_cellpose/main.nf @@ -3,8 +3,8 @@ process RESOLVE_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.6-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.7-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.7-cellpose'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_comseg/main.nf b/modules/local/resolve_comseg/main.nf index 0c4403e..c1acc8d 100644 --- a/modules/local/resolve_comseg/main.nf +++ b/modules/local/resolve_comseg/main.nf @@ -3,8 +3,8 @@ process RESOLVE_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6-comseg' - : 'docker.io/quentinblampey/sopa:2.1.6-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.7-comseg' + : 'docker.io/quentinblampey/sopa:2.1.7-comseg'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_stardist/main.nf b/modules/local/resolve_stardist/main.nf index 678a24b..6cf3a0a 100644 --- a/modules/local/resolve_stardist/main.nf +++ b/modules/local/resolve_stardist/main.nf @@ -3,8 +3,8 @@ process RESOLVE_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6-stardist' - : 'docker.io/quentinblampey/sopa:2.1.6-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.7-stardist' + : 'docker.io/quentinblampey/sopa:2.1.7-stardist'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/scanpy_preprocess/main.nf b/modules/local/scanpy_preprocess/main.nf index 7639b4b..5b9e9b3 100644 --- a/modules/local/scanpy_preprocess/main.nf +++ b/modules/local/scanpy_preprocess/main.nf @@ -3,8 +3,8 @@ process SCANPY_PREPROCESS { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6' - : 'docker.io/quentinblampey/sopa:2.1.6'}" + ? 'docker://quentinblampey/sopa:2.1.7' + : 'docker.io/quentinblampey/sopa:2.1.7'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tangram_annotation/main.nf b/modules/local/tangram_annotation/main.nf index 26b251b..c24163c 100644 --- a/modules/local/tangram_annotation/main.nf +++ b/modules/local/tangram_annotation/main.nf @@ -3,8 +3,8 @@ process TANGRAM_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6-tangram' - : 'docker.io/quentinblampey/sopa:2.1.6-tangram'}" + ? 'docker://quentinblampey/sopa:2.1.7-tangram' + : 'docker.io/quentinblampey/sopa:2.1.7-tangram'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tissue_segmentation/main.nf b/modules/local/tissue_segmentation/main.nf index 169f393..0d8a896 100644 --- a/modules/local/tissue_segmentation/main.nf +++ b/modules/local/tissue_segmentation/main.nf @@ -3,8 +3,8 @@ process TISSUE_SEGMENTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6' - : 'docker.io/quentinblampey/sopa:2.1.6'}" + ? 'docker://quentinblampey/sopa:2.1.7' + : 'docker.io/quentinblampey/sopa:2.1.7'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/to_spatialdata/main.nf b/modules/local/to_spatialdata/main.nf index 237de06..d9315d7 100644 --- a/modules/local/to_spatialdata/main.nf +++ b/modules/local/to_spatialdata/main.nf @@ -5,8 +5,8 @@ process TO_SPATIALDATA { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.6' - : 'docker.io/quentinblampey/sopa:2.1.6'}" + ? 'docker://quentinblampey/sopa:2.1.7' + : 'docker.io/quentinblampey/sopa:2.1.7'}" input: tuple val(meta), path(data_dir), path(fullres_image_file) diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index 1608095..5b8d0f0 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -4,15 +4,15 @@ 9, { "RESOLVE_BAYSOR": { - "sopa": "2.1.6", + "sopa": "2.1.7", "baysor": "0.7.1" }, "TANGRAM_ANNOTATION": { - "sopa": "2.1.6", + "sopa": "2.1.7", "tangram": "1.0.4" }, "TO_SPATIALDATA": { - "sopa": "2.1.6", + "sopa": "2.1.7", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 783b1d3..b87bc2a 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -4,11 +4,11 @@ 8, { "RESOLVE_CELLPOSE": { - "sopa": "2.1.6", + "sopa": "2.1.7", "cellpose": "4.0.7" }, "TO_SPATIALDATA": { - "sopa": "2.1.6", + "sopa": "2.1.7", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 05bf7f3..159468d 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -3,18 +3,18 @@ "content": [ { "FLUO_ANNOTATION": { - "sopa": "2.1.6" + "sopa": "2.1.7" }, "PATCH_SEGMENTATION_PROSEG": { - "sopa": "2.1.6", + "sopa": "2.1.7", "proseg": "3.0.10" }, "SCANPY_PREPROCESS": { - "sopa": "2.1.6", + "sopa": "2.1.7", "scanpy": "1.11.4" }, "TO_SPATIALDATA": { - "sopa": "2.1.6", + "sopa": "2.1.7", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, From 75ddff1f6df2df59463c3a9be790b147804ae3f1 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 4 Nov 2025 17:45:25 +0100 Subject: [PATCH 192/227] use sopa 2.1.8 in docker images --- modules/local/aggregate/main.nf | 4 ++-- modules/local/explorer/main.nf | 4 ++-- modules/local/explorer_raw/main.nf | 4 ++-- modules/local/fluo_annotation/main.nf | 4 ++-- modules/local/make_image_patches/main.nf | 4 ++-- modules/local/make_transcript_patches/main.nf | 4 ++-- modules/local/patch_segmentation_baysor/main.nf | 4 ++-- modules/local/patch_segmentation_cellpose/main.nf | 4 ++-- modules/local/patch_segmentation_comseg/main.nf | 4 ++-- modules/local/patch_segmentation_proseg/main.nf | 4 ++-- modules/local/patch_segmentation_stardist/main.nf | 4 ++-- modules/local/report/main.nf | 4 ++-- modules/local/resolve_baysor/main.nf | 4 ++-- modules/local/resolve_cellpose/main.nf | 4 ++-- modules/local/resolve_comseg/main.nf | 4 ++-- modules/local/resolve_stardist/main.nf | 4 ++-- modules/local/scanpy_preprocess/main.nf | 4 ++-- modules/local/tangram_annotation/main.nf | 4 ++-- modules/local/tissue_segmentation/main.nf | 4 ++-- modules/local/to_spatialdata/main.nf | 4 ++-- tests/baysor.nf.test.snap | 6 +++--- tests/cellpose.nf.test.snap | 4 ++-- tests/default.nf.test.snap | 8 ++++---- 23 files changed, 49 insertions(+), 49 deletions(-) diff --git a/modules/local/aggregate/main.nf b/modules/local/aggregate/main.nf index 55c60e4..d5ec577 100644 --- a/modules/local/aggregate/main.nf +++ b/modules/local/aggregate/main.nf @@ -3,8 +3,8 @@ process AGGREGATE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7' - : 'docker.io/quentinblampey/sopa:2.1.7'}" + ? 'docker://quentinblampey/sopa:2.1.8' + : 'docker.io/quentinblampey/sopa:2.1.8'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/explorer/main.nf b/modules/local/explorer/main.nf index 01426a5..053c339 100644 --- a/modules/local/explorer/main.nf +++ b/modules/local/explorer/main.nf @@ -3,8 +3,8 @@ process EXPLORER { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7' - : 'docker.io/quentinblampey/sopa:2.1.7'}" + ? 'docker://quentinblampey/sopa:2.1.8' + : 'docker.io/quentinblampey/sopa:2.1.8'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/explorer_raw/main.nf b/modules/local/explorer_raw/main.nf index 3cccf87..c20bcf4 100644 --- a/modules/local/explorer_raw/main.nf +++ b/modules/local/explorer_raw/main.nf @@ -5,8 +5,8 @@ process EXPLORER_RAW { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7' - : 'docker.io/quentinblampey/sopa:2.1.7'}" + ? 'docker://quentinblampey/sopa:2.1.8' + : 'docker.io/quentinblampey/sopa:2.1.8'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/fluo_annotation/main.nf b/modules/local/fluo_annotation/main.nf index 94c4365..39d5d0a 100644 --- a/modules/local/fluo_annotation/main.nf +++ b/modules/local/fluo_annotation/main.nf @@ -3,8 +3,8 @@ process FLUO_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7' - : 'docker.io/quentinblampey/sopa:2.1.7'}" + ? 'docker://quentinblampey/sopa:2.1.8' + : 'docker.io/quentinblampey/sopa:2.1.8'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_image_patches/main.nf b/modules/local/make_image_patches/main.nf index 453ab6a..27d90e4 100644 --- a/modules/local/make_image_patches/main.nf +++ b/modules/local/make_image_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_IMAGE_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7' - : 'docker.io/quentinblampey/sopa:2.1.7'}" + ? 'docker://quentinblampey/sopa:2.1.8' + : 'docker.io/quentinblampey/sopa:2.1.8'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_transcript_patches/main.nf b/modules/local/make_transcript_patches/main.nf index 1cad0ab..9aed5d3 100644 --- a/modules/local/make_transcript_patches/main.nf +++ b/modules/local/make_transcript_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_TRANSCRIPT_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7' - : 'docker.io/quentinblampey/sopa:2.1.7'}" + ? 'docker://quentinblampey/sopa:2.1.8' + : 'docker.io/quentinblampey/sopa:2.1.8'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/patch_segmentation_baysor/main.nf b/modules/local/patch_segmentation_baysor/main.nf index 83cdf5b..b7bb250 100644 --- a/modules/local/patch_segmentation_baysor/main.nf +++ b/modules/local/patch_segmentation_baysor/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7-baysor' - : 'docker.io/quentinblampey/sopa:2.1.7-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.8-baysor' + : 'docker.io/quentinblampey/sopa:2.1.8-baysor'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_cellpose/main.nf b/modules/local/patch_segmentation_cellpose/main.nf index 7878d4d..6cb8f5d 100644 --- a/modules/local/patch_segmentation_cellpose/main.nf +++ b/modules/local/patch_segmentation_cellpose/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.7-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.8-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.8-cellpose'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_comseg/main.nf b/modules/local/patch_segmentation_comseg/main.nf index 9fc1956..54aa867 100644 --- a/modules/local/patch_segmentation_comseg/main.nf +++ b/modules/local/patch_segmentation_comseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7-comseg' - : 'docker.io/quentinblampey/sopa:2.1.7-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.8-comseg' + : 'docker.io/quentinblampey/sopa:2.1.8-comseg'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_proseg/main.nf b/modules/local/patch_segmentation_proseg/main.nf index aa64d76..7eb6c51 100644 --- a/modules/local/patch_segmentation_proseg/main.nf +++ b/modules/local/patch_segmentation_proseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_PROSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7-proseg' - : 'docker.io/quentinblampey/sopa:2.1.7-proseg'}" + ? 'docker://quentinblampey/sopa:2.1.8-proseg' + : 'docker.io/quentinblampey/sopa:2.1.8-proseg'}" input: tuple val(meta), path(sdata_path), path(patches_file_transcripts), path(transcript_patches) diff --git a/modules/local/patch_segmentation_stardist/main.nf b/modules/local/patch_segmentation_stardist/main.nf index a61d7d2..755c97e 100644 --- a/modules/local/patch_segmentation_stardist/main.nf +++ b/modules/local/patch_segmentation_stardist/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7-stardist' - : 'docker.io/quentinblampey/sopa:2.1.7-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.8-stardist' + : 'docker.io/quentinblampey/sopa:2.1.8-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/report/main.nf b/modules/local/report/main.nf index 42faef3..36770e2 100644 --- a/modules/local/report/main.nf +++ b/modules/local/report/main.nf @@ -3,8 +3,8 @@ process REPORT { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7' - : 'docker.io/quentinblampey/sopa:2.1.7'}" + ? 'docker://quentinblampey/sopa:2.1.8' + : 'docker.io/quentinblampey/sopa:2.1.8'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/resolve_baysor/main.nf b/modules/local/resolve_baysor/main.nf index b7db6af..9e24a89 100644 --- a/modules/local/resolve_baysor/main.nf +++ b/modules/local/resolve_baysor/main.nf @@ -3,8 +3,8 @@ process RESOLVE_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7-baysor' - : 'docker.io/quentinblampey/sopa:2.1.7-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.8-baysor' + : 'docker.io/quentinblampey/sopa:2.1.8-baysor'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_cellpose/main.nf b/modules/local/resolve_cellpose/main.nf index ed2dee5..a14ff57 100644 --- a/modules/local/resolve_cellpose/main.nf +++ b/modules/local/resolve_cellpose/main.nf @@ -3,8 +3,8 @@ process RESOLVE_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.7-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.8-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.8-cellpose'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_comseg/main.nf b/modules/local/resolve_comseg/main.nf index c1acc8d..9dcfaef 100644 --- a/modules/local/resolve_comseg/main.nf +++ b/modules/local/resolve_comseg/main.nf @@ -3,8 +3,8 @@ process RESOLVE_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7-comseg' - : 'docker.io/quentinblampey/sopa:2.1.7-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.8-comseg' + : 'docker.io/quentinblampey/sopa:2.1.8-comseg'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_stardist/main.nf b/modules/local/resolve_stardist/main.nf index 6cf3a0a..f0243ed 100644 --- a/modules/local/resolve_stardist/main.nf +++ b/modules/local/resolve_stardist/main.nf @@ -3,8 +3,8 @@ process RESOLVE_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7-stardist' - : 'docker.io/quentinblampey/sopa:2.1.7-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.8-stardist' + : 'docker.io/quentinblampey/sopa:2.1.8-stardist'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/scanpy_preprocess/main.nf b/modules/local/scanpy_preprocess/main.nf index 5b9e9b3..a76b604 100644 --- a/modules/local/scanpy_preprocess/main.nf +++ b/modules/local/scanpy_preprocess/main.nf @@ -3,8 +3,8 @@ process SCANPY_PREPROCESS { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7' - : 'docker.io/quentinblampey/sopa:2.1.7'}" + ? 'docker://quentinblampey/sopa:2.1.8' + : 'docker.io/quentinblampey/sopa:2.1.8'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tangram_annotation/main.nf b/modules/local/tangram_annotation/main.nf index c24163c..a1dae87 100644 --- a/modules/local/tangram_annotation/main.nf +++ b/modules/local/tangram_annotation/main.nf @@ -3,8 +3,8 @@ process TANGRAM_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7-tangram' - : 'docker.io/quentinblampey/sopa:2.1.7-tangram'}" + ? 'docker://quentinblampey/sopa:2.1.8-tangram' + : 'docker.io/quentinblampey/sopa:2.1.8-tangram'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tissue_segmentation/main.nf b/modules/local/tissue_segmentation/main.nf index 0d8a896..38e34a6 100644 --- a/modules/local/tissue_segmentation/main.nf +++ b/modules/local/tissue_segmentation/main.nf @@ -3,8 +3,8 @@ process TISSUE_SEGMENTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7' - : 'docker.io/quentinblampey/sopa:2.1.7'}" + ? 'docker://quentinblampey/sopa:2.1.8' + : 'docker.io/quentinblampey/sopa:2.1.8'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/to_spatialdata/main.nf b/modules/local/to_spatialdata/main.nf index d9315d7..9de77a1 100644 --- a/modules/local/to_spatialdata/main.nf +++ b/modules/local/to_spatialdata/main.nf @@ -5,8 +5,8 @@ process TO_SPATIALDATA { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.7' - : 'docker.io/quentinblampey/sopa:2.1.7'}" + ? 'docker://quentinblampey/sopa:2.1.8' + : 'docker.io/quentinblampey/sopa:2.1.8'}" input: tuple val(meta), path(data_dir), path(fullres_image_file) diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index 5b8d0f0..7c58ec0 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -4,15 +4,15 @@ 9, { "RESOLVE_BAYSOR": { - "sopa": "2.1.7", + "sopa": "2.1.8", "baysor": "0.7.1" }, "TANGRAM_ANNOTATION": { - "sopa": "2.1.7", + "sopa": "2.1.8", "tangram": "1.0.4" }, "TO_SPATIALDATA": { - "sopa": "2.1.7", + "sopa": "2.1.8", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index b87bc2a..9a92b79 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -4,11 +4,11 @@ 8, { "RESOLVE_CELLPOSE": { - "sopa": "2.1.7", + "sopa": "2.1.8", "cellpose": "4.0.7" }, "TO_SPATIALDATA": { - "sopa": "2.1.7", + "sopa": "2.1.8", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 159468d..d88edd2 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -3,18 +3,18 @@ "content": [ { "FLUO_ANNOTATION": { - "sopa": "2.1.7" + "sopa": "2.1.8" }, "PATCH_SEGMENTATION_PROSEG": { - "sopa": "2.1.7", + "sopa": "2.1.8", "proseg": "3.0.10" }, "SCANPY_PREPROCESS": { - "sopa": "2.1.7", + "sopa": "2.1.8", "scanpy": "1.11.4" }, "TO_SPATIALDATA": { - "sopa": "2.1.7", + "sopa": "2.1.8", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, From 0dd21c6e8619acf8cda35f86755ece1122639248 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 4 Nov 2025 18:04:02 +0100 Subject: [PATCH 193/227] update proseg snapshot --- tests/default.nf.test.snap | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index d88edd2..e8f990b 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -11,7 +11,7 @@ }, "SCANPY_PREPROCESS": { "sopa": "2.1.8", - "scanpy": "1.11.4" + "scanpy": "1.11.5" }, "TO_SPATIALDATA": { "sopa": "2.1.8", @@ -347,13 +347,6 @@ "sample_name.zarr/tables/table/uns", "sample_name.zarr/tables/table/uns/.zattrs", "sample_name.zarr/tables/table/uns/.zgroup", - "sample_name.zarr/tables/table/uns/hvg", - "sample_name.zarr/tables/table/uns/hvg/.zattrs", - "sample_name.zarr/tables/table/uns/hvg/.zgroup", - "sample_name.zarr/tables/table/uns/hvg/flavor", - "sample_name.zarr/tables/table/uns/hvg/flavor/.zarray", - "sample_name.zarr/tables/table/uns/hvg/flavor/.zattrs", - "sample_name.zarr/tables/table/uns/hvg/flavor/0", "sample_name.zarr/tables/table/uns/leiden", "sample_name.zarr/tables/table/uns/leiden/.zattrs", "sample_name.zarr/tables/table/uns/leiden/.zgroup", @@ -411,10 +404,6 @@ "sample_name.zarr/tables/table/uns/pca/params", "sample_name.zarr/tables/table/uns/pca/params/.zattrs", "sample_name.zarr/tables/table/uns/pca/params/.zgroup", - "sample_name.zarr/tables/table/uns/pca/params/mask_var", - "sample_name.zarr/tables/table/uns/pca/params/mask_var/.zarray", - "sample_name.zarr/tables/table/uns/pca/params/mask_var/.zattrs", - "sample_name.zarr/tables/table/uns/pca/params/mask_var/0", "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable", "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/.zarray", "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/.zattrs", @@ -497,30 +486,14 @@ "sample_name.zarr/tables/table/var/_index/.zarray", "sample_name.zarr/tables/table/var/_index/.zattrs", "sample_name.zarr/tables/table/var/_index/0", - "sample_name.zarr/tables/table/var/dispersions", - "sample_name.zarr/tables/table/var/dispersions/.zarray", - "sample_name.zarr/tables/table/var/dispersions/.zattrs", - "sample_name.zarr/tables/table/var/dispersions/0", - "sample_name.zarr/tables/table/var/dispersions_norm", - "sample_name.zarr/tables/table/var/dispersions_norm/.zarray", - "sample_name.zarr/tables/table/var/dispersions_norm/.zattrs", - "sample_name.zarr/tables/table/var/dispersions_norm/0", "sample_name.zarr/tables/table/var/gene", "sample_name.zarr/tables/table/var/gene/.zarray", "sample_name.zarr/tables/table/var/gene/.zattrs", "sample_name.zarr/tables/table/var/gene/0", - "sample_name.zarr/tables/table/var/highly_variable", - "sample_name.zarr/tables/table/var/highly_variable/.zarray", - "sample_name.zarr/tables/table/var/highly_variable/.zattrs", - "sample_name.zarr/tables/table/var/highly_variable/0", "sample_name.zarr/tables/table/var/lambda_bg_0", "sample_name.zarr/tables/table/var/lambda_bg_0/.zarray", "sample_name.zarr/tables/table/var/lambda_bg_0/.zattrs", "sample_name.zarr/tables/table/var/lambda_bg_0/0", - "sample_name.zarr/tables/table/var/means", - "sample_name.zarr/tables/table/var/means/.zarray", - "sample_name.zarr/tables/table/var/means/.zattrs", - "sample_name.zarr/tables/table/var/means/0", "sample_name.zarr/tables/table/var/total_count", "sample_name.zarr/tables/table/var/total_count/.zarray", "sample_name.zarr/tables/table/var/total_count/.zattrs", From d34fd46aa4c5226ef90e3044c47495cfc03abc4c Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 5 Nov 2025 15:49:44 +0100 Subject: [PATCH 194/227] add profiles for the sopa params --- .gitignore | 1 + conf/predefined/cosmx_baysor.config | 45 +++++++++++++++ conf/predefined/cosmx_cellpose.config | 27 +++++++++ conf/predefined/cosmx_cellpose_baysor.config | 56 ++++++++++++++++++ conf/predefined/cosmx_proseg.config | 21 +++++++ conf/predefined/hyperion_base.config | 29 ++++++++++ conf/predefined/macsima_base.config | 29 ++++++++++ .../merscope_baysor_cellpose.config | 57 +++++++++++++++++++ conf/predefined/merscope_baysor_vizgen.config | 47 +++++++++++++++ conf/predefined/merscope_cellpose.config | 28 +++++++++ conf/predefined/merscope_proseg.config | 22 +++++++ conf/predefined/phenocycler_base_10X.config | 29 ++++++++++ conf/predefined/phenocycler_base_20X.config | 29 ++++++++++ conf/predefined/phenocycler_base_40X.config | 29 ++++++++++ conf/predefined/visium_hd_stardist.config | 21 +++++++ conf/predefined/xenium_baysor.config | 45 +++++++++++++++ conf/predefined/xenium_baysor_prior.config | 46 +++++++++++++++ .../xenium_baysor_prior_small_cells.config | 46 +++++++++++++++ conf/predefined/xenium_cellpose.config | 27 +++++++++ conf/predefined/xenium_cellpose_baysor.config | 56 ++++++++++++++++++ conf/predefined/xenium_proseg.config | 21 +++++++ docs/usage.md | 8 ++- nextflow.config | 21 +++++++ nextflow_schema.json | 2 +- 24 files changed, 740 insertions(+), 2 deletions(-) create mode 100644 conf/predefined/cosmx_baysor.config create mode 100644 conf/predefined/cosmx_cellpose.config create mode 100644 conf/predefined/cosmx_cellpose_baysor.config create mode 100644 conf/predefined/cosmx_proseg.config create mode 100644 conf/predefined/hyperion_base.config create mode 100644 conf/predefined/macsima_base.config create mode 100644 conf/predefined/merscope_baysor_cellpose.config create mode 100644 conf/predefined/merscope_baysor_vizgen.config create mode 100644 conf/predefined/merscope_cellpose.config create mode 100644 conf/predefined/merscope_proseg.config create mode 100644 conf/predefined/phenocycler_base_10X.config create mode 100644 conf/predefined/phenocycler_base_20X.config create mode 100644 conf/predefined/phenocycler_base_40X.config create mode 100644 conf/predefined/visium_hd_stardist.config create mode 100644 conf/predefined/xenium_baysor.config create mode 100644 conf/predefined/xenium_baysor_prior.config create mode 100644 conf/predefined/xenium_baysor_prior_small_cells.config create mode 100644 conf/predefined/xenium_cellpose.config create mode 100644 conf/predefined/xenium_cellpose_baysor.config create mode 100644 conf/predefined/xenium_proseg.config diff --git a/.gitignore b/.gitignore index d75d93b..1fb6500 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ sandbox samplesheets lint_* .nf-test* +conf/predefined/convert* diff --git a/conf/predefined/cosmx_baysor.config b/conf/predefined/cosmx_baysor.config new file mode 100644 index 0000000..1ff1a64 --- /dev/null +++ b/conf/predefined/cosmx_baysor.config @@ -0,0 +1,45 @@ +params { + read = [ + technology: 'cosmx' + ] + patchify = [ + patch_width_microns: 8000, + patch_overlap_microns: 150, + ] + segmentation = [ + baysor: [ + min_area: 2000, + config: [ + data: [ + force_2d: true, + min_molecules_per_cell: 10, + x: 'x', + y: 'y', + z: 'z', + gene: 'target', + min_molecules_per_gene: 0, + min_molecules_per_segment: 3, + confidence_nn_id: 6, + ], + segmentation: [ + scale: 6.25, + scale_std: '25%', + prior_segmentation_confidence: 0, + estimate_scale_from_centers: false, + n_clusters: 4, + iters: 500, + n_cells_init: 0, + nuclei_genes: '', + cyto_genes: '', + ], + ], + ] + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4 + ] +} diff --git a/conf/predefined/cosmx_cellpose.config b/conf/predefined/cosmx_cellpose.config new file mode 100644 index 0000000..3cd7e7d --- /dev/null +++ b/conf/predefined/cosmx_cellpose.config @@ -0,0 +1,27 @@ +params { + read = [ + technology: 'cosmx' + ] + patchify = [ + patch_width_pixel: 6000, + patch_overlap_pixel: 150, + ] + segmentation = [ + cellpose: [ + diameter: 60, + channels: [ + 'DNA' + ], + flow_threshold: 2, + cellprob_threshold: -6, + min_area: 2000, + ] + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4 + ] +} diff --git a/conf/predefined/cosmx_cellpose_baysor.config b/conf/predefined/cosmx_cellpose_baysor.config new file mode 100644 index 0000000..9506b45 --- /dev/null +++ b/conf/predefined/cosmx_cellpose_baysor.config @@ -0,0 +1,56 @@ +params { + read = [ + technology: 'cosmx' + ] + patchify = [ + patch_width_pixel: 6000, + patch_overlap_pixel: 150, + patch_width_microns: 8000, + patch_overlap_microns: 150, + ] + segmentation = [ + cellpose: [ + diameter: 60, + channels: [ + 'DNA' + ], + flow_threshold: 2, + cellprob_threshold: -6, + min_area: 2000, + ], + baysor: [ + min_area: 2000, + config: [ + data: [ + force_2d: true, + min_molecules_per_cell: 10, + x: 'x', + y: 'y', + z: 'z', + gene: 'target', + min_molecules_per_gene: 0, + min_molecules_per_segment: 3, + confidence_nn_id: 6, + ], + segmentation: [ + scale: 6.25, + scale_std: '25%', + prior_segmentation_confidence: 1, + estimate_scale_from_centers: false, + n_clusters: 4, + iters: 500, + n_cells_init: 0, + nuclei_genes: '', + cyto_genes: '', + ], + ], + ], + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4 + ] +} diff --git a/conf/predefined/cosmx_proseg.config b/conf/predefined/cosmx_proseg.config new file mode 100644 index 0000000..313bc21 --- /dev/null +++ b/conf/predefined/cosmx_proseg.config @@ -0,0 +1,21 @@ +params { + read = [ + technology: 'cosmx' + ] + patchify = [ + patch_width_microns: -1, + patch_overlap_microns: 0, + ] + segmentation = [ + proseg: [ + prior_shapes_key: 'auto' + ] + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4 + ] +} diff --git a/conf/predefined/hyperion_base.config b/conf/predefined/hyperion_base.config new file mode 100644 index 0000000..3a24534 --- /dev/null +++ b/conf/predefined/hyperion_base.config @@ -0,0 +1,29 @@ +params { + read = [ + technology: 'hyperion' + ] + patchify = [ + patch_width_pixel: 3000, + patch_overlap_pixel: 40, + ] + segmentation = [ + cellpose: [ + diameter: 8, + channels: [ + 'DNA1' + ], + flow_threshold: 2, + cellprob_threshold: -6, + min_area: 16, + ] + ] + aggregate = [ + aggregate_channels: true, + min_intensity_ratio: 0.1, + expand_radius_ratio: 0.1, + ] + explorer = [ + ram_threshold_gb: 4, + pixel_size: 1, + ] +} diff --git a/conf/predefined/macsima_base.config b/conf/predefined/macsima_base.config new file mode 100644 index 0000000..33dcb88 --- /dev/null +++ b/conf/predefined/macsima_base.config @@ -0,0 +1,29 @@ +params { + read = [ + technology: 'macsima' + ] + patchify = [ + patch_width_pixel: 3000, + patch_overlap_pixel: 40, + ] + segmentation = [ + cellpose: [ + diameter: 35, + channels: [ + 'DAPI' + ], + flow_threshold: 2, + cellprob_threshold: -6, + min_area: 400, + ] + ] + aggregate = [ + aggregate_channels: true, + min_intensity_ratio: 0.1, + expand_radius_ratio: 0.1, + ] + explorer = [ + ram_threshold_gb: 4, + pixel_size: 0.17, + ] +} diff --git a/conf/predefined/merscope_baysor_cellpose.config b/conf/predefined/merscope_baysor_cellpose.config new file mode 100644 index 0000000..a9f80c2 --- /dev/null +++ b/conf/predefined/merscope_baysor_cellpose.config @@ -0,0 +1,57 @@ +params { + read = [ + technology: 'merscope' + ] + patchify = [ + patch_width_pixel: 6000, + patch_overlap_pixel: 150, + patch_width_microns: 1000, + patch_overlap_microns: 20, + ] + segmentation = [ + cellpose: [ + diameter: 60, + channels: [ + 'DAPI' + ], + flow_threshold: 2, + cellprob_threshold: -6, + min_area: 2000, + ], + baysor: [ + min_area: 20, + config: [ + data: [ + force_2d: true, + min_molecules_per_cell: 10, + x: 'x', + y: 'y', + z: 'z', + gene: 'gene', + min_molecules_per_gene: 0, + min_molecules_per_segment: 3, + confidence_nn_id: 6, + ], + segmentation: [ + scale: 6.25, + scale_std: '25%', + prior_segmentation_confidence: 1, + estimate_scale_from_centers: false, + n_clusters: 4, + iters: 500, + n_cells_init: 0, + nuclei_genes: '', + cyto_genes: '', + ], + ], + ], + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4, + pixel_size: 0.108, + ] +} diff --git a/conf/predefined/merscope_baysor_vizgen.config b/conf/predefined/merscope_baysor_vizgen.config new file mode 100644 index 0000000..3b2349c --- /dev/null +++ b/conf/predefined/merscope_baysor_vizgen.config @@ -0,0 +1,47 @@ +params { + read = [ + technology: 'merscope' + ] + patchify = [ + patch_width_pixel: 6000, + patch_overlap_pixel: 150, + ] + segmentation = [ + baysor: [ + min_area: 20, + prior_shapes_key: 'auto', + config: [ + data: [ + force_2d: true, + min_molecules_per_cell: 10, + x: 'x', + y: 'y', + z: 'z', + gene: 'gene', + min_molecules_per_gene: 0, + min_molecules_per_segment: 3, + confidence_nn_id: 6, + ], + segmentation: [ + scale: 6.25, + scale_std: '25%', + prior_segmentation_confidence: 0.75, + estimate_scale_from_centers: false, + n_clusters: 4, + iters: 500, + n_cells_init: 0, + nuclei_genes: '', + cyto_genes: '', + ], + ], + ] + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4, + pixel_size: 0.108, + ] +} diff --git a/conf/predefined/merscope_cellpose.config b/conf/predefined/merscope_cellpose.config new file mode 100644 index 0000000..fed588e --- /dev/null +++ b/conf/predefined/merscope_cellpose.config @@ -0,0 +1,28 @@ +params { + read = [ + technology: 'merscope' + ] + patchify = [ + patch_width_pixel: 6000, + patch_overlap_pixel: 150, + ] + segmentation = [ + cellpose: [ + diameter: 60, + channels: [ + 'DAPI' + ], + flow_threshold: 2, + cellprob_threshold: -6, + min_area: 2000, + ] + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4, + pixel_size: 0.108, + ] +} diff --git a/conf/predefined/merscope_proseg.config b/conf/predefined/merscope_proseg.config new file mode 100644 index 0000000..776f13d --- /dev/null +++ b/conf/predefined/merscope_proseg.config @@ -0,0 +1,22 @@ +params { + read = [ + technology: 'merscope' + ] + patchify = [ + patch_width_microns: -1, + patch_overlap_microns: 0, + ] + segmentation = [ + proseg: [ + prior_shapes_key: 'auto' + ] + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4, + pixel_size: 0.108, + ] +} diff --git a/conf/predefined/phenocycler_base_10X.config b/conf/predefined/phenocycler_base_10X.config new file mode 100644 index 0000000..d04af62 --- /dev/null +++ b/conf/predefined/phenocycler_base_10X.config @@ -0,0 +1,29 @@ +params { + read = [ + technology: 'phenocycler' + ] + patchify = [ + patch_width_pixel: 3000, + patch_overlap_pixel: 40, + ] + segmentation = [ + cellpose: [ + diameter: 8, + channels: [ + 'DAPI' + ], + flow_threshold: 2, + cellprob_threshold: -6, + min_area: 16, + ] + ] + aggregate = [ + aggregate_channels: true, + min_intensity_ratio: 0.1, + expand_radius_ratio: 0.1, + ] + explorer = [ + ram_threshold_gb: 4, + pixel_size: 1, + ] +} diff --git a/conf/predefined/phenocycler_base_20X.config b/conf/predefined/phenocycler_base_20X.config new file mode 100644 index 0000000..b2842e3 --- /dev/null +++ b/conf/predefined/phenocycler_base_20X.config @@ -0,0 +1,29 @@ +params { + read = [ + technology: 'phenocycler' + ] + patchify = [ + patch_width_pixel: 3000, + patch_overlap_pixel: 40, + ] + segmentation = [ + cellpose: [ + diameter: 12, + channels: [ + 'DAPI' + ], + flow_threshold: 2, + cellprob_threshold: -6, + min_area: 38, + ] + ] + aggregate = [ + aggregate_channels: true, + min_intensity_ratio: 0.1, + expand_radius_ratio: 0.1, + ] + explorer = [ + ram_threshold_gb: 4, + pixel_size: 0.5, + ] +} diff --git a/conf/predefined/phenocycler_base_40X.config b/conf/predefined/phenocycler_base_40X.config new file mode 100644 index 0000000..ca19a06 --- /dev/null +++ b/conf/predefined/phenocycler_base_40X.config @@ -0,0 +1,29 @@ +params { + read = [ + technology: 'phenocycler' + ] + patchify = [ + patch_width_pixel: 3000, + patch_overlap_pixel: 40, + ] + segmentation = [ + cellpose: [ + diameter: 24, + channels: [ + 'DAPI' + ], + flow_threshold: 2, + cellprob_threshold: -6, + min_area: 120, + ] + ] + aggregate = [ + aggregate_channels: true, + min_intensity_ratio: 0.1, + expand_radius_ratio: 0.1, + ] + explorer = [ + ram_threshold_gb: 4, + pixel_size: 0.25, + ] +} diff --git a/conf/predefined/visium_hd_stardist.config b/conf/predefined/visium_hd_stardist.config new file mode 100644 index 0000000..b963d15 --- /dev/null +++ b/conf/predefined/visium_hd_stardist.config @@ -0,0 +1,21 @@ +params { + read = [ + technology: 'visium_hd' + ] + patchify = [ + patch_width_pixel: 2000, + patch_overlap_pixel: 50, + ] + segmentation = [ + stardist: [ + min_area: 30 + ] + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4 + ] +} diff --git a/conf/predefined/xenium_baysor.config b/conf/predefined/xenium_baysor.config new file mode 100644 index 0000000..0dbff62 --- /dev/null +++ b/conf/predefined/xenium_baysor.config @@ -0,0 +1,45 @@ +params { + read = [ + technology: 'xenium' + ] + patchify = [ + patch_width_microns: 1000, + patch_overlap_microns: 20, + ] + segmentation = [ + baysor: [ + min_area: 20, + config: [ + data: [ + force_2d: true, + min_molecules_per_cell: 10, + x: 'x', + y: 'y', + z: 'z', + gene: 'feature_name', + min_molecules_per_gene: 0, + min_molecules_per_segment: 3, + confidence_nn_id: 6, + ], + segmentation: [ + scale: 6.25, + scale_std: '25%', + prior_segmentation_confidence: 0, + estimate_scale_from_centers: false, + n_clusters: 4, + iters: 500, + n_cells_init: 0, + nuclei_genes: '', + cyto_genes: '', + ], + ], + ] + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4 + ] +} diff --git a/conf/predefined/xenium_baysor_prior.config b/conf/predefined/xenium_baysor_prior.config new file mode 100644 index 0000000..ac989cd --- /dev/null +++ b/conf/predefined/xenium_baysor_prior.config @@ -0,0 +1,46 @@ +params { + read = [ + technology: 'xenium' + ] + patchify = [ + patch_width_microns: 1000, + patch_overlap_microns: 20, + ] + segmentation = [ + baysor: [ + min_area: 20, + prior_shapes_key: 'auto', + config: [ + data: [ + force_2d: true, + min_molecules_per_cell: 10, + x: 'x', + y: 'y', + z: 'z', + gene: 'feature_name', + min_molecules_per_gene: 0, + min_molecules_per_segment: 3, + confidence_nn_id: 6, + ], + segmentation: [ + scale: 6.25, + scale_std: '25%', + prior_segmentation_confidence: 0.8, + estimate_scale_from_centers: false, + n_clusters: 4, + iters: 500, + n_cells_init: 0, + nuclei_genes: '', + cyto_genes: '', + ], + ], + ] + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4 + ] +} diff --git a/conf/predefined/xenium_baysor_prior_small_cells.config b/conf/predefined/xenium_baysor_prior_small_cells.config new file mode 100644 index 0000000..52af923 --- /dev/null +++ b/conf/predefined/xenium_baysor_prior_small_cells.config @@ -0,0 +1,46 @@ +params { + read = [ + technology: 'xenium' + ] + patchify = [ + patch_width_microns: 1000, + patch_overlap_microns: 20, + ] + segmentation = [ + baysor: [ + min_area: 20, + prior_shapes_key: 'auto', + config: [ + data: [ + force_2d: true, + min_molecules_per_cell: 10, + x: 'x', + y: 'y', + z: 'z', + gene: 'feature_name', + min_molecules_per_gene: 0, + min_molecules_per_segment: 3, + confidence_nn_id: 6, + ], + segmentation: [ + scale: 4, + scale_std: '25%', + prior_segmentation_confidence: 0.8, + estimate_scale_from_centers: false, + n_clusters: 4, + iters: 500, + n_cells_init: 0, + nuclei_genes: '', + cyto_genes: '', + ], + ], + ] + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4 + ] +} diff --git a/conf/predefined/xenium_cellpose.config b/conf/predefined/xenium_cellpose.config new file mode 100644 index 0000000..9449777 --- /dev/null +++ b/conf/predefined/xenium_cellpose.config @@ -0,0 +1,27 @@ +params { + read = [ + technology: 'xenium' + ] + patchify = [ + patch_width_pixel: 6000, + patch_overlap_pixel: 150, + ] + segmentation = [ + cellpose: [ + diameter: 30, + channels: [ + 'DAPI' + ], + flow_threshold: 2, + cellprob_threshold: -6, + min_area: 400, + ] + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4 + ] +} diff --git a/conf/predefined/xenium_cellpose_baysor.config b/conf/predefined/xenium_cellpose_baysor.config new file mode 100644 index 0000000..42b53dd --- /dev/null +++ b/conf/predefined/xenium_cellpose_baysor.config @@ -0,0 +1,56 @@ +params { + read = [ + technology: 'xenium' + ] + patchify = [ + patch_width_pixel: 6000, + patch_overlap_pixel: 150, + patch_width_microns: 1000, + patch_overlap_microns: 20, + ] + segmentation = [ + cellpose: [ + diameter: 30, + channels: [ + 'DAPI' + ], + flow_threshold: 2, + cellprob_threshold: -6, + min_area: 400, + ], + baysor: [ + min_area: 20, + config: [ + data: [ + force_2d: true, + min_molecules_per_cell: 10, + x: 'x', + y: 'y', + z: 'z', + gene: 'feature_name', + min_molecules_per_gene: 0, + min_molecules_per_segment: 3, + confidence_nn_id: 6, + ], + segmentation: [ + scale: 6.25, + scale_std: '25%', + prior_segmentation_confidence: 1, + estimate_scale_from_centers: false, + n_clusters: 4, + iters: 500, + n_cells_init: 0, + nuclei_genes: '', + cyto_genes: '', + ], + ], + ], + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4 + ] +} diff --git a/conf/predefined/xenium_proseg.config b/conf/predefined/xenium_proseg.config new file mode 100644 index 0000000..e5729e0 --- /dev/null +++ b/conf/predefined/xenium_proseg.config @@ -0,0 +1,21 @@ +params { + read = [ + technology: 'xenium' + ] + patchify = [ + patch_width_microns: -1, + patch_overlap_microns: 0, + ] + segmentation = [ + proseg: [ + prior_shapes_key: 'auto' + ] + ] + aggregate = [ + aggregate_channels: true, + min_transcripts: 10, + ] + explorer = [ + ram_threshold_gb: 4 + ] +} diff --git a/docs/usage.md b/docs/usage.md index 91186a6..9c6198b 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -78,7 +78,11 @@ This samplesheet was made for [this public sample](https://www.10xgenomics.com/d ## Sopa parameters -You'll also need to choose some Sopa parameters that you'll provide to Nextflow via the `-params-file` option. You can find existing Sopa parameter files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument. +You'll also need to choose some Sopa parameters. + +The first option (recommended) is to use an existing `-profile` (see the existing profiles further). + +The second option is to provide the parameters to Nextflow via the `-params-file` option. You can find existing Sopa parameter files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument. For instance, if you have Xenium data and want to run Sopa with `proseg`, you can use: @@ -199,6 +203,8 @@ If `-profile` is not specified, the pipeline will run locally and expect all sof - A generic configuration profile to enable [Wave](https://seqera.io/wave/) containers. Use together with one of the above (requires Nextflow ` 24.03.0-edge` or later). - `conda` - A generic configuration profile to be used with [Conda](https://conda.io/docs/). Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker, Singularity, Podman, Shifter, Charliecloud, or Apptainer. +- `xenium_proseg` + - A profile with Sopa parameters to run Proseg on Xenium data ### `-resume` diff --git a/nextflow.config b/nextflow.config index 8d1e552..2050bd0 100644 --- a/nextflow.config +++ b/nextflow.config @@ -169,6 +169,27 @@ profiles { test_comseg { includeConfig 'conf/test_comseg.config' } test_cellpose { includeConfig 'conf/test_cellpose.config' } test_full { includeConfig 'conf/test_full.config' } + + xenium_baysor { includeConfig 'conf/predefined/xenium_baysor.config' } + xenium_baysor_prior_small_cells { includeConfig 'conf/predefined/xenium_baysor_prior_small_cells.config' } + xenium_baysor_prior { includeConfig 'conf/predefined/xenium_baysor_prior.config' } + xenium_cellpose_baysor { includeConfig 'conf/predefined/xenium_cellpose_baysor.config' } + xenium_proseg { includeConfig 'conf/predefined/xenium_proseg.config' } + xenium_cellpose { includeConfig 'conf/predefined/xenium_cellpose.config' } + cosmx_cellpose { includeConfig 'conf/predefined/cosmx_cellpose.config' } + cosmx_proseg { includeConfig 'conf/predefined/cosmx_proseg.config' } + cosmx_baysor { includeConfig 'conf/predefined/cosmx_baysor.config' } + cosmx_cellpose_baysor { includeConfig 'conf/predefined/cosmx_cellpose_baysor.config' } + merscope_baysor_cellpose { includeConfig 'conf/predefined/merscope_baysor_cellpose.config' } + merscope_cellpose { includeConfig 'conf/predefined/merscope_cellpose.config' } + merscope_baysor_vizgen { includeConfig 'conf/predefined/merscope_baysor_vizgen.config' } + merscope_proseg { includeConfig 'conf/predefined/merscope_proseg.config' } + visium_hd_stardist { includeConfig 'conf/predefined/visium_hd_stardist.config' } + hyperion_base { includeConfig 'conf/predefined/hyperion_base.config' } + macsima_base { includeConfig 'conf/predefined/macsima_base.config' } + phenocycler_base_40X { includeConfig 'conf/predefined/phenocycler_base_40X.config' } + phenocycler_base_10X { includeConfig 'conf/predefined/phenocycler_base_10X.config' } + phenocycler_base_20X { includeConfig 'conf/predefined/phenocycler_base_20X.config' } } // Load nf-core custom profiles from different institutions diff --git a/nextflow_schema.json b/nextflow_schema.json index 8ca653b..735bd3a 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -39,7 +39,7 @@ } }, "sopa_config": { - "title": "Sopa config (or params file) - we recommend providing an existing `-params-file` as detailed in the usage section", + "title": "Sopa config - can be provided via a technology-specific `profile` or `-params-file`, as detailed in the usage section", "type": "object", "fa_icon": "fas fa-rocket", "description": "Parameters related to Sopa", From cde0fc61eb4ff46146c49a8080267fa1ecf529b3 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 5 Nov 2025 18:15:47 +0100 Subject: [PATCH 195/227] add conversion scripts and detail the profiles in usage.md --- .gitignore | 1 - conf/predefined/convert.nf | 23 ++++++++++++++++++++ conf/predefined/convert.sh | 14 ++++++++++++ conf/predefined/convert_list.sh | 10 +++++++++ docs/usage.md | 38 +++++++++++++++++++++++++++++++++ nextflow_schema.json | 2 +- 6 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 conf/predefined/convert.nf create mode 100644 conf/predefined/convert.sh create mode 100644 conf/predefined/convert_list.sh diff --git a/.gitignore b/.gitignore index 1fb6500..d75d93b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,3 @@ sandbox samplesheets lint_* .nf-test* -conf/predefined/convert* diff --git a/conf/predefined/convert.nf b/conf/predefined/convert.nf new file mode 100644 index 0000000..afe2253 --- /dev/null +++ b/conf/predefined/convert.nf @@ -0,0 +1,23 @@ +def convert(v) { + if (v instanceof Map) { + return '[\n' + v.collect { k, val -> "${k}: ${convert(val)}" }.join(', ') + '\n]' + } + if (v instanceof List) { + return '[\n' + v.collect { convert(it) }.join(', ') + '\n]' + } + if (v instanceof String) { + return "'${v.replace("'", "\\'")}'" + } + if (v == null) { + return 'null' + } + return v.toString() +} + +workflow { + def output = params.output + + params.remove('output') + + new File(output).text = "params {\n " + params.collect { k, v -> "${k} = ${convert(v)}" }.join('\n ') + "\n}\n" +} diff --git a/conf/predefined/convert.sh b/conf/predefined/convert.sh new file mode 100644 index 0000000..54490d8 --- /dev/null +++ b/conf/predefined/convert.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# convert all yaml parameter files in the sopa workflow config directory to nextflow config files +# you have to update the path below to point to your local sopa workflow config directory + +find /Users/quentinblampey/dev/sopa/workflow/config -mindepth 2 -maxdepth 2 -type f -name '*.yaml' | while read -r file; do + parent_dir=$(basename "$(dirname "$file")") + filename=$(basename "$file") + name_no_suffix="${filename%.*}" + output_file="${parent_dir}_${name_no_suffix}.config" + + nextflow run convert.nf -params-file "$file" --output "$output_file" + echo "$output_file generated." +done diff --git a/conf/predefined/convert_list.sh b/conf/predefined/convert_list.sh new file mode 100644 index 0000000..f2caae9 --- /dev/null +++ b/conf/predefined/convert_list.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# list all the predefined config files, to be added to the nextflow.config profiles section + +find . -type f -name '*.config' | while read -r file; do + filename=$(basename "$file") + name_no_suffix="${filename%.*}" + + echo " $name_no_suffix { includeConfig 'conf/predefined/$name_no_suffix.config' }" +done diff --git a/docs/usage.md b/docs/usage.md index 9c6198b..b27fe5a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -205,6 +205,44 @@ If `-profile` is not specified, the pipeline will run locally and expect all sof - A generic configuration profile to be used with [Conda](https://conda.io/docs/). Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker, Singularity, Podman, Shifter, Charliecloud, or Apptainer. - `xenium_proseg` - A profile with Sopa parameters to run Proseg on Xenium data +- `xenium_baysor` + - A profile with Sopa parameters to run Baysor on Xenium data +- `xenium_baysor_prior_small_cells` + - Same as above, but with a smaller Baysor scale for the cell diameter +- `xenium_baysor_prior` + - A profile with Sopa parameters to run Baysor on Xenium data with the 10X Genomics segmentation as a prior +- `xenium_cellpose_baysor` + - A profile with Sopa parameters to run Cellpose as a prior for Baysor on Xenium data +- `xenium_cellpose` + - A profile with Sopa parameters to run Cellpose on Xenium data +- `merscope_baysor_cellpose` + - A profile with Sopa parameters to run Cellpose as a prior for Baysor on MERSCOPE data +- `merscope_baysor_vizgen` + - A profile with Sopa parameters to run Baysor on MERSCOPE data with the Vizgen segmentation as a prior +- `merscope_proseg` + - A profile with Sopa parameters to run Proseg on MERSCOPE data +- `merscope_cellpose` + - A profile with Sopa parameters to run Cellpose on MERSCOPE data +- `cosmx_cellpose` + - A profile with Sopa parameters to run Cellpose on CosMx data +- `cosmx_proseg` + - A profile with Sopa parameters to run Proseg on CosMx data +- `cosmx_baysor` + - A profile with Sopa parameters to run Baysor on Xenium data +- `cosmx_cellpose_baysor` + - A profile with Sopa parameters to run Cellpose as a prior for Baysor on CosMx data +- `visium_hd_stardist` + - A profile with Sopa parameters to run Stardist on Visium HD data +- `phenocycler_base_10X` + - A profile with Sopa parameters to run Cellpose on Phenocycler data at 10X resolution +- `phenocycler_base_20X` + - A profile with Sopa parameters to run Cellpose on Phenocycler data at 20X resolution +- `phenocycler_base_40X` + - A profile with Sopa parameters to run Cellpose on Phenocycler data at 40X resolution +- `hyperion_base` + - A profile with Sopa parameters to run Cellpose on Hyperion data +- `macsima_base` + - A profile with Sopa parameters to run Cellpose on MACSima data ### `-resume` diff --git a/nextflow_schema.json b/nextflow_schema.json index 735bd3a..1cc7595 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -39,7 +39,7 @@ } }, "sopa_config": { - "title": "Sopa config - can be provided via a technology-specific `profile` or `-params-file`, as detailed in the usage section", + "title": "The Sopa config, provided via a `-profile` or `-params-file` (see the usage section)", "type": "object", "fa_icon": "fas fa-rocket", "description": "Parameters related to Sopa", From 047fb5f9d69c1dae656d32e9382bc2c6d399f405 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 10 Nov 2025 17:58:10 +0100 Subject: [PATCH 196/227] add contribute instrcutions to sync the sopa configs + adding small LICENSE --- .github/CONTRIBUTING.md | 19 +++++++++++++++++++ conf/predefined/convert.nf | 2 ++ conf/predefined/convert.sh | 13 ++++++++++--- conf/predefined/convert_list.sh | 4 +++- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 00bbbcf..5e513ab 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -59,6 +59,25 @@ These tests are run both with the latest available version of `Nextflow` and als - Fix the bug, and bump version (X.Y.Z+1). - Open a pull-request from `patch` to `main`/`master` with the changes. +## Updating the Sopa parameters profiles + +Some Sopa parameters profiles are stored in the [Python Sopa repository](https://github.com/gustaveroussy/sopa). They have to be synchronized with the profiles in `conf/predefined`. +To do that, we can convert each config from `gustavroussy/sopa` to a nextflow profile as follows: + +```sh +# clone the python repo wherever you want +git clone https://github.com/gustaveroussy/sopa.git + +# now, inside the nf-core/sopa repo: +cd conf/predefined + +# set SOPA_DIR depending on where you cloned gustaveroussy/sopa.git +SOPA_DIR=/path/to/gustaveroussy/sopa sh convert.sh +sh convert_list.sh # showing all profile imports, to be added to nextflow.config +``` + +Submit only the non-toy configs, and run file formatting before pushing the changes (if any). + ## Getting help For further information/help, please consult the [nf-core/sopa documentation](https://nf-co.re/sopa/usage) and don't hesitate to get in touch on the nf-core Slack [#sopa](https://nfcore.slack.com/channels/sopa) channel ([join our Slack here](https://nf-co.re/join/slack)). diff --git a/conf/predefined/convert.nf b/conf/predefined/convert.nf index afe2253..1c42d7c 100644 --- a/conf/predefined/convert.nf +++ b/conf/predefined/convert.nf @@ -1,3 +1,5 @@ +// Copyright (c) The nf-core/sopa team + def convert(v) { if (v instanceof Map) { return '[\n' + v.collect { k, val -> "${k}: ${convert(val)}" }.join(', ') + '\n]' diff --git a/conf/predefined/convert.sh b/conf/predefined/convert.sh index 54490d8..3709a4b 100644 --- a/conf/predefined/convert.sh +++ b/conf/predefined/convert.sh @@ -1,9 +1,16 @@ #!/bin/bash -# convert all yaml parameter files in the sopa workflow config directory to nextflow config files -# you have to update the path below to point to your local sopa workflow config directory +# Copyright (c) The nf-core/sopa team +# +# Convert all YAML config files in subdirectories to Nextflow config files +# Needs to set the SOPA_DIR environment variable to the repository root -find /Users/quentinblampey/dev/sopa/workflow/config -mindepth 2 -maxdepth 2 -type f -name '*.yaml' | while read -r file; do +if [ -z "${SOPA_DIR:-}" ]; then + echo "Error: SOPA_DIR environment variable is not set. Please clone https://github.com/gustaveroussy/sopa.git and set SOPA_DIR to the repository root." >&2 + exit 1 +fi + +find "$SOPA_DIR/workflow/config" -mindepth 2 -maxdepth 2 -type f -name '*.yaml' | while read -r file; do parent_dir=$(basename "$(dirname "$file")") filename=$(basename "$file") name_no_suffix="${filename%.*}" diff --git a/conf/predefined/convert_list.sh b/conf/predefined/convert_list.sh index f2caae9..4fbc4d9 100644 --- a/conf/predefined/convert_list.sh +++ b/conf/predefined/convert_list.sh @@ -1,6 +1,8 @@ #!/bin/bash -# list all the predefined config files, to be added to the nextflow.config profiles section +# Copyright (c) The nf-core/sopa team +# +# List all the predefined config files, to be added to the nextflow.config profiles section find . -type f -name '*.config' | while read -r file; do filename=$(basename "$file") From 26753744bcb4a158199fdbbf85a3e661bc470b4d Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 12 Nov 2025 08:57:04 +0100 Subject: [PATCH 197/227] remove params-file details + move profiles to the right docs section --- docs/usage.md | 95 ++++++++++++++++++++------------------------ nextflow_schema.json | 2 +- 2 files changed, 43 insertions(+), 54 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index b27fe5a..543d9d3 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -78,20 +78,48 @@ This samplesheet was made for [this public sample](https://www.10xgenomics.com/d ## Sopa parameters -You'll also need to choose some Sopa parameters. +You'll also need to choose some Sopa parameters to decide which reader/segmentation tool to use. To do that, provide an existing `-profile` containing all the dedicated Sopa parameters, depending on your technology: -The first option (recommended) is to use an existing `-profile` (see the existing profiles further). - -The second option is to provide the parameters to Nextflow via the `-params-file` option. You can find existing Sopa parameter files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument. - -For instance, if you have Xenium data and want to run Sopa with `proseg`, you can use: - -``` --params-file https://raw.githubusercontent.com/gustaveroussy/sopa/refs/heads/main/workflow/config/xenium/proseg.yaml -``` - -> [!NOTE] -> This `-params-file` option is **not** specific to Sopa - you can list other Nextflow params inside it. In that case, make your own local params-file. +- `xenium_proseg` + - A profile with Sopa parameters to run Proseg on Xenium data +- `xenium_baysor` + - A profile with Sopa parameters to run Baysor on Xenium data +- `xenium_baysor_prior_small_cells` + - Same as above, but with a smaller Baysor scale for the cell diameter +- `xenium_baysor_prior` + - A profile with Sopa parameters to run Baysor on Xenium data with the 10X Genomics segmentation as a prior +- `xenium_cellpose_baysor` + - A profile with Sopa parameters to run Cellpose as a prior for Baysor on Xenium data +- `xenium_cellpose` + - A profile with Sopa parameters to run Cellpose on Xenium data +- `merscope_baysor_cellpose` + - A profile with Sopa parameters to run Cellpose as a prior for Baysor on MERSCOPE data +- `merscope_baysor_vizgen` + - A profile with Sopa parameters to run Baysor on MERSCOPE data with the Vizgen segmentation as a prior +- `merscope_proseg` + - A profile with Sopa parameters to run Proseg on MERSCOPE data +- `merscope_cellpose` + - A profile with Sopa parameters to run Cellpose on MERSCOPE data +- `cosmx_cellpose` + - A profile with Sopa parameters to run Cellpose on CosMx data +- `cosmx_proseg` + - A profile with Sopa parameters to run Proseg on CosMx data +- `cosmx_baysor` + - A profile with Sopa parameters to run Baysor on Xenium data +- `cosmx_cellpose_baysor` + - A profile with Sopa parameters to run Cellpose as a prior for Baysor on CosMx data +- `visium_hd_stardist` + - A profile with Sopa parameters to run Stardist on Visium HD data +- `phenocycler_base_10X` + - A profile with Sopa parameters to run Cellpose on Phenocycler data at 10X resolution +- `phenocycler_base_20X` + - A profile with Sopa parameters to run Cellpose on Phenocycler data at 20X resolution +- `phenocycler_base_40X` + - A profile with Sopa parameters to run Cellpose on Phenocycler data at 40X resolution +- `hyperion_base` + - A profile with Sopa parameters to run Cellpose on Hyperion data +- `macsima_base` + - A profile with Sopa parameters to run Cellpose on MACSima data ## Running the pipeline @@ -203,46 +231,7 @@ If `-profile` is not specified, the pipeline will run locally and expect all sof - A generic configuration profile to enable [Wave](https://seqera.io/wave/) containers. Use together with one of the above (requires Nextflow ` 24.03.0-edge` or later). - `conda` - A generic configuration profile to be used with [Conda](https://conda.io/docs/). Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker, Singularity, Podman, Shifter, Charliecloud, or Apptainer. -- `xenium_proseg` - - A profile with Sopa parameters to run Proseg on Xenium data -- `xenium_baysor` - - A profile with Sopa parameters to run Baysor on Xenium data -- `xenium_baysor_prior_small_cells` - - Same as above, but with a smaller Baysor scale for the cell diameter -- `xenium_baysor_prior` - - A profile with Sopa parameters to run Baysor on Xenium data with the 10X Genomics segmentation as a prior -- `xenium_cellpose_baysor` - - A profile with Sopa parameters to run Cellpose as a prior for Baysor on Xenium data -- `xenium_cellpose` - - A profile with Sopa parameters to run Cellpose on Xenium data -- `merscope_baysor_cellpose` - - A profile with Sopa parameters to run Cellpose as a prior for Baysor on MERSCOPE data -- `merscope_baysor_vizgen` - - A profile with Sopa parameters to run Baysor on MERSCOPE data with the Vizgen segmentation as a prior -- `merscope_proseg` - - A profile with Sopa parameters to run Proseg on MERSCOPE data -- `merscope_cellpose` - - A profile with Sopa parameters to run Cellpose on MERSCOPE data -- `cosmx_cellpose` - - A profile with Sopa parameters to run Cellpose on CosMx data -- `cosmx_proseg` - - A profile with Sopa parameters to run Proseg on CosMx data -- `cosmx_baysor` - - A profile with Sopa parameters to run Baysor on Xenium data -- `cosmx_cellpose_baysor` - - A profile with Sopa parameters to run Cellpose as a prior for Baysor on CosMx data -- `visium_hd_stardist` - - A profile with Sopa parameters to run Stardist on Visium HD data -- `phenocycler_base_10X` - - A profile with Sopa parameters to run Cellpose on Phenocycler data at 10X resolution -- `phenocycler_base_20X` - - A profile with Sopa parameters to run Cellpose on Phenocycler data at 20X resolution -- `phenocycler_base_40X` - - A profile with Sopa parameters to run Cellpose on Phenocycler data at 40X resolution -- `hyperion_base` - - A profile with Sopa parameters to run Cellpose on Hyperion data -- `macsima_base` - - A profile with Sopa parameters to run Cellpose on MACSima data +- Some Sopa-specific profiles are listed in the above "Sopa parameters" section. ### `-resume` diff --git a/nextflow_schema.json b/nextflow_schema.json index 1cc7595..841c10c 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -39,7 +39,7 @@ } }, "sopa_config": { - "title": "The Sopa config, provided via a `-profile` or `-params-file` (see the usage section)", + "title": "The Sopa config, provided via a `-profile` (see the usage section)", "type": "object", "fa_icon": "fas fa-rocket", "description": "Parameters related to Sopa", From 1cd3ec6d9cf468bf942a70c62c014615db1ed58d Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 14 Nov 2025 15:26:10 +0100 Subject: [PATCH 198/227] update to sopa==2.1.9 --- modules/local/aggregate/main.nf | 4 ++-- modules/local/explorer/main.nf | 4 ++-- modules/local/explorer_raw/main.nf | 4 ++-- modules/local/fluo_annotation/main.nf | 4 ++-- modules/local/make_image_patches/main.nf | 4 ++-- modules/local/make_transcript_patches/main.nf | 4 ++-- modules/local/patch_segmentation_baysor/main.nf | 4 ++-- modules/local/patch_segmentation_cellpose/main.nf | 4 ++-- modules/local/patch_segmentation_comseg/main.nf | 4 ++-- modules/local/patch_segmentation_proseg/main.nf | 4 ++-- modules/local/patch_segmentation_stardist/main.nf | 4 ++-- modules/local/report/main.nf | 4 ++-- modules/local/resolve_baysor/main.nf | 4 ++-- modules/local/resolve_cellpose/main.nf | 4 ++-- modules/local/resolve_comseg/main.nf | 4 ++-- modules/local/resolve_stardist/main.nf | 4 ++-- modules/local/scanpy_preprocess/main.nf | 4 ++-- modules/local/tangram_annotation/main.nf | 4 ++-- modules/local/tissue_segmentation/main.nf | 4 ++-- modules/local/to_spatialdata/main.nf | 4 ++-- tests/baysor.nf.test.snap | 6 +++--- tests/cellpose.nf.test.snap | 4 ++-- tests/default.nf.test.snap | 8 ++++---- 23 files changed, 49 insertions(+), 49 deletions(-) diff --git a/modules/local/aggregate/main.nf b/modules/local/aggregate/main.nf index d5ec577..2b5da49 100644 --- a/modules/local/aggregate/main.nf +++ b/modules/local/aggregate/main.nf @@ -3,8 +3,8 @@ process AGGREGATE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8' - : 'docker.io/quentinblampey/sopa:2.1.8'}" + ? 'docker://quentinblampey/sopa:2.1.9' + : 'docker.io/quentinblampey/sopa:2.1.9'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/explorer/main.nf b/modules/local/explorer/main.nf index 053c339..307da53 100644 --- a/modules/local/explorer/main.nf +++ b/modules/local/explorer/main.nf @@ -3,8 +3,8 @@ process EXPLORER { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8' - : 'docker.io/quentinblampey/sopa:2.1.8'}" + ? 'docker://quentinblampey/sopa:2.1.9' + : 'docker.io/quentinblampey/sopa:2.1.9'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/explorer_raw/main.nf b/modules/local/explorer_raw/main.nf index c20bcf4..a844ea6 100644 --- a/modules/local/explorer_raw/main.nf +++ b/modules/local/explorer_raw/main.nf @@ -5,8 +5,8 @@ process EXPLORER_RAW { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8' - : 'docker.io/quentinblampey/sopa:2.1.8'}" + ? 'docker://quentinblampey/sopa:2.1.9' + : 'docker.io/quentinblampey/sopa:2.1.9'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/fluo_annotation/main.nf b/modules/local/fluo_annotation/main.nf index 39d5d0a..3608926 100644 --- a/modules/local/fluo_annotation/main.nf +++ b/modules/local/fluo_annotation/main.nf @@ -3,8 +3,8 @@ process FLUO_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8' - : 'docker.io/quentinblampey/sopa:2.1.8'}" + ? 'docker://quentinblampey/sopa:2.1.9' + : 'docker.io/quentinblampey/sopa:2.1.9'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_image_patches/main.nf b/modules/local/make_image_patches/main.nf index 27d90e4..fdae2e0 100644 --- a/modules/local/make_image_patches/main.nf +++ b/modules/local/make_image_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_IMAGE_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8' - : 'docker.io/quentinblampey/sopa:2.1.8'}" + ? 'docker://quentinblampey/sopa:2.1.9' + : 'docker.io/quentinblampey/sopa:2.1.9'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_transcript_patches/main.nf b/modules/local/make_transcript_patches/main.nf index 9aed5d3..78c0d60 100644 --- a/modules/local/make_transcript_patches/main.nf +++ b/modules/local/make_transcript_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_TRANSCRIPT_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8' - : 'docker.io/quentinblampey/sopa:2.1.8'}" + ? 'docker://quentinblampey/sopa:2.1.9' + : 'docker.io/quentinblampey/sopa:2.1.9'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/patch_segmentation_baysor/main.nf b/modules/local/patch_segmentation_baysor/main.nf index b7bb250..ae529a9 100644 --- a/modules/local/patch_segmentation_baysor/main.nf +++ b/modules/local/patch_segmentation_baysor/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8-baysor' - : 'docker.io/quentinblampey/sopa:2.1.8-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.9-baysor' + : 'docker.io/quentinblampey/sopa:2.1.9-baysor'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_cellpose/main.nf b/modules/local/patch_segmentation_cellpose/main.nf index 6cb8f5d..55e4391 100644 --- a/modules/local/patch_segmentation_cellpose/main.nf +++ b/modules/local/patch_segmentation_cellpose/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.8-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.9-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.9-cellpose'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_comseg/main.nf b/modules/local/patch_segmentation_comseg/main.nf index 54aa867..48ce4be 100644 --- a/modules/local/patch_segmentation_comseg/main.nf +++ b/modules/local/patch_segmentation_comseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8-comseg' - : 'docker.io/quentinblampey/sopa:2.1.8-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.9-comseg' + : 'docker.io/quentinblampey/sopa:2.1.9-comseg'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_proseg/main.nf b/modules/local/patch_segmentation_proseg/main.nf index 7eb6c51..c3d13d4 100644 --- a/modules/local/patch_segmentation_proseg/main.nf +++ b/modules/local/patch_segmentation_proseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_PROSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8-proseg' - : 'docker.io/quentinblampey/sopa:2.1.8-proseg'}" + ? 'docker://quentinblampey/sopa:2.1.9-proseg' + : 'docker.io/quentinblampey/sopa:2.1.9-proseg'}" input: tuple val(meta), path(sdata_path), path(patches_file_transcripts), path(transcript_patches) diff --git a/modules/local/patch_segmentation_stardist/main.nf b/modules/local/patch_segmentation_stardist/main.nf index 755c97e..0761e07 100644 --- a/modules/local/patch_segmentation_stardist/main.nf +++ b/modules/local/patch_segmentation_stardist/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8-stardist' - : 'docker.io/quentinblampey/sopa:2.1.8-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.9-stardist' + : 'docker.io/quentinblampey/sopa:2.1.9-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/report/main.nf b/modules/local/report/main.nf index 36770e2..b68af19 100644 --- a/modules/local/report/main.nf +++ b/modules/local/report/main.nf @@ -3,8 +3,8 @@ process REPORT { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8' - : 'docker.io/quentinblampey/sopa:2.1.8'}" + ? 'docker://quentinblampey/sopa:2.1.9' + : 'docker.io/quentinblampey/sopa:2.1.9'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/resolve_baysor/main.nf b/modules/local/resolve_baysor/main.nf index 9e24a89..fb16778 100644 --- a/modules/local/resolve_baysor/main.nf +++ b/modules/local/resolve_baysor/main.nf @@ -3,8 +3,8 @@ process RESOLVE_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8-baysor' - : 'docker.io/quentinblampey/sopa:2.1.8-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.9-baysor' + : 'docker.io/quentinblampey/sopa:2.1.9-baysor'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_cellpose/main.nf b/modules/local/resolve_cellpose/main.nf index a14ff57..3af7531 100644 --- a/modules/local/resolve_cellpose/main.nf +++ b/modules/local/resolve_cellpose/main.nf @@ -3,8 +3,8 @@ process RESOLVE_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.8-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.9-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.9-cellpose'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_comseg/main.nf b/modules/local/resolve_comseg/main.nf index 9dcfaef..a4ddaeb 100644 --- a/modules/local/resolve_comseg/main.nf +++ b/modules/local/resolve_comseg/main.nf @@ -3,8 +3,8 @@ process RESOLVE_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8-comseg' - : 'docker.io/quentinblampey/sopa:2.1.8-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.9-comseg' + : 'docker.io/quentinblampey/sopa:2.1.9-comseg'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_stardist/main.nf b/modules/local/resolve_stardist/main.nf index f0243ed..1340847 100644 --- a/modules/local/resolve_stardist/main.nf +++ b/modules/local/resolve_stardist/main.nf @@ -3,8 +3,8 @@ process RESOLVE_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8-stardist' - : 'docker.io/quentinblampey/sopa:2.1.8-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.9-stardist' + : 'docker.io/quentinblampey/sopa:2.1.9-stardist'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/scanpy_preprocess/main.nf b/modules/local/scanpy_preprocess/main.nf index a76b604..bbb8c2b 100644 --- a/modules/local/scanpy_preprocess/main.nf +++ b/modules/local/scanpy_preprocess/main.nf @@ -3,8 +3,8 @@ process SCANPY_PREPROCESS { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8' - : 'docker.io/quentinblampey/sopa:2.1.8'}" + ? 'docker://quentinblampey/sopa:2.1.9' + : 'docker.io/quentinblampey/sopa:2.1.9'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tangram_annotation/main.nf b/modules/local/tangram_annotation/main.nf index a1dae87..f9a7e80 100644 --- a/modules/local/tangram_annotation/main.nf +++ b/modules/local/tangram_annotation/main.nf @@ -3,8 +3,8 @@ process TANGRAM_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8-tangram' - : 'docker.io/quentinblampey/sopa:2.1.8-tangram'}" + ? 'docker://quentinblampey/sopa:2.1.9-tangram' + : 'docker.io/quentinblampey/sopa:2.1.9-tangram'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tissue_segmentation/main.nf b/modules/local/tissue_segmentation/main.nf index 38e34a6..046dc44 100644 --- a/modules/local/tissue_segmentation/main.nf +++ b/modules/local/tissue_segmentation/main.nf @@ -3,8 +3,8 @@ process TISSUE_SEGMENTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8' - : 'docker.io/quentinblampey/sopa:2.1.8'}" + ? 'docker://quentinblampey/sopa:2.1.9' + : 'docker.io/quentinblampey/sopa:2.1.9'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/to_spatialdata/main.nf b/modules/local/to_spatialdata/main.nf index 9de77a1..9e94dd8 100644 --- a/modules/local/to_spatialdata/main.nf +++ b/modules/local/to_spatialdata/main.nf @@ -5,8 +5,8 @@ process TO_SPATIALDATA { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.8' - : 'docker.io/quentinblampey/sopa:2.1.8'}" + ? 'docker://quentinblampey/sopa:2.1.9' + : 'docker.io/quentinblampey/sopa:2.1.9'}" input: tuple val(meta), path(data_dir), path(fullres_image_file) diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index 7c58ec0..f31eb07 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -4,15 +4,15 @@ 9, { "RESOLVE_BAYSOR": { - "sopa": "2.1.8", + "sopa": "2.1.9", "baysor": "0.7.1" }, "TANGRAM_ANNOTATION": { - "sopa": "2.1.8", + "sopa": "2.1.9", "tangram": "1.0.4" }, "TO_SPATIALDATA": { - "sopa": "2.1.8", + "sopa": "2.1.9", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 9a92b79..88ef287 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -4,11 +4,11 @@ 8, { "RESOLVE_CELLPOSE": { - "sopa": "2.1.8", + "sopa": "2.1.9", "cellpose": "4.0.7" }, "TO_SPATIALDATA": { - "sopa": "2.1.8", + "sopa": "2.1.9", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index e8f990b..04851b9 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -3,18 +3,18 @@ "content": [ { "FLUO_ANNOTATION": { - "sopa": "2.1.8" + "sopa": "2.1.9" }, "PATCH_SEGMENTATION_PROSEG": { - "sopa": "2.1.8", + "sopa": "2.1.9", "proseg": "3.0.10" }, "SCANPY_PREPROCESS": { - "sopa": "2.1.8", + "sopa": "2.1.9", "scanpy": "1.11.5" }, "TO_SPATIALDATA": { - "sopa": "2.1.8", + "sopa": "2.1.9", "spatialdata": "0.5.0", "spatialdata_io": "0.3.0" }, From 72247508b824f73dc6a72b7db3dbe41bc00ec931 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 14 Nov 2025 16:00:49 +0100 Subject: [PATCH 199/227] update snapshot --- nextflow_schema.json | 4 +- tests/.nftignore | 2 + tests/baysor.nf.test.snap | 39 ++-------- tests/cellpose.nf.test.snap | 35 ++------- tests/default.nf.test.snap | 143 ++---------------------------------- 5 files changed, 20 insertions(+), 203 deletions(-) diff --git a/nextflow_schema.json b/nextflow_schema.json index 841c10c..2c7361d 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -39,10 +39,10 @@ } }, "sopa_config": { - "title": "The Sopa config, provided via a `-profile` (see the usage section)", + "title": "The Sopa config", "type": "object", "fa_icon": "fas fa-rocket", - "description": "Parameters related to Sopa", + "description": "Parameters related to Sopa, provided via a `-profile` (see the [usage](../usage) section).", "required": ["read", "segmentation"], "properties": { "read": { diff --git a/tests/.nftignore b/tests/.nftignore index 7d01b42..51015bb 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -13,6 +13,8 @@ pipeline_info/*.{html,json,txt,yml} **/1 **/2 **/3 +**/uns +**/uns/** **/zmetadata **/.sopa_cache **/.sopa_cache/** diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index f31eb07..45d5e34 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -14,7 +14,7 @@ "TO_SPATIALDATA": { "sopa": "2.1.9", "spatialdata": "0.5.0", - "spatialdata_io": "0.3.0" + "spatialdata_io": "0.5.1" }, "Workflow": { "nf-core/sopa": "v1.0.0" @@ -289,39 +289,10 @@ "sample_name.zarr/tables/table/obsp", "sample_name.zarr/tables/table/obsp/.zattrs", "sample_name.zarr/tables/table/obsp/.zgroup", - "sample_name.zarr/tables/table/uns", - "sample_name.zarr/tables/table/uns/.zattrs", - "sample_name.zarr/tables/table/uns/.zgroup", - "sample_name.zarr/tables/table/uns/sopa_attrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/.zattrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/.zgroup", - "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types", - "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/.zarray", - "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/.zattrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/0", - "sample_name.zarr/tables/table/uns/sopa_attrs/intensities", - "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", - "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/0", - "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts", - "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", - "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/0", - "sample_name.zarr/tables/table/uns/spatialdata_attrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zattrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zgroup", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/0", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/0", + "sample_name.zarr/tables/table/table/raw", + "sample_name.zarr/tables/table/table/raw/.zarray", + "sample_name.zarr/tables/table/table/raw/.zattrs", + "sample_name.zarr/tables/table/table/raw/0", "sample_name.zarr/tables/table/var", "sample_name.zarr/tables/table/var/.zattrs", "sample_name.zarr/tables/table/var/.zgroup", diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 88ef287..17b09d1 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -10,7 +10,7 @@ "TO_SPATIALDATA": { "sopa": "2.1.9", "spatialdata": "0.5.0", - "spatialdata_io": "0.3.0" + "spatialdata_io": "0.5.1" }, "Workflow": { "nf-core/sopa": "v1.0.0" @@ -218,35 +218,10 @@ "sample_name.zarr/tables/table/obsp", "sample_name.zarr/tables/table/obsp/.zattrs", "sample_name.zarr/tables/table/obsp/.zgroup", - "sample_name.zarr/tables/table/uns", - "sample_name.zarr/tables/table/uns/.zattrs", - "sample_name.zarr/tables/table/uns/.zgroup", - "sample_name.zarr/tables/table/uns/sopa_attrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/.zattrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/.zgroup", - "sample_name.zarr/tables/table/uns/sopa_attrs/intensities", - "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", - "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/0", - "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts", - "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", - "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/0", - "sample_name.zarr/tables/table/uns/spatialdata_attrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zattrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zgroup", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/0", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/0", + "sample_name.zarr/tables/table/table/raw", + "sample_name.zarr/tables/table/table/raw/.zarray", + "sample_name.zarr/tables/table/table/raw/.zattrs", + "sample_name.zarr/tables/table/table/raw/0", "sample_name.zarr/tables/table/var", "sample_name.zarr/tables/table/var/.zattrs", "sample_name.zarr/tables/table/var/.zgroup", diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 04851b9..7512e39 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -7,7 +7,7 @@ }, "PATCH_SEGMENTATION_PROSEG": { "sopa": "2.1.9", - "proseg": "3.0.10" + "proseg": "3.0.11" }, "SCANPY_PREPROCESS": { "sopa": "2.1.9", @@ -16,7 +16,7 @@ "TO_SPATIALDATA": { "sopa": "2.1.9", "spatialdata": "0.5.0", - "spatialdata_io": "0.3.0" + "spatialdata_io": "0.5.1" }, "Workflow": { "nf-core/sopa": "v1.0.0" @@ -344,141 +344,10 @@ "sample_name.zarr/tables/table/obsp/distances/indptr", "sample_name.zarr/tables/table/obsp/distances/indptr/.zarray", "sample_name.zarr/tables/table/obsp/distances/indptr/0", - "sample_name.zarr/tables/table/uns", - "sample_name.zarr/tables/table/uns/.zattrs", - "sample_name.zarr/tables/table/uns/.zgroup", - "sample_name.zarr/tables/table/uns/leiden", - "sample_name.zarr/tables/table/uns/leiden/.zattrs", - "sample_name.zarr/tables/table/uns/leiden/.zgroup", - "sample_name.zarr/tables/table/uns/leiden/params", - "sample_name.zarr/tables/table/uns/leiden/params/.zattrs", - "sample_name.zarr/tables/table/uns/leiden/params/.zgroup", - "sample_name.zarr/tables/table/uns/leiden/params/n_iterations", - "sample_name.zarr/tables/table/uns/leiden/params/n_iterations/.zarray", - "sample_name.zarr/tables/table/uns/leiden/params/n_iterations/.zattrs", - "sample_name.zarr/tables/table/uns/leiden/params/n_iterations/0", - "sample_name.zarr/tables/table/uns/leiden/params/random_state", - "sample_name.zarr/tables/table/uns/leiden/params/random_state/.zarray", - "sample_name.zarr/tables/table/uns/leiden/params/random_state/.zattrs", - "sample_name.zarr/tables/table/uns/leiden/params/random_state/0", - "sample_name.zarr/tables/table/uns/leiden/params/resolution", - "sample_name.zarr/tables/table/uns/leiden/params/resolution/.zarray", - "sample_name.zarr/tables/table/uns/leiden/params/resolution/.zattrs", - "sample_name.zarr/tables/table/uns/leiden/params/resolution/0", - "sample_name.zarr/tables/table/uns/log1p", - "sample_name.zarr/tables/table/uns/log1p/.zattrs", - "sample_name.zarr/tables/table/uns/log1p/.zgroup", - "sample_name.zarr/tables/table/uns/neighbors", - "sample_name.zarr/tables/table/uns/neighbors/.zattrs", - "sample_name.zarr/tables/table/uns/neighbors/.zgroup", - "sample_name.zarr/tables/table/uns/neighbors/connectivities_key", - "sample_name.zarr/tables/table/uns/neighbors/connectivities_key/.zarray", - "sample_name.zarr/tables/table/uns/neighbors/connectivities_key/.zattrs", - "sample_name.zarr/tables/table/uns/neighbors/connectivities_key/0", - "sample_name.zarr/tables/table/uns/neighbors/distances_key", - "sample_name.zarr/tables/table/uns/neighbors/distances_key/.zarray", - "sample_name.zarr/tables/table/uns/neighbors/distances_key/.zattrs", - "sample_name.zarr/tables/table/uns/neighbors/distances_key/0", - "sample_name.zarr/tables/table/uns/neighbors/params", - "sample_name.zarr/tables/table/uns/neighbors/params/.zattrs", - "sample_name.zarr/tables/table/uns/neighbors/params/.zgroup", - "sample_name.zarr/tables/table/uns/neighbors/params/method", - "sample_name.zarr/tables/table/uns/neighbors/params/method/.zarray", - "sample_name.zarr/tables/table/uns/neighbors/params/method/.zattrs", - "sample_name.zarr/tables/table/uns/neighbors/params/method/0", - "sample_name.zarr/tables/table/uns/neighbors/params/metric", - "sample_name.zarr/tables/table/uns/neighbors/params/metric/.zarray", - "sample_name.zarr/tables/table/uns/neighbors/params/metric/.zattrs", - "sample_name.zarr/tables/table/uns/neighbors/params/metric/0", - "sample_name.zarr/tables/table/uns/neighbors/params/n_neighbors", - "sample_name.zarr/tables/table/uns/neighbors/params/n_neighbors/.zarray", - "sample_name.zarr/tables/table/uns/neighbors/params/n_neighbors/.zattrs", - "sample_name.zarr/tables/table/uns/neighbors/params/n_neighbors/0", - "sample_name.zarr/tables/table/uns/neighbors/params/random_state", - "sample_name.zarr/tables/table/uns/neighbors/params/random_state/.zarray", - "sample_name.zarr/tables/table/uns/neighbors/params/random_state/.zattrs", - "sample_name.zarr/tables/table/uns/neighbors/params/random_state/0", - "sample_name.zarr/tables/table/uns/pca", - "sample_name.zarr/tables/table/uns/pca/.zattrs", - "sample_name.zarr/tables/table/uns/pca/.zgroup", - "sample_name.zarr/tables/table/uns/pca/params", - "sample_name.zarr/tables/table/uns/pca/params/.zattrs", - "sample_name.zarr/tables/table/uns/pca/params/.zgroup", - "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable", - "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/.zarray", - "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/.zattrs", - "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/0", - "sample_name.zarr/tables/table/uns/pca/params/zero_center", - "sample_name.zarr/tables/table/uns/pca/params/zero_center/.zarray", - "sample_name.zarr/tables/table/uns/pca/params/zero_center/.zattrs", - "sample_name.zarr/tables/table/uns/pca/params/zero_center/0", - "sample_name.zarr/tables/table/uns/pca/variance", - "sample_name.zarr/tables/table/uns/pca/variance/.zarray", - "sample_name.zarr/tables/table/uns/pca/variance/.zattrs", - "sample_name.zarr/tables/table/uns/pca/variance/0", - "sample_name.zarr/tables/table/uns/pca/variance_ratio", - "sample_name.zarr/tables/table/uns/pca/variance_ratio/.zarray", - "sample_name.zarr/tables/table/uns/pca/variance_ratio/.zattrs", - "sample_name.zarr/tables/table/uns/pca/variance_ratio/0", - "sample_name.zarr/tables/table/uns/proseg_run", - "sample_name.zarr/tables/table/uns/proseg_run/.zattrs", - "sample_name.zarr/tables/table/uns/proseg_run/.zgroup", - "sample_name.zarr/tables/table/uns/proseg_run/args", - "sample_name.zarr/tables/table/uns/proseg_run/args/.zarray", - "sample_name.zarr/tables/table/uns/proseg_run/args/.zattrs", - "sample_name.zarr/tables/table/uns/proseg_run/args/0", - "sample_name.zarr/tables/table/uns/proseg_run/duration", - "sample_name.zarr/tables/table/uns/proseg_run/duration/.zarray", - "sample_name.zarr/tables/table/uns/proseg_run/duration/.zattrs", - "sample_name.zarr/tables/table/uns/proseg_run/duration/0", - "sample_name.zarr/tables/table/uns/proseg_run/version", - "sample_name.zarr/tables/table/uns/proseg_run/version/.zarray", - "sample_name.zarr/tables/table/uns/proseg_run/version/.zattrs", - "sample_name.zarr/tables/table/uns/proseg_run/version/0", - "sample_name.zarr/tables/table/uns/sopa_attrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/.zattrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/.zgroup", - "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types", - "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/.zarray", - "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/.zattrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/0", - "sample_name.zarr/tables/table/uns/sopa_attrs/intensities", - "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", - "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/0", - "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts", - "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", - "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", - "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/0", - "sample_name.zarr/tables/table/uns/spatialdata_attrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zattrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zgroup", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/0", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", - "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/0", - "sample_name.zarr/tables/table/uns/umap", - "sample_name.zarr/tables/table/uns/umap/.zattrs", - "sample_name.zarr/tables/table/uns/umap/.zgroup", - "sample_name.zarr/tables/table/uns/umap/params", - "sample_name.zarr/tables/table/uns/umap/params/.zattrs", - "sample_name.zarr/tables/table/uns/umap/params/.zgroup", - "sample_name.zarr/tables/table/uns/umap/params/a", - "sample_name.zarr/tables/table/uns/umap/params/a/.zarray", - "sample_name.zarr/tables/table/uns/umap/params/a/.zattrs", - "sample_name.zarr/tables/table/uns/umap/params/a/0", - "sample_name.zarr/tables/table/uns/umap/params/b", - "sample_name.zarr/tables/table/uns/umap/params/b/.zarray", - "sample_name.zarr/tables/table/uns/umap/params/b/.zattrs", - "sample_name.zarr/tables/table/uns/umap/params/b/0", + "sample_name.zarr/tables/table/table/raw", + "sample_name.zarr/tables/table/table/raw/.zarray", + "sample_name.zarr/tables/table/table/raw/.zattrs", + "sample_name.zarr/tables/table/table/raw/0", "sample_name.zarr/tables/table/var", "sample_name.zarr/tables/table/var/.zattrs", "sample_name.zarr/tables/table/var/.zgroup", From c991e413df3b52cf459ef06d7daeb1fbc92c9b52 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 14 Nov 2025 16:33:23 +0100 Subject: [PATCH 200/227] fix snapshots 2 --- tests/.nftignore | 2 - tests/baysor.nf.test.snap | 41 +++++++++- tests/cellpose.nf.test.snap | 37 ++++++++- tests/default.nf.test.snap | 151 +++++++++++++++++++++++++++++++++++- 4 files changed, 217 insertions(+), 14 deletions(-) diff --git a/tests/.nftignore b/tests/.nftignore index 51015bb..7d01b42 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -13,8 +13,6 @@ pipeline_info/*.{html,json,txt,yml} **/1 **/2 **/3 -**/uns -**/uns/** **/zmetadata **/.sopa_cache **/.sopa_cache/** diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index 45d5e34..ec571dc 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -289,10 +289,43 @@ "sample_name.zarr/tables/table/obsp", "sample_name.zarr/tables/table/obsp/.zattrs", "sample_name.zarr/tables/table/obsp/.zgroup", - "sample_name.zarr/tables/table/table/raw", - "sample_name.zarr/tables/table/table/raw/.zarray", - "sample_name.zarr/tables/table/table/raw/.zattrs", - "sample_name.zarr/tables/table/table/raw/0", + "sample_name.zarr/tables/table/raw", + "sample_name.zarr/tables/table/raw/.zarray", + "sample_name.zarr/tables/table/raw/.zattrs", + "sample_name.zarr/tables/table/raw/0", + "sample_name.zarr/tables/table/uns", + "sample_name.zarr/tables/table/uns/.zattrs", + "sample_name.zarr/tables/table/uns/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/0", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/0", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/0", "sample_name.zarr/tables/table/var", "sample_name.zarr/tables/table/var/.zattrs", "sample_name.zarr/tables/table/var/.zgroup", diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 17b09d1..4b76d0d 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -218,10 +218,39 @@ "sample_name.zarr/tables/table/obsp", "sample_name.zarr/tables/table/obsp/.zattrs", "sample_name.zarr/tables/table/obsp/.zgroup", - "sample_name.zarr/tables/table/table/raw", - "sample_name.zarr/tables/table/table/raw/.zarray", - "sample_name.zarr/tables/table/table/raw/.zattrs", - "sample_name.zarr/tables/table/table/raw/0", + "sample_name.zarr/tables/table/raw", + "sample_name.zarr/tables/table/raw/.zarray", + "sample_name.zarr/tables/table/raw/.zattrs", + "sample_name.zarr/tables/table/raw/0", + "sample_name.zarr/tables/table/uns", + "sample_name.zarr/tables/table/uns/.zattrs", + "sample_name.zarr/tables/table/uns/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/0", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/0", "sample_name.zarr/tables/table/var", "sample_name.zarr/tables/table/var/.zattrs", "sample_name.zarr/tables/table/var/.zgroup", diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 7512e39..63577d6 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -344,10 +344,153 @@ "sample_name.zarr/tables/table/obsp/distances/indptr", "sample_name.zarr/tables/table/obsp/distances/indptr/.zarray", "sample_name.zarr/tables/table/obsp/distances/indptr/0", - "sample_name.zarr/tables/table/table/raw", - "sample_name.zarr/tables/table/table/raw/.zarray", - "sample_name.zarr/tables/table/table/raw/.zattrs", - "sample_name.zarr/tables/table/table/raw/0", + "sample_name.zarr/tables/table/raw", + "sample_name.zarr/tables/table/raw/.zarray", + "sample_name.zarr/tables/table/raw/.zattrs", + "sample_name.zarr/tables/table/raw/0", + "sample_name.zarr/tables/table/uns", + "sample_name.zarr/tables/table/uns/.zattrs", + "sample_name.zarr/tables/table/uns/.zgroup", + "sample_name.zarr/tables/table/uns/leiden", + "sample_name.zarr/tables/table/uns/leiden/.zattrs", + "sample_name.zarr/tables/table/uns/leiden/.zgroup", + "sample_name.zarr/tables/table/uns/leiden/params", + "sample_name.zarr/tables/table/uns/leiden/params/.zattrs", + "sample_name.zarr/tables/table/uns/leiden/params/.zgroup", + "sample_name.zarr/tables/table/uns/leiden/params/n_iterations", + "sample_name.zarr/tables/table/uns/leiden/params/n_iterations/.zarray", + "sample_name.zarr/tables/table/uns/leiden/params/n_iterations/.zattrs", + "sample_name.zarr/tables/table/uns/leiden/params/n_iterations/0", + "sample_name.zarr/tables/table/uns/leiden/params/random_state", + "sample_name.zarr/tables/table/uns/leiden/params/random_state/.zarray", + "sample_name.zarr/tables/table/uns/leiden/params/random_state/.zattrs", + "sample_name.zarr/tables/table/uns/leiden/params/random_state/0", + "sample_name.zarr/tables/table/uns/leiden/params/resolution", + "sample_name.zarr/tables/table/uns/leiden/params/resolution/.zarray", + "sample_name.zarr/tables/table/uns/leiden/params/resolution/.zattrs", + "sample_name.zarr/tables/table/uns/leiden/params/resolution/0", + "sample_name.zarr/tables/table/uns/log1p", + "sample_name.zarr/tables/table/uns/log1p/.zattrs", + "sample_name.zarr/tables/table/uns/log1p/.zgroup", + "sample_name.zarr/tables/table/uns/log1p/base", + "sample_name.zarr/tables/table/uns/log1p/base/.zarray", + "sample_name.zarr/tables/table/uns/log1p/base/.zattrs", + "sample_name.zarr/tables/table/uns/log1p/base/0", + "sample_name.zarr/tables/table/uns/neighbors", + "sample_name.zarr/tables/table/uns/neighbors/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/.zgroup", + "sample_name.zarr/tables/table/uns/neighbors/connectivities_key", + "sample_name.zarr/tables/table/uns/neighbors/connectivities_key/.zarray", + "sample_name.zarr/tables/table/uns/neighbors/connectivities_key/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/connectivities_key/0", + "sample_name.zarr/tables/table/uns/neighbors/distances_key", + "sample_name.zarr/tables/table/uns/neighbors/distances_key/.zarray", + "sample_name.zarr/tables/table/uns/neighbors/distances_key/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/distances_key/0", + "sample_name.zarr/tables/table/uns/neighbors/params", + "sample_name.zarr/tables/table/uns/neighbors/params/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/params/.zgroup", + "sample_name.zarr/tables/table/uns/neighbors/params/method", + "sample_name.zarr/tables/table/uns/neighbors/params/method/.zarray", + "sample_name.zarr/tables/table/uns/neighbors/params/method/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/params/method/0", + "sample_name.zarr/tables/table/uns/neighbors/params/metric", + "sample_name.zarr/tables/table/uns/neighbors/params/metric/.zarray", + "sample_name.zarr/tables/table/uns/neighbors/params/metric/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/params/metric/0", + "sample_name.zarr/tables/table/uns/neighbors/params/n_neighbors", + "sample_name.zarr/tables/table/uns/neighbors/params/n_neighbors/.zarray", + "sample_name.zarr/tables/table/uns/neighbors/params/n_neighbors/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/params/n_neighbors/0", + "sample_name.zarr/tables/table/uns/neighbors/params/random_state", + "sample_name.zarr/tables/table/uns/neighbors/params/random_state/.zarray", + "sample_name.zarr/tables/table/uns/neighbors/params/random_state/.zattrs", + "sample_name.zarr/tables/table/uns/neighbors/params/random_state/0", + "sample_name.zarr/tables/table/uns/pca", + "sample_name.zarr/tables/table/uns/pca/.zattrs", + "sample_name.zarr/tables/table/uns/pca/.zgroup", + "sample_name.zarr/tables/table/uns/pca/params", + "sample_name.zarr/tables/table/uns/pca/params/.zattrs", + "sample_name.zarr/tables/table/uns/pca/params/.zgroup", + "sample_name.zarr/tables/table/uns/pca/params/mask_var", + "sample_name.zarr/tables/table/uns/pca/params/mask_var/.zarray", + "sample_name.zarr/tables/table/uns/pca/params/mask_var/.zattrs", + "sample_name.zarr/tables/table/uns/pca/params/mask_var/0", + "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable", + "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/.zarray", + "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/.zattrs", + "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/0", + "sample_name.zarr/tables/table/uns/pca/params/zero_center", + "sample_name.zarr/tables/table/uns/pca/params/zero_center/.zarray", + "sample_name.zarr/tables/table/uns/pca/params/zero_center/.zattrs", + "sample_name.zarr/tables/table/uns/pca/params/zero_center/0", + "sample_name.zarr/tables/table/uns/pca/variance", + "sample_name.zarr/tables/table/uns/pca/variance/.zarray", + "sample_name.zarr/tables/table/uns/pca/variance/.zattrs", + "sample_name.zarr/tables/table/uns/pca/variance/0", + "sample_name.zarr/tables/table/uns/pca/variance_ratio", + "sample_name.zarr/tables/table/uns/pca/variance_ratio/.zarray", + "sample_name.zarr/tables/table/uns/pca/variance_ratio/.zattrs", + "sample_name.zarr/tables/table/uns/pca/variance_ratio/0", + "sample_name.zarr/tables/table/uns/proseg_run", + "sample_name.zarr/tables/table/uns/proseg_run/.zattrs", + "sample_name.zarr/tables/table/uns/proseg_run/.zgroup", + "sample_name.zarr/tables/table/uns/proseg_run/args", + "sample_name.zarr/tables/table/uns/proseg_run/args/.zarray", + "sample_name.zarr/tables/table/uns/proseg_run/args/.zattrs", + "sample_name.zarr/tables/table/uns/proseg_run/args/0", + "sample_name.zarr/tables/table/uns/proseg_run/duration", + "sample_name.zarr/tables/table/uns/proseg_run/duration/.zarray", + "sample_name.zarr/tables/table/uns/proseg_run/duration/.zattrs", + "sample_name.zarr/tables/table/uns/proseg_run/duration/0", + "sample_name.zarr/tables/table/uns/proseg_run/version", + "sample_name.zarr/tables/table/uns/proseg_run/version/.zarray", + "sample_name.zarr/tables/table/uns/proseg_run/version/.zattrs", + "sample_name.zarr/tables/table/uns/proseg_run/version/0", + "sample_name.zarr/tables/table/uns/sopa_attrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/cell_types/0", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/intensities/0", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zarray", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/.zattrs", + "sample_name.zarr/tables/table/uns/sopa_attrs/transcripts/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/.zgroup", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/instance_key/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region/0", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zarray", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/.zattrs", + "sample_name.zarr/tables/table/uns/spatialdata_attrs/region_key/0", + "sample_name.zarr/tables/table/uns/umap", + "sample_name.zarr/tables/table/uns/umap/.zattrs", + "sample_name.zarr/tables/table/uns/umap/.zgroup", + "sample_name.zarr/tables/table/uns/umap/params", + "sample_name.zarr/tables/table/uns/umap/params/.zattrs", + "sample_name.zarr/tables/table/uns/umap/params/.zgroup", + "sample_name.zarr/tables/table/uns/umap/params/a", + "sample_name.zarr/tables/table/uns/umap/params/a/.zarray", + "sample_name.zarr/tables/table/uns/umap/params/a/.zattrs", + "sample_name.zarr/tables/table/uns/umap/params/a/0", + "sample_name.zarr/tables/table/uns/umap/params/b", + "sample_name.zarr/tables/table/uns/umap/params/b/.zarray", + "sample_name.zarr/tables/table/uns/umap/params/b/.zattrs", + "sample_name.zarr/tables/table/uns/umap/params/b/0", "sample_name.zarr/tables/table/var", "sample_name.zarr/tables/table/var/.zattrs", "sample_name.zarr/tables/table/var/.zgroup", From 2b846f8b0ad4bc2a96fc7bfff5e124d22c504eac Mon Sep 17 00:00:00 2001 From: Blampey Quentin Date: Fri, 5 Dec 2025 12:22:42 +0100 Subject: [PATCH 201/227] use sopa==2.1.10 and update snapshots --- modules/local/aggregate/environment.yml | 2 +- modules/local/aggregate/main.nf | 4 ++-- modules/local/explorer/environment.yml | 2 +- modules/local/explorer/main.nf | 4 ++-- modules/local/explorer_raw/environment.yml | 2 +- modules/local/explorer_raw/main.nf | 4 ++-- modules/local/fluo_annotation/environment.yml | 2 +- modules/local/fluo_annotation/main.nf | 4 ++-- modules/local/make_image_patches/environment.yml | 2 +- modules/local/make_image_patches/main.nf | 4 ++-- modules/local/make_transcript_patches/environment.yml | 2 +- modules/local/make_transcript_patches/main.nf | 4 ++-- modules/local/patch_segmentation_baysor/main.nf | 4 ++-- modules/local/patch_segmentation_cellpose/main.nf | 4 ++-- .../local/patch_segmentation_comseg/environment.yml | 2 +- modules/local/patch_segmentation_comseg/main.nf | 4 ++-- .../local/patch_segmentation_proseg/environment.yml | 2 +- modules/local/patch_segmentation_proseg/main.nf | 4 ++-- modules/local/patch_segmentation_stardist/main.nf | 4 ++-- modules/local/report/environment.yml | 2 +- modules/local/report/main.nf | 4 ++-- modules/local/resolve_baysor/main.nf | 4 ++-- modules/local/resolve_cellpose/main.nf | 4 ++-- modules/local/resolve_comseg/environment.yml | 2 +- modules/local/resolve_comseg/main.nf | 4 ++-- modules/local/resolve_stardist/main.nf | 4 ++-- modules/local/scanpy_preprocess/environment.yml | 2 +- modules/local/scanpy_preprocess/main.nf | 4 ++-- modules/local/tangram_annotation/environment.yml | 2 +- modules/local/tangram_annotation/main.nf | 4 ++-- modules/local/tissue_segmentation/environment.yml | 2 +- modules/local/tissue_segmentation/main.nf | 4 ++-- modules/local/to_spatialdata/environment.yml | 2 +- modules/local/to_spatialdata/main.nf | 4 ++-- tests/baysor.nf.test | 2 +- tests/baysor.nf.test.snap | 8 ++++---- tests/cellpose.nf.test | 2 +- tests/cellpose.nf.test.snap | 8 ++++---- tests/default.nf.test | 2 +- tests/default.nf.test.snap | 10 +++++----- workflows/sopa.nf | 2 +- 41 files changed, 71 insertions(+), 71 deletions(-) diff --git a/modules/local/aggregate/environment.yml b/modules/local/aggregate/environment.yml index 0f643ba..0680157 100644 --- a/modules/local/aggregate/environment.yml +++ b/modules/local/aggregate/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 diff --git a/modules/local/aggregate/main.nf b/modules/local/aggregate/main.nf index 2b5da49..14abff0 100644 --- a/modules/local/aggregate/main.nf +++ b/modules/local/aggregate/main.nf @@ -3,8 +3,8 @@ process AGGREGATE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.10' + : 'docker.io/quentinblampey/sopa:2.1.10'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/explorer/environment.yml b/modules/local/explorer/environment.yml index 0f643ba..0680157 100644 --- a/modules/local/explorer/environment.yml +++ b/modules/local/explorer/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 diff --git a/modules/local/explorer/main.nf b/modules/local/explorer/main.nf index 307da53..4bd5786 100644 --- a/modules/local/explorer/main.nf +++ b/modules/local/explorer/main.nf @@ -3,8 +3,8 @@ process EXPLORER { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.10' + : 'docker.io/quentinblampey/sopa:2.1.10'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/explorer_raw/environment.yml b/modules/local/explorer_raw/environment.yml index 0f643ba..0680157 100644 --- a/modules/local/explorer_raw/environment.yml +++ b/modules/local/explorer_raw/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 diff --git a/modules/local/explorer_raw/main.nf b/modules/local/explorer_raw/main.nf index a844ea6..6ce0be7 100644 --- a/modules/local/explorer_raw/main.nf +++ b/modules/local/explorer_raw/main.nf @@ -5,8 +5,8 @@ process EXPLORER_RAW { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.10' + : 'docker.io/quentinblampey/sopa:2.1.10'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/fluo_annotation/environment.yml b/modules/local/fluo_annotation/environment.yml index 0f643ba..0680157 100644 --- a/modules/local/fluo_annotation/environment.yml +++ b/modules/local/fluo_annotation/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 diff --git a/modules/local/fluo_annotation/main.nf b/modules/local/fluo_annotation/main.nf index 3608926..7704236 100644 --- a/modules/local/fluo_annotation/main.nf +++ b/modules/local/fluo_annotation/main.nf @@ -3,8 +3,8 @@ process FLUO_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.10' + : 'docker.io/quentinblampey/sopa:2.1.10'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_image_patches/environment.yml b/modules/local/make_image_patches/environment.yml index 0f643ba..0680157 100644 --- a/modules/local/make_image_patches/environment.yml +++ b/modules/local/make_image_patches/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 diff --git a/modules/local/make_image_patches/main.nf b/modules/local/make_image_patches/main.nf index fdae2e0..8e6ba86 100644 --- a/modules/local/make_image_patches/main.nf +++ b/modules/local/make_image_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_IMAGE_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.10' + : 'docker.io/quentinblampey/sopa:2.1.10'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_transcript_patches/environment.yml b/modules/local/make_transcript_patches/environment.yml index 0f643ba..0680157 100644 --- a/modules/local/make_transcript_patches/environment.yml +++ b/modules/local/make_transcript_patches/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 diff --git a/modules/local/make_transcript_patches/main.nf b/modules/local/make_transcript_patches/main.nf index 78c0d60..f9310ce 100644 --- a/modules/local/make_transcript_patches/main.nf +++ b/modules/local/make_transcript_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_TRANSCRIPT_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.10' + : 'docker.io/quentinblampey/sopa:2.1.10'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/patch_segmentation_baysor/main.nf b/modules/local/patch_segmentation_baysor/main.nf index ae529a9..829aab4 100644 --- a/modules/local/patch_segmentation_baysor/main.nf +++ b/modules/local/patch_segmentation_baysor/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-baysor' - : 'docker.io/quentinblampey/sopa:2.1.9-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.10-baysor' + : 'docker.io/quentinblampey/sopa:2.1.10-baysor'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_cellpose/main.nf b/modules/local/patch_segmentation_cellpose/main.nf index 55e4391..b17c93c 100644 --- a/modules/local/patch_segmentation_cellpose/main.nf +++ b/modules/local/patch_segmentation_cellpose/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.9-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.10-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.10-cellpose'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_comseg/environment.yml b/modules/local/patch_segmentation_comseg/environment.yml index 2654b07..d057715 100644 --- a/modules/local/patch_segmentation_comseg/environment.yml +++ b/modules/local/patch_segmentation_comseg/environment.yml @@ -5,5 +5,5 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 - comseg==1.8.2 diff --git a/modules/local/patch_segmentation_comseg/main.nf b/modules/local/patch_segmentation_comseg/main.nf index 48ce4be..37dcf48 100644 --- a/modules/local/patch_segmentation_comseg/main.nf +++ b/modules/local/patch_segmentation_comseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-comseg' - : 'docker.io/quentinblampey/sopa:2.1.9-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.10-comseg' + : 'docker.io/quentinblampey/sopa:2.1.10-comseg'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_proseg/environment.yml b/modules/local/patch_segmentation_proseg/environment.yml index 0f643ba..0680157 100644 --- a/modules/local/patch_segmentation_proseg/environment.yml +++ b/modules/local/patch_segmentation_proseg/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 diff --git a/modules/local/patch_segmentation_proseg/main.nf b/modules/local/patch_segmentation_proseg/main.nf index c3d13d4..16b7a93 100644 --- a/modules/local/patch_segmentation_proseg/main.nf +++ b/modules/local/patch_segmentation_proseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_PROSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-proseg' - : 'docker.io/quentinblampey/sopa:2.1.9-proseg'}" + ? 'docker://quentinblampey/sopa:2.1.10-proseg' + : 'docker.io/quentinblampey/sopa:2.1.10-proseg'}" input: tuple val(meta), path(sdata_path), path(patches_file_transcripts), path(transcript_patches) diff --git a/modules/local/patch_segmentation_stardist/main.nf b/modules/local/patch_segmentation_stardist/main.nf index 0761e07..5ef3c8e 100644 --- a/modules/local/patch_segmentation_stardist/main.nf +++ b/modules/local/patch_segmentation_stardist/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-stardist' - : 'docker.io/quentinblampey/sopa:2.1.9-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.10-stardist' + : 'docker.io/quentinblampey/sopa:2.1.10-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/report/environment.yml b/modules/local/report/environment.yml index 0f643ba..0680157 100644 --- a/modules/local/report/environment.yml +++ b/modules/local/report/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 diff --git a/modules/local/report/main.nf b/modules/local/report/main.nf index b68af19..c839d1e 100644 --- a/modules/local/report/main.nf +++ b/modules/local/report/main.nf @@ -3,8 +3,8 @@ process REPORT { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.10' + : 'docker.io/quentinblampey/sopa:2.1.10'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/resolve_baysor/main.nf b/modules/local/resolve_baysor/main.nf index fb16778..0291fb4 100644 --- a/modules/local/resolve_baysor/main.nf +++ b/modules/local/resolve_baysor/main.nf @@ -3,8 +3,8 @@ process RESOLVE_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-baysor' - : 'docker.io/quentinblampey/sopa:2.1.9-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.10-baysor' + : 'docker.io/quentinblampey/sopa:2.1.10-baysor'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_cellpose/main.nf b/modules/local/resolve_cellpose/main.nf index 3af7531..adef316 100644 --- a/modules/local/resolve_cellpose/main.nf +++ b/modules/local/resolve_cellpose/main.nf @@ -3,8 +3,8 @@ process RESOLVE_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.9-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.10-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.10-cellpose'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_comseg/environment.yml b/modules/local/resolve_comseg/environment.yml index 2654b07..d057715 100644 --- a/modules/local/resolve_comseg/environment.yml +++ b/modules/local/resolve_comseg/environment.yml @@ -5,5 +5,5 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 - comseg==1.8.2 diff --git a/modules/local/resolve_comseg/main.nf b/modules/local/resolve_comseg/main.nf index a4ddaeb..464b684 100644 --- a/modules/local/resolve_comseg/main.nf +++ b/modules/local/resolve_comseg/main.nf @@ -3,8 +3,8 @@ process RESOLVE_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-comseg' - : 'docker.io/quentinblampey/sopa:2.1.9-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.10-comseg' + : 'docker.io/quentinblampey/sopa:2.1.10-comseg'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_stardist/main.nf b/modules/local/resolve_stardist/main.nf index 1340847..19a228c 100644 --- a/modules/local/resolve_stardist/main.nf +++ b/modules/local/resolve_stardist/main.nf @@ -3,8 +3,8 @@ process RESOLVE_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-stardist' - : 'docker.io/quentinblampey/sopa:2.1.9-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.10-stardist' + : 'docker.io/quentinblampey/sopa:2.1.10-stardist'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/scanpy_preprocess/environment.yml b/modules/local/scanpy_preprocess/environment.yml index 0f643ba..0680157 100644 --- a/modules/local/scanpy_preprocess/environment.yml +++ b/modules/local/scanpy_preprocess/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 diff --git a/modules/local/scanpy_preprocess/main.nf b/modules/local/scanpy_preprocess/main.nf index bbb8c2b..c211bc1 100644 --- a/modules/local/scanpy_preprocess/main.nf +++ b/modules/local/scanpy_preprocess/main.nf @@ -3,8 +3,8 @@ process SCANPY_PREPROCESS { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.10' + : 'docker.io/quentinblampey/sopa:2.1.10'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tangram_annotation/environment.yml b/modules/local/tangram_annotation/environment.yml index 650c28b..01a6eaa 100644 --- a/modules/local/tangram_annotation/environment.yml +++ b/modules/local/tangram_annotation/environment.yml @@ -5,5 +5,5 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 - tangram-sc==1.0.4 diff --git a/modules/local/tangram_annotation/main.nf b/modules/local/tangram_annotation/main.nf index f9a7e80..80e674b 100644 --- a/modules/local/tangram_annotation/main.nf +++ b/modules/local/tangram_annotation/main.nf @@ -3,8 +3,8 @@ process TANGRAM_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-tangram' - : 'docker.io/quentinblampey/sopa:2.1.9-tangram'}" + ? 'docker://quentinblampey/sopa:2.1.10-tangram' + : 'docker.io/quentinblampey/sopa:2.1.10-tangram'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tissue_segmentation/environment.yml b/modules/local/tissue_segmentation/environment.yml index 0f643ba..0680157 100644 --- a/modules/local/tissue_segmentation/environment.yml +++ b/modules/local/tissue_segmentation/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 diff --git a/modules/local/tissue_segmentation/main.nf b/modules/local/tissue_segmentation/main.nf index 046dc44..d53c796 100644 --- a/modules/local/tissue_segmentation/main.nf +++ b/modules/local/tissue_segmentation/main.nf @@ -3,8 +3,8 @@ process TISSUE_SEGMENTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.10' + : 'docker.io/quentinblampey/sopa:2.1.10'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/to_spatialdata/environment.yml b/modules/local/to_spatialdata/environment.yml index 0f643ba..0680157 100644 --- a/modules/local/to_spatialdata/environment.yml +++ b/modules/local/to_spatialdata/environment.yml @@ -5,4 +5,4 @@ dependencies: - python=3.11 - pip=24.3.1 - pip: - - sopa==2.1.6 + - sopa==2.1.10 diff --git a/modules/local/to_spatialdata/main.nf b/modules/local/to_spatialdata/main.nf index 9e94dd8..6e91242 100644 --- a/modules/local/to_spatialdata/main.nf +++ b/modules/local/to_spatialdata/main.nf @@ -5,8 +5,8 @@ process TO_SPATIALDATA { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.10' + : 'docker.io/quentinblampey/sopa:2.1.10'}" input: tuple val(meta), path(data_dir), path(fullres_image_file) diff --git a/tests/baysor.nf.test b/tests/baysor.nf.test index 946801b..56ab5c8 100644 --- a/tests/baysor.nf.test +++ b/tests/baysor.nf.test @@ -24,7 +24,7 @@ nextflow_pipeline { // Number of successful tasks workflow.trace.succeeded().size(), // pipeline versions.yml file for multiqc from which Nextflow version is removed because we test pipelines on multiple Nextflow versions - removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_mqc_versions.yml"), + removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_versions.yml"), // All stable path name, with a relative path stable_name, // All files with stable contents diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index ec571dc..273648b 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -4,15 +4,15 @@ 9, { "RESOLVE_BAYSOR": { - "sopa": "2.1.9", + "sopa": "2.1.10", "baysor": "0.7.1" }, "TANGRAM_ANNOTATION": { - "sopa": "2.1.9", + "sopa": "2.1.10", "tangram": "1.0.4" }, "TO_SPATIALDATA": { - "sopa": "2.1.9", + "sopa": "2.1.10", "spatialdata": "0.5.0", "spatialdata_io": "0.5.1" }, @@ -22,7 +22,7 @@ }, [ "pipeline_info", - "pipeline_info/nf_core_sopa_software_mqc_versions.yml", + "pipeline_info/nf_core_sopa_software_versions.yml", "sample_name.explorer", "sample_name.explorer/adata.h5ad", "sample_name.explorer/analysis.zarr.zip", diff --git a/tests/cellpose.nf.test b/tests/cellpose.nf.test index 6fc0b0e..1e542e0 100644 --- a/tests/cellpose.nf.test +++ b/tests/cellpose.nf.test @@ -24,7 +24,7 @@ nextflow_pipeline { // Number of successful tasks workflow.trace.succeeded().size(), // pipeline versions.yml file for multiqc from which Nextflow version is removed because we test pipelines on multiple Nextflow versions - removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_mqc_versions.yml"), + removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_versions.yml"), // All stable path name, with a relative path stable_name, // All files with stable contents diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 4b76d0d..8954057 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -4,11 +4,11 @@ 8, { "RESOLVE_CELLPOSE": { - "sopa": "2.1.9", - "cellpose": "4.0.7" + "sopa": "2.1.10", + "cellpose": "4.0.8" }, "TO_SPATIALDATA": { - "sopa": "2.1.9", + "sopa": "2.1.10", "spatialdata": "0.5.0", "spatialdata_io": "0.5.1" }, @@ -18,7 +18,7 @@ }, [ "pipeline_info", - "pipeline_info/nf_core_sopa_software_mqc_versions.yml", + "pipeline_info/nf_core_sopa_software_versions.yml", "sample_name.explorer", "sample_name.explorer/adata.h5ad", "sample_name.explorer/analysis.zarr.zip", diff --git a/tests/default.nf.test b/tests/default.nf.test index 3e17df0..76ca31a 100644 --- a/tests/default.nf.test +++ b/tests/default.nf.test @@ -22,7 +22,7 @@ nextflow_pipeline { { assert workflow.success}, { assert snapshot( // pipeline versions.yml file for multiqc from which Nextflow version is removed because we test pipelines on multiple Nextflow versions - removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_mqc_versions.yml"), + removeNextflowVersion("$outputDir/pipeline_info/nf_core_sopa_software_versions.yml"), // All stable path name, with a relative path stable_name, // All files with stable contents diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 63577d6..e6a5d8b 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -3,18 +3,18 @@ "content": [ { "FLUO_ANNOTATION": { - "sopa": "2.1.9" + "sopa": "2.1.10" }, "PATCH_SEGMENTATION_PROSEG": { - "sopa": "2.1.9", + "sopa": "2.1.10", "proseg": "3.0.11" }, "SCANPY_PREPROCESS": { - "sopa": "2.1.9", + "sopa": "2.1.10", "scanpy": "1.11.5" }, "TO_SPATIALDATA": { - "sopa": "2.1.9", + "sopa": "2.1.10", "spatialdata": "0.5.0", "spatialdata_io": "0.5.1" }, @@ -24,7 +24,7 @@ }, [ "pipeline_info", - "pipeline_info/nf_core_sopa_software_mqc_versions.yml", + "pipeline_info/nf_core_sopa_software_versions.yml", "sample_name.explorer", "sample_name.explorer/adata.h5ad", "sample_name.explorer/analysis.zarr.zip", diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 142322d..0533e3e 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -160,7 +160,7 @@ workflow SOPA { .mix(topic_versions_string) .collectFile( storeDir: "${params.outdir}/pipeline_info", - name: 'nf_core_' + 'sopa_software_' + 'versions.yml', + name: 'nf_core_sopa_software_versions.yml', sort: true, newLine: true ).set { ch_collated_versions } From 4bba4b5d8ddfd190042583937db668f5ab5928e9 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 12 Dec 2025 13:42:44 +0100 Subject: [PATCH 202/227] start adding flattened params --- nextflow_schema.json | 360 +++++++++++++++++++++---------------------- 1 file changed, 172 insertions(+), 188 deletions(-) diff --git a/nextflow_schema.json b/nextflow_schema.json index 2c7361d..50f1a3c 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -38,191 +38,6 @@ } } }, - "sopa_config": { - "title": "The Sopa config", - "type": "object", - "fa_icon": "fas fa-rocket", - "description": "Parameters related to Sopa, provided via a `-profile` (see the [usage](../usage) section).", - "required": ["read", "segmentation"], - "properties": { - "read": { - "type": "object", - "required": ["technology"], - "properties": { - "technology": { - "type": "string", - "description": "Technology used for the spatial data, e.g., 'xenium', 'merscope', ...", - "fa_icon": "fas fa-microscope", - "enum": [ - "xenium", - "merscope", - "cosmx", - "visium_hd", - "molecular_cartography", - "macsima", - "phenocycler", - "hyperion", - "ome_tif", - "toy_dataset" - ] - }, - "kwargs": { - "type": "object", - "additionalProperties": true, - "fa_icon": "fas fa-gear" - } - }, - "additionalProperties": true, - "description": "Dictionary of parameters to read the raw spatial inputs, e.g., technology name.", - "fa_icon": "fas fa-gear" - }, - "segmentation": { - "type": "object", - "properties": { - "tissue": { - "type": "object", - "additionalProperties": true, - "description": "Dictionary of tissue segmentation parameters.", - "fa_icon": "fas fa-gear" - }, - "baysor": { - "type": "object", - "properties": { - "config": { - "type": "object", - "properties": { - "data": { - "type": "object", - "description": "Baysor config: data section.", - "fa_icon": "fas fa-gear", - "additionalProperties": true - }, - "segmentation": { - "type": "object", - "description": "Baysor config: segmentation section.", - "fa_icon": "fas fa-gear", - "additionalProperties": true - } - }, - "description": "Baysor configuration parameters.", - "fa_icon": "fas fa-gear" - } - }, - "additionalProperties": true, - "description": "Dictionary of Baysor parameters." - }, - "comseg": { - "type": "object", - "properties": { - "config": { - "type": "object", - "properties": { - "dict_scale": { - "type": "object", - "description": "Comseg dict scale section.", - "fa_icon": "fas fa-gear", - "additionalProperties": true - } - }, - "additionalProperties": true, - "description": "Comseg configuration parameters.", - "fa_icon": "fas fa-gear" - } - }, - "additionalProperties": true, - "description": "Dictionary of Comseg parameters." - }, - "cellpose": { - "type": "object", - "additionalProperties": true, - "description": "Dictionary of Cellpose parameters.", - "fa_icon": "fas fa-gear" - }, - "stardist": { - "type": "object", - "additionalProperties": true, - "description": "Dictionary of Stardist parameters.", - "fa_icon": "fas fa-gear" - }, - "proseg": { - "type": "object", - "additionalProperties": true, - "description": "Dictionary of Proseg parameters.", - "fa_icon": "fas fa-gear" - } - }, - "additionalProperties": true, - "description": "Dictionary of segmentation parameters.", - "fa_icon": "fas fa-gear" - }, - "patchify": { - "type": "object", - "additionalProperties": true, - "description": "Dictionary of patches parameters.", - "fa_icon": "fas fa-gear" - }, - "aggregate": { - "type": "object", - "additionalProperties": true, - "description": "Dictionary of aggregation parameters.", - "fa_icon": "fas fa-gear" - }, - "annotation": { - "type": "object", - "required": ["method", "args"], - "properties": { - "method": { - "type": "string", - "description": "Cell type annotation method, either 'tangram' or 'fluorescence'", - "enum": ["tangram", "fluorescence"], - "fa_icon": "fas fa-gear" - }, - "args": { - "type": "object", - "description": "Cell type annotation arguments", - "fa_icon": "fas fa-gear", - "properties": { - "marker_cell_dict": { - "type": "object", - "description": "Dictionary mapping cell type markers to their descriptions", - "additionalProperties": { - "type": "string" - } - } - }, - "additionalProperties": true - } - }, - "additionalProperties": true, - "description": "Dictionary of annotation parameters.", - "fa_icon": "fas fa-gear" - }, - "scanpy_preprocess": { - "type": "object", - "properties": { - "resolution": { - "type": "number", - "description": "Resolution parameter for the Leiden clustering algorithm.", - "fa_icon": "fas fa-sliders-h" - }, - "check_counts": { - "type": "boolean", - "description": "Whether to check counts in Scanpy preprocessing.", - "fa_icon": "fas fa-check" - } - }, - "additionalProperties": true, - "description": "Dictionary of Scanpy preprocessing parameters.", - "fa_icon": "fas fa-gear" - }, - "explorer": { - "type": "object", - "additionalProperties": true, - "description": "Dictionary of Xenium Explorer parameters.", - "fa_icon": "fas fa-gear" - } - } - }, "spaceranger_options": { "title": "Space Ranger options", "type": "object", @@ -379,15 +194,163 @@ "description": "Display hidden parameters in the help message (only works when --help or --help_full are provided)." } } + }, + "reader": { + "title": "Reader", + "type": "object", + "description": "Parameters related to the SpatialData reader", + "default": "", + "properties": { + "technology": { + "type": "string", + "description": "Technology used for the spatial data, e.g., 'xenium', 'merscope', ..." + }, + "convert_kwargs": { + "type": "string" + } + }, + "required": ["technology"] + }, + "patches": { + "title": "Patches", + "type": "object", + "description": "", + "default": "", + "properties": { + "patch_width_pixel": { + "type": "number" + }, + "patch_overlap_pixel": { + "type": "number" + }, + "patch_width_microns": { + "type": "number" + }, + "patch_overlap_microns": { + "type": "number" + }, + "prior_shapes_key": { + "type": "string" + } + } + }, + "aggregation": { + "title": "Aggregation", + "type": "object", + "description": "", + "default": "", + "properties": { + "aggregate_genes": { + "type": "boolean", + "default": true + }, + "aggregate_channels": { + "type": "boolean", + "default": true + }, + "min_transcripts": { + "type": "string", + "default": "0" + }, + "min_intensity_ratio": { + "type": "string", + "default": "0" + }, + "expand_radius_ratio": { + "type": "string", + "default": "0" + } + } + }, + "scanpy_preprocessing": { + "title": "Scanpy preprocessing", + "type": "object", + "description": "Optional scanpy table preprocessing (log1p, UMAP, leiden clustering) after aggregation/annotation.", + "default": "", + "properties": { + "use_scanpy_preprocessing": { + "type": "boolean", + "description": "Whether to run scanpy preprocessing" + }, + "resolution": { + "type": "number", + "description": "Resolution parameter for the leiden clustering", + "default": 1 + }, + "check_counts": { + "type": "boolean", + "description": "Whether to check that adata.X contains counts" + }, + "hvg": { + "type": "boolean", + "description": "Whether to compute highly variable genes before computing the UMAP and clustering" + } + } + }, + "explorer": { + "title": "Explorer", + "type": "object", + "description": "", + "default": "", + "properties": { + "pixel_size": { + "type": "number", + "default": 0.2125, + "description": "Number of microns in a pixel. Invalid value can lead to inconsistent scales in the Explorer." + }, + "lazy": { + "type": "boolean", + "default": true, + "description": "If `True`, will not load the full images in memory (except if the image memory is below `ram_threshold_gb`)" + }, + "ram_threshold_gb": { + "type": "number", + "description": "Threshold (in gygabytes) from which image can be loaded in memory.", + "default": 4 + } + } + }, + "proseg": { + "title": "Proseg", + "type": "object", + "description": "", + "default": "", + "properties": { + "use_proseg": { + "type": "boolean", + "description": "Whether to run proseg segmentation" + } + } + }, + "tangram": { + "title": "Tangram", + "type": "object", + "description": "", + "default": "", + "properties": { + "use_tangram": { + "type": "boolean", + "description": "Whether to run tangram cell-type annotation" + }, + "sc_reference_path": { + "type": "string", + "description": "Path to the scRNAseq annotated reference, as a `.h5ad` file" + }, + "cell_type_key": { + "type": "string", + "description": "Key of `adata_ref.obs` containing the cell-types" + }, + "reference_preprocessing": { + "type": "string", + "description": "Preprocessing method applied to the reference. Either None (raw counts), or `normalized` (sc.pp.normalize_total) or `log1p` (sc.pp.normalize_total and sc.pp.log1p)" + } + } } }, "allOf": [ { "$ref": "#/$defs/input_output_options" }, - { - "$ref": "#/$defs/sopa_config" - }, { "$ref": "#/$defs/spaceranger_options" }, @@ -396,6 +359,27 @@ }, { "$ref": "#/$defs/generic_options" + }, + { + "$ref": "#/$defs/reader" + }, + { + "$ref": "#/$defs/patches" + }, + { + "$ref": "#/$defs/aggregation" + }, + { + "$ref": "#/$defs/scanpy_preprocessing" + }, + { + "$ref": "#/$defs/explorer" + }, + { + "$ref": "#/$defs/proseg" + }, + { + "$ref": "#/$defs/tangram" } ] } From 0aa08274baadadcfc131fce8154fbc90085e02cb Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 12 Dec 2025 14:37:46 +0100 Subject: [PATCH 203/227] in progress --- conf/test.config | 67 +++++----- modules/local/utils.nf | 52 ++++---- nextflow_schema.json | 8 +- .../local/utils_nfcore_sopa_pipeline/main.nf | 117 ++++++++--------- workflows/sopa.nf | 118 +++++++++--------- 5 files changed, 174 insertions(+), 188 deletions(-) diff --git a/conf/test.config b/conf/test.config index 0befa9f..2eae13b 100644 --- a/conf/test.config +++ b/conf/test.config @@ -25,42 +25,33 @@ params { // Input data input = "${baseDir}/tests/samplesheet.csv" - read = [ - technology: "toy_dataset", - kwargs: [ - genes: 500 - ], - ] - - patchify = [ - patch_width_microns: 400, - patch_overlap_microns: 20, - ] - - segmentation.proseg.prior_shapes_key = "auto" - - aggregate = [ - aggregate_channels: true, - min_transcripts: 5, - ] - - annotation = [ - method: "fluorescence", - args: [ - marker_cell_dict: [ - CK: "Tumoral cell", - CD3: "T cell", - CD20: "B cell", - ] - ], - ] - - scanpy_preprocess = [ - check_counts: false - ] - - explorer = [ - ram_threshold_gb: 4, - pixel_size: 0.1, - ] + // Reading + technology = "toy_dataset" + convert_kwargs = '{"genes": 500}' + + // Patches + patch_width_microns = -1 + prior_shapes_key = "auto" + + // Aggregation + aggregate_channels = true + min_transcripts = 5 + + // annotation = [ + // method: "fluorescence", + // args: [ + // marker_cell_dict: [ + // CK: "Tumoral cell", + // CD3: "T cell", + // CD20: "B cell", + // ] + // ], + // ] + + // Scanpy preprocessing + use_scanpy_preprocessing = true + + // Explorer + ram_threshold_gb = 4 + pixel_size = 0.1 } diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 6768692..d0ac72f 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -39,51 +39,45 @@ def ArgsCLI(Map params, String contains = null, List keys = null) { return params .findAll { key, _value -> - (contains == null || key.contains(contains)) && (keys == null || key in keys) + (contains == null || key.contains(contains)) && (keys == null || key in keys) && (_value != null) } .collect { key, value -> stringifyItem(key, value) } .join(" ") } def ArgsToSpatialData(Map params, Map meta, String fullres_image_file) { - def args = deepCopyCollection(params.read) + def args = [ + technology: params.technology, + kwargs: params.convert_kwargs, + ] - if (args.technology == "visium_hd") { - if (!args.kwargs) { - args.kwargs = ["dataset_id": meta.id] - } - else { - args.kwargs["dataset_id"] = meta.id - } + // if (args.technology == "visium_hd") { + // if (!args.kwargs) { + // args.kwargs = ["dataset_id": meta.id] + // } + // else { + // args.kwargs["dataset_id"] = meta.id + // } - args.kwargs["fullres_image_file"] = fullres_image_file - } + // args.kwargs["fullres_image_file"] = fullres_image_file + // } return ArgsCLI(args) } def ArgsExplorerRaw(Map params, String raw_data_path) { - def args = deepCopyCollection(params.explorer ?: [:]) + def args = [ + pixel_size: params.pixel_size, + ram_threshold_gb: params.ram_threshold_gb, + lazy: params.get('lazy', null), + ] - if (params.read.technology == "xenium") { + if (params.technology == "xenium") { args["raw_data_path"] = raw_data_path } - return ArgsCLI(args) -} + println(args) + println(ArgsCLI(args)) -def deepCopyCollection(object) { - if (object instanceof Map) { - object.collectEntries { key, value -> - [key, deepCopyCollection(value)] - } - } - else if (object instanceof List) { - object.collect { item -> - deepCopyCollection(item) - } - } - else { - object - } + return ArgsCLI(args) } diff --git a/nextflow_schema.json b/nextflow_schema.json index 50f1a3c..5204c7d 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -249,12 +249,12 @@ "default": true }, "min_transcripts": { - "type": "string", - "default": "0" + "type": "number", + "default": 0 }, "min_intensity_ratio": { - "type": "string", - "default": "0" + "type": "number", + "default": 0 }, "expand_radius_ratio": { "type": "string", diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index 93dcdaf..868e03b 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -8,15 +8,15 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' -include { paramsSummaryMap } from 'plugin/nf-schema' -include { samplesheetToList } from 'plugin/nf-schema' -include { paramsHelp } from 'plugin/nf-schema' -include { completionEmail } from '../../nf-core/utils_nfcore_pipeline' -include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' -include { imNotification } from '../../nf-core/utils_nfcore_pipeline' -include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' -include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' +include { completionEmail } from '../../nf-core/utils_nfcore_pipeline' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +include { imNotification } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -30,11 +30,11 @@ workflow PIPELINE_INITIALISATION { validate_params // boolean: Boolean whether to validate parameters against the schema at runtime monochrome_logs // boolean: Do not use coloured log outputs nextflow_cli_args // array: List of positional nextflow CLI args - outdir // string: The output directory where the results will be saved - input // string: Path to input samplesheet - help // boolean: Display help message and exit - help_full // boolean: Show the full help message - show_hidden // boolean: Show hidden parameters in the help message + outdir // string: The output directory where the results will be saved + input // string: Path to input samplesheet + help // boolean: Display help message and exit + help_full // boolean: Show the full help message + show_hidden // boolean: Show hidden parameters in the help message main: @@ -63,7 +63,7 @@ workflow PIPELINE_INITIALISATION { \033[0;35m nf-core/sopa ${workflow.manifest.version}\033[0m -\033[2m----------------------------------------------------\033[0m- """ - after_text = """${workflow.manifest.doi ? "\n* The pipeline\n" : ""}${workflow.manifest.doi.tokenize(",").collect { " https://doi.org/${it.trim().replace('https://doi.org/','')}"}.join("\n")}${workflow.manifest.doi ? "\n" : ""} + after_text = """${workflow.manifest.doi ? "\n* The pipeline\n" : ""}${workflow.manifest.doi.tokenize(",").collect { " https://doi.org/${it.trim().replace('https://doi.org/', '')}" }.join("\n")}${workflow.manifest.doi ? "\n" : ""} * The nf-core framework https://doi.org/10.1038/s41587-020-0439-x @@ -72,7 +72,7 @@ workflow PIPELINE_INITIALISATION { """ command = "nextflow run ${workflow.manifest.name} -profile --input samplesheet.csv --outdir " - UTILS_NFSCHEMA_PLUGIN ( + UTILS_NFSCHEMA_PLUGIN( workflow, validate_params, null, @@ -81,7 +81,7 @@ workflow PIPELINE_INITIALISATION { show_hidden, before_text, after_text, - command + command, ) // @@ -95,7 +95,8 @@ workflow PIPELINE_INITIALISATION { // Create channel from input file provided through params.input // - Channel.fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + Channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) .map { meta, data_path -> if (!meta.fastq_dir) { if (!data_path) { @@ -270,46 +271,46 @@ def methodsDescriptionText(mqc_methods_yaml) { } def validateParams(params) { - def TRANSCRIPT_BASED_METHODS = ['proseg', 'baysor', 'comseg'] - def STAINING_BASED_METHODS = ['stardist', 'cellpose'] - - // top-level checks - assert params.read instanceof Map && params.read.containsKey('technology') : "Provide a 'read.technology' key" - assert params.containsKey('segmentation') : "Provide a 'segmentation' section" - - // backward compatibility - TRANSCRIPT_BASED_METHODS.each { m -> - if (params.segmentation?.get(m)?.containsKey('cell_key')) { - println("Deprecated 'cell_key' → using 'prior_shapes_key' instead.") - params.segmentation[m].prior_shapes_key = params.segmentation[m].cell_key - params.segmentation[m].remove('cell_key') - } - } - if (params.aggregate?.containsKey('average_intensities')) { - println("Deprecated 'average_intensities' → using 'aggregate_channels' instead.") - params.aggregate.aggregate_channels = params.aggregate.average_intensities - params.aggregate.remove('average_intensities') - } - - // check segmentation methods - assert params.segmentation : "Provide at least one segmentation method" - assert TRANSCRIPT_BASED_METHODS.count { params.segmentation.containsKey(it) } <= 1 : "Only one of ${TRANSCRIPT_BASED_METHODS} may be used" - assert STAINING_BASED_METHODS.count { params.segmentation.containsKey(it) } <= 1 : "Only one of ${STAINING_BASED_METHODS} may be used" - if (params.segmentation.containsKey('stardist')) { - assert TRANSCRIPT_BASED_METHODS.every { !params.segmentation.containsKey(it) } : "'stardist' cannot be combined with transcript-based methods" - } - - // check prior shapes key - TRANSCRIPT_BASED_METHODS.each { m -> - if (params.segmentation.containsKey(m) && params.segmentation.containsKey('cellpose')) { - params.segmentation[m].prior_shapes_key = 'cellpose_boundaries' - } - } - - // check annotation method - if (params.annotation && params.annotation.method == "tangram") { - assert params.annotation.args.containsKey('sc_reference_path') : "Provide 'annotation.args.sc_reference_path' for the tangram annotation method" - } + // def TRANSCRIPT_BASED_METHODS = ['proseg', 'baysor', 'comseg'] + // def STAINING_BASED_METHODS = ['stardist', 'cellpose'] + + // // top-level checks + // assert params.read instanceof Map && params.read.containsKey('technology') : "Provide a 'read.technology' key" + // assert params.containsKey('segmentation') : "Provide a 'segmentation' section" + + // // backward compatibility + // TRANSCRIPT_BASED_METHODS.each { m -> + // if (params.segmentation?.get(m)?.containsKey('cell_key')) { + // println("Deprecated 'cell_key' → using 'prior_shapes_key' instead.") + // params.segmentation[m].prior_shapes_key = params.segmentation[m].cell_key + // params.segmentation[m].remove('cell_key') + // } + // } + // if (params.aggregate?.containsKey('average_intensities')) { + // println("Deprecated 'average_intensities' → using 'aggregate_channels' instead.") + // params.aggregate.aggregate_channels = params.aggregate.average_intensities + // params.aggregate.remove('average_intensities') + // } + + // // check segmentation methods + // assert params.segmentation : "Provide at least one segmentation method" + // assert TRANSCRIPT_BASED_METHODS.count { params.segmentation.containsKey(it) } <= 1 : "Only one of ${TRANSCRIPT_BASED_METHODS} may be used" + // assert STAINING_BASED_METHODS.count { params.segmentation.containsKey(it) } <= 1 : "Only one of ${STAINING_BASED_METHODS} may be used" + // if (params.segmentation.containsKey('stardist')) { + // assert TRANSCRIPT_BASED_METHODS.every { !params.segmentation.containsKey(it) } : "'stardist' cannot be combined with transcript-based methods" + // } + + // // check prior shapes key + // TRANSCRIPT_BASED_METHODS.each { m -> + // if (params.segmentation.containsKey(m) && params.segmentation.containsKey('cellpose')) { + // params.segmentation[m].prior_shapes_key = 'cellpose_boundaries' + // } + // } + + // // check annotation method + // if (params.annotation && params.annotation.method == "tangram") { + // assert params.annotation.args.containsKey('sc_reference_path') : "Provide 'annotation.args.sc_reference_path' for the tangram annotation method" + // } return params } diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 33c20e4..c2ba3ee 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -43,7 +43,7 @@ workflow SOPA { ch_versions = Channel.empty() - if (params.read.technology == "visium_hd") { + if (params.technology == "visium_hd") { (ch_input_spatialdata, versions) = SPACERANGER(ch_samplesheet) ch_input_spatialdata = ch_input_spatialdata.map { meta, out -> [meta, out[0].toString().replaceFirst(/(.*?outs).*/, '$1'), meta.image] } @@ -56,85 +56,85 @@ workflow SOPA { (ch_spatialdata, versions) = TO_SPATIALDATA(ch_input_spatialdata) ch_versions = ch_versions.mix(versions) - ch_explorer_raw = ch_spatialdata.map { meta, sdata_path -> [meta, sdata_path, params.read.technology == "xenium" ? meta.data_dir : []] } + ch_explorer_raw = ch_spatialdata.map { meta, sdata_path -> [meta, sdata_path, params.technology == "xenium" ? meta.data_dir : []] } EXPLORER_RAW(ch_explorer_raw) - if (params.segmentation.tissue) { - (ch_tissue_seg, _out) = TISSUE_SEGMENTATION(ch_spatialdata, ArgsCLI(params.segmentation.tissue)) - } - else { - ch_tissue_seg = ch_spatialdata - } + // if (params.segmentation.tissue) { + // (ch_tissue_seg, _out) = TISSUE_SEGMENTATION(ch_spatialdata, ArgsCLI(params.segmentation.tissue)) + // } + // else { + // ch_tissue_seg = ch_spatialdata + // } - if (params.segmentation.cellpose) { - (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(params.patchify, "pixel")) - (ch_resolved, versions) = CELLPOSE(ch_image_patches, params) + // if (params.segmentation.cellpose) { + // (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(params.patchify, "pixel")) + // (ch_resolved, versions) = CELLPOSE(ch_image_patches, params) - ch_versions = ch_versions.mix(versions) - } + // ch_versions = ch_versions.mix(versions) + // } - if (params.segmentation.stardist) { - (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(params.patchify, "pixel")) - (ch_resolved, versions) = STARDIST(ch_image_patches, params) + // if (params.segmentation.stardist) { + // (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(params.patchify, "pixel")) + // (ch_resolved, versions) = STARDIST(ch_image_patches, params) - ch_versions = ch_versions.mix(versions) - } + // ch_versions = ch_versions.mix(versions) + // } - if (params.segmentation.baysor) { - ch_input_baysor = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg + // if (params.segmentation.baysor) { + // ch_input_baysor = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg - ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_baysor, transcriptPatchesArgs(params, "baysor")) - (ch_resolved, versions) = BAYSOR(ch_transcripts_patches, params) + // ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_baysor, transcriptPatchesArgs(params, "baysor")) + // (ch_resolved, versions) = BAYSOR(ch_transcripts_patches, params) - ch_versions = ch_versions.mix(versions) - } + // ch_versions = ch_versions.mix(versions) + // } - if (params.segmentation.comseg) { - ch_input_comseg = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg + // if (params.segmentation.comseg) { + // ch_input_comseg = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg - ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_comseg, transcriptPatchesArgs(params, "comseg")) - (ch_resolved, versions) = COMSEG(ch_transcripts_patches, params) + // ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_comseg, transcriptPatchesArgs(params, "comseg")) + // (ch_resolved, versions) = COMSEG(ch_transcripts_patches, params) - ch_versions = ch_versions.mix(versions) - } + // ch_versions = ch_versions.mix(versions) + // } - if (params.segmentation.proseg) { - ch_input_proseg = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg + // if (params.use_proseg) { + // ch_input_proseg = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg - ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, transcriptPatchesArgs(params, "proseg")) - (ch_resolved, versions) = PROSEG(ch_proseg_patches, params) + // ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, transcriptPatchesArgs(params, "proseg")) + // (ch_resolved, versions) = PROSEG(ch_proseg_patches, params) - ch_versions = ch_versions.mix(versions) - } + // ch_versions = ch_versions.mix(versions) + // } - (ch_aggregated, _out) = AGGREGATE(ch_resolved, ArgsCLI(params.aggregate)) + // (ch_aggregated, _out) = AGGREGATE(ch_resolved, ArgsCLI(params.aggregate)) - if (params.annotation && params.annotation.method == "tangram") { - sc_reference = file(params.annotation.args.sc_reference_path) - params.annotation.args.remove('sc_reference_path') + // if (params.annotation && params.annotation.method == "tangram") { + // sc_reference = file(params.annotation.args.sc_reference_path) + // params.annotation.args.remove('sc_reference_path') - (ch_annotated, _out, versions) = TANGRAM_ANNOTATION(ch_aggregated, sc_reference, ArgsCLI(params.annotation.args)) - ch_versions = ch_versions.mix(versions) - } - else if (params.annotation && params.annotation.method == "fluorescence") { - (ch_annotated, _out, versions) = FLUO_ANNOTATION(ch_aggregated, ArgsCLI(params.annotation.args)) - ch_versions = ch_versions.mix(versions) - } - else { - ch_annotated = ch_aggregated - } + // (ch_annotated, _out, versions) = TANGRAM_ANNOTATION(ch_aggregated, sc_reference, ArgsCLI(params.annotation.args)) + // ch_versions = ch_versions.mix(versions) + // } + // else if (params.annotation && params.annotation.method == "fluorescence") { + // (ch_annotated, _out, versions) = FLUO_ANNOTATION(ch_aggregated, ArgsCLI(params.annotation.args)) + // ch_versions = ch_versions.mix(versions) + // } + // else { + // ch_annotated = ch_aggregated + // } - if (params.scanpy_preprocess) { - (ch_preprocessed, _out, versions) = SCANPY_PREPROCESS(ch_annotated, ArgsCLI(params.scanpy_preprocess)) - ch_versions = ch_versions.mix(versions) - } - else { - ch_preprocessed = ch_annotated - } + // if (params.scanpy_preprocess) { + // (ch_preprocessed, _out, versions) = SCANPY_PREPROCESS(ch_annotated, ArgsCLI(params.scanpy_preprocess)) + // ch_versions = ch_versions.mix(versions) + // } + // else { + // ch_preprocessed = ch_annotated + // } - EXPLORER(ch_preprocessed, ArgsCLI(params.explorer)) + // EXPLORER(ch_preprocessed, ArgsCLI(params.explorer)) - REPORT(ch_preprocessed) + // REPORT(ch_preprocessed) // // Collate and save software versions From 5fd9f4813a1e744fb58379457b1cc8ba61dc3cf7 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 12 Dec 2025 18:21:34 +0100 Subject: [PATCH 204/227] make proseg run --- conf/test.config | 5 +- modules/local/explorer/main.nf | 3 +- modules/local/explorer_raw/main.nf | 4 +- modules/local/to_spatialdata/main.nf | 4 +- modules/local/utils.nf | 108 +++++++--- nextflow.config | 65 +++++- nextflow_schema.json | 88 ++++++++- .../local/utils_nfcore_sopa_pipeline/main.nf | 54 ++--- workflows/sopa.nf | 187 +++++++++--------- 9 files changed, 333 insertions(+), 185 deletions(-) diff --git a/conf/test.config b/conf/test.config index 2eae13b..fb07bba 100644 --- a/conf/test.config +++ b/conf/test.config @@ -27,12 +27,15 @@ params { // Reading technology = "toy_dataset" - convert_kwargs = '{"genes": 500}' + toy_dataset_genes = 500 // Patches patch_width_microns = -1 prior_shapes_key = "auto" + // Proseg segmentation + use_proseg = true + // Aggregation aggregate_channels = true min_transcripts = 5 diff --git a/modules/local/explorer/main.nf b/modules/local/explorer/main.nf index 307da53..e02ca8a 100644 --- a/modules/local/explorer/main.nf +++ b/modules/local/explorer/main.nf @@ -10,7 +10,6 @@ process EXPLORER { input: tuple val(meta), path(sdata_path) - val cli_arguments output: path "${meta.explorer_dir}/experiment.xenium" @@ -21,6 +20,6 @@ process EXPLORER { script: """ - sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "-it" + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} --mode "-it" """ } diff --git a/modules/local/explorer_raw/main.nf b/modules/local/explorer_raw/main.nf index a844ea6..1ce5e2e 100644 --- a/modules/local/explorer_raw/main.nf +++ b/modules/local/explorer_raw/main.nf @@ -1,4 +1,4 @@ -include { ArgsExplorerRaw } from '../utils' +include { argsExplorerRaw } from '../utils' process EXPLORER_RAW { label "process_high" @@ -19,6 +19,6 @@ process EXPLORER_RAW { script: """ - sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${ArgsExplorerRaw(params, data_dir.toString())} --mode "+it" --no-save-h5ad + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${argsExplorerRaw(data_dir.toString())} --mode "+it" --no-save-h5ad """ } diff --git a/modules/local/to_spatialdata/main.nf b/modules/local/to_spatialdata/main.nf index 9e94dd8..b322c73 100644 --- a/modules/local/to_spatialdata/main.nf +++ b/modules/local/to_spatialdata/main.nf @@ -1,4 +1,4 @@ -include { ArgsToSpatialData } from '../utils' +include { argsToSpatialData } from '../utils' process TO_SPATIALDATA { label "process_high" @@ -17,7 +17,7 @@ process TO_SPATIALDATA { script: """ - sopa convert ${data_dir} --sdata-path ${meta.sdata_dir} ${ArgsToSpatialData(params, meta, fullres_image_file.toString())} + sopa convert ${data_dir} --sdata-path ${meta.sdata_dir} ${argsToSpatialData(meta, fullres_image_file.toString())} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/local/utils.nf b/modules/local/utils.nf index d0ac72f..2af0cb5 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -34,50 +34,102 @@ def stringifyValueForCli(value) { return "'${value.toString()}'" } -def ArgsCLI(Map params, String contains = null, List keys = null) { - params = params ?: [:] +def extractSubArgs(Map args, String group) { + if (group == "proseg") { + return [ + command_line_suffix: args.command_line_suffix, + infer_presets: args.infer_presets, + prior_shapes_key: args.visium_hd_prior_shapes_key, + ] + } else if (group == "aggregate") { + return [ + aggregate_genes: args.aggregate_genes, + aggregate_channels: args.aggregate_channels, + min_transcripts: args.min_transcripts, + min_intensity_ratio: args.min_intensity_ratio, + expand_radius_ratio: args.expand_radius_ratio, + ] + } else if (group == "tissue_segmentation") { + return [ + level: args.level, + mode: args.mode, + ] + } else if (group == "transcript_patches") { + return [ + prior_shapes_key: args.prior_shapes_key, + unassigned_value: args.unassigned_value, + patch_width_microns: args.patch_width_microns, + patch_overlap_microns: args.patch_overlap_microns + ] + } else if (group == "image_patches") { + return [ + patch_width_pixels: args.patch_width_pixels, + patch_overlap_pixels: args.patch_overlap_pixels + ] + } else if (group == "tangram") { + return [ + sc_reference_path: args.sc_reference_path, + cell_type_key: args.cell_type_key, + reference_preprocessing: args.reference_preprocessing + ] + } else if (group == "scanpy_preprocessing") { + return [ + check_counts: args.check_counts, + resolution: args.resolution, + hvg: args.hvg, + ] + } else if (group == "explorer_raw") { + return [ + pixel_size: args.pixel_size, + ram_threshold_gb: args.ram_threshold_gb, + lazy: args.lazy, + ] + } else { + exit 1, "Unknown argument group: ${group}" + } +} + +def argsCLI(Map args = null, String group = null) { + args = args ?: params - return params - .findAll { key, _value -> - (contains == null || key.contains(contains)) && (keys == null || key in keys) && (_value != null) - } + if (group != null) { + args = extractSubArgs(args, group) + } + + return args + .findAll { _key, _value -> _value != null } .collect { key, value -> stringifyItem(key, value) } .join(" ") } -def ArgsToSpatialData(Map params, Map meta, String fullres_image_file) { +def argsToSpatialData(Map meta, String fullres_image_file) { def args = [ technology: params.technology, - kwargs: params.convert_kwargs, + kwargs: [:], ] - // if (args.technology == "visium_hd") { - // if (!args.kwargs) { - // args.kwargs = ["dataset_id": meta.id] - // } - // else { - // args.kwargs["dataset_id"] = meta.id - // } + if (params.toy_dataset_genes != null) { + args.kwargs['genes'] = params.toy_dataset_genes + } + + if (params.visium_hd_imread_page != null) { + args.kwargs['imread_kwargs'] = ["page": params.visium_hd_imread_page] + } - // args.kwargs["fullres_image_file"] = fullres_image_file - // } + if (params.technology == "visium_hd") { + args.kwargs["dataset_id"] = meta.id + args.kwargs["fullres_image_file"] = fullres_image_file + } - return ArgsCLI(args) + return argsCLI(args) } -def ArgsExplorerRaw(Map params, String raw_data_path) { - def args = [ - pixel_size: params.pixel_size, - ram_threshold_gb: params.ram_threshold_gb, - lazy: params.get('lazy', null), - ] +def argsExplorerRaw(String raw_data_path) { + def args = extractSubArgs(params, "explorer_raw") if (params.technology == "xenium") { args["raw_data_path"] = raw_data_path } - println(args) - println(ArgsCLI(args)) - - return ArgsCLI(args) + return argsCLI(args) } diff --git a/nextflow.config b/nextflow.config index 2050bd0..0b80918 100644 --- a/nextflow.config +++ b/nextflow.config @@ -11,13 +11,64 @@ params { // Input options input = null - read = null - segmentation = null - patchify = null - aggregate = null - annotation = null - scanpy_preprocess = null - explorer = null + + // Reader options + technology = null + toy_dataset_genes = null + visium_hd_imread_page = null + + // Patchify options + patch_width_pixel = null + patch_overlap_pixel = null + patch_width_microns = null + patch_overlap_microns = null + prior_shapes_key = null + unassigned_value = null + + // Tissue segmentation options + use_tissue_segmentation = false + + // Proseg segmentation options + use_proseg = false + command_line_suffix = "" + infer_presets = null + visium_hd_prior_shapes_key = null + + // Comseg segmentation options + use_comseg = false + + // Baysor segmentation options + use_baysor = false + + // Cellpose segmentation options + use_cellpose = false + + // Stardist segmentation options + use_stardist = false + + // Tangram options + use_tangram = false + sc_reference_path = null + cell_type_key = null + reference_preprocessing = null + + // Aggregation options + aggregate_genes = null + aggregate_channels = null + min_transcripts = null + min_intensity_ratio = null + expand_radius_ratio = null + + // Scanpy preprocessing + use_scanpy_preprocessing = false + resolution = null + check_counts = false + hvg = null + + // Explorer options + ram_threshold_gb = null + pixel_size = null + lazy = null // Spaceranger options spaceranger_reference = "https://cf.10xgenomics.com/supp/spatial-exp/refdata-gex-GRCh38-2020-A.tar.gz" diff --git a/nextflow_schema.json b/nextflow_schema.json index 5204c7d..77b1a7c 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -203,10 +203,27 @@ "properties": { "technology": { "type": "string", - "description": "Technology used for the spatial data, e.g., 'xenium', 'merscope', ..." + "description": "Technology used for the spatial data, e.g., 'xenium', 'merscope', ...", + "enum": [ + "xenium", + "merscope", + "cosmx", + "visium_hd", + "molecular_cartography", + "macsima", + "phenocycler", + "hyperion", + "ome_tif", + "toy_dataset" + ] + }, + "visium_hd_imread_page": { + "type": "number", + "description": "Optional page for the imageio reader" }, - "convert_kwargs": { - "type": "string" + "toy_dataset_genes": { + "type": "number", + "description": "Used on toy dataset for testing purpose" } }, "required": ["technology"] @@ -231,6 +248,31 @@ }, "prior_shapes_key": { "type": "string" + }, + "unassigned_value": { + "type": "string" + } + } + }, + "tissue_segmentation": { + "title": "Tissue segmentation", + "type": "object", + "description": "Parameters related to tissue segmentation", + "default": "", + "properties": { + "use_tissue_segmentation": { + "type": "boolean", + "description": "Whether to run tissue segmentation", + "default": false + }, + "level": { + "type": "number", + "description": "Level of the image pyramid to use for tissue segmentation" + }, + "mode": { + "type": "string", + "description": "Mode for the tissue segmentation: 'staining' or 'saturation' (for H&E images).", + "enum": ["staining", "saturation"] } } }, @@ -270,7 +312,8 @@ "properties": { "use_scanpy_preprocessing": { "type": "boolean", - "description": "Whether to run scanpy preprocessing" + "description": "Whether to run scanpy preprocessing", + "default": false }, "resolution": { "type": "number", @@ -318,7 +361,33 @@ "properties": { "use_proseg": { "type": "boolean", - "description": "Whether to run proseg segmentation" + "description": "Whether to run proseg segmentation", + "default": false + }, + "command_line_suffix": { + "type": "string", + "description": "String suffix to add to the proseg command line. This can be used to add extra parameters to the proseg command line." + }, + "infer_presets": { + "type": "boolean", + "description": "Whether to infer the proseg presets based on the columns of the transcripts dataframe." + }, + "visium_hd_prior_shapes_key": { + "type": "string", + "description": "**Only for Visium HD data.** Key of `sdata` containing the prior cell boundaries. If `'auto'`, use the latest performed segmentation (e.g., stardist or the 10X Genomics segmentation)." + } + } + }, + "comseg": { + "title": "Comseg", + "type": "object", + "description": "", + "default": "", + "properties": { + "use_comseg": { + "type": "boolean", + "description": "Whether to run comseg segmentation", + "default": false } } }, @@ -330,7 +399,8 @@ "properties": { "use_tangram": { "type": "boolean", - "description": "Whether to run tangram cell-type annotation" + "description": "Whether to run tangram cell-type annotation", + "default": false }, "sc_reference_path": { "type": "string", @@ -378,6 +448,12 @@ { "$ref": "#/$defs/proseg" }, + { + "$ref": "#/$defs/tissue_segmentation" + }, + { + "$ref": "#/$defs/comseg" + }, { "$ref": "#/$defs/tangram" } diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index 868e03b..2d28876 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -271,46 +271,20 @@ def methodsDescriptionText(mqc_methods_yaml) { } def validateParams(params) { - // def TRANSCRIPT_BASED_METHODS = ['proseg', 'baysor', 'comseg'] - // def STAINING_BASED_METHODS = ['stardist', 'cellpose'] - - // // top-level checks - // assert params.read instanceof Map && params.read.containsKey('technology') : "Provide a 'read.technology' key" - // assert params.containsKey('segmentation') : "Provide a 'segmentation' section" - - // // backward compatibility - // TRANSCRIPT_BASED_METHODS.each { m -> - // if (params.segmentation?.get(m)?.containsKey('cell_key')) { - // println("Deprecated 'cell_key' → using 'prior_shapes_key' instead.") - // params.segmentation[m].prior_shapes_key = params.segmentation[m].cell_key - // params.segmentation[m].remove('cell_key') - // } - // } - // if (params.aggregate?.containsKey('average_intensities')) { - // println("Deprecated 'average_intensities' → using 'aggregate_channels' instead.") - // params.aggregate.aggregate_channels = params.aggregate.average_intensities - // params.aggregate.remove('average_intensities') - // } - - // // check segmentation methods - // assert params.segmentation : "Provide at least one segmentation method" - // assert TRANSCRIPT_BASED_METHODS.count { params.segmentation.containsKey(it) } <= 1 : "Only one of ${TRANSCRIPT_BASED_METHODS} may be used" - // assert STAINING_BASED_METHODS.count { params.segmentation.containsKey(it) } <= 1 : "Only one of ${STAINING_BASED_METHODS} may be used" - // if (params.segmentation.containsKey('stardist')) { - // assert TRANSCRIPT_BASED_METHODS.every { !params.segmentation.containsKey(it) } : "'stardist' cannot be combined with transcript-based methods" - // } - - // // check prior shapes key - // TRANSCRIPT_BASED_METHODS.each { m -> - // if (params.segmentation.containsKey(m) && params.segmentation.containsKey('cellpose')) { - // params.segmentation[m].prior_shapes_key = 'cellpose_boundaries' - // } - // } - - // // check annotation method - // if (params.annotation && params.annotation.method == "tangram") { - // assert params.annotation.args.containsKey('sc_reference_path') : "Provide 'annotation.args.sc_reference_path' for the tangram annotation method" - // } + def TRANSCRIPT_BASED_METHODS = ['use_proseg', 'use_baysor', 'use_comseg'] + def STAINING_BASED_METHODS = ['use_stardist', 'use_cellpose'] + + // check segmentation methods + assert TRANSCRIPT_BASED_METHODS.count { params[it] } <= 1 : "Only one of ${TRANSCRIPT_BASED_METHODS} may be used" + assert STAINING_BASED_METHODS.count { params[it] } <= 1 : "Only one of ${STAINING_BASED_METHODS} may be used" + if (params.use_stardist) { + assert TRANSCRIPT_BASED_METHODS.every { !params[it] } : "'stardist' cannot be combined with transcript-based methods" + } + + // check prior shapes key + if (params.use_cellpose) { + params.prior_shapes_key = "cellpose_boundaries" + } return params } diff --git a/workflows/sopa.nf b/workflows/sopa.nf index c2ba3ee..e2936ca 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -28,7 +28,7 @@ include { REPORT } from '../modules/local/report' include { TANGRAM_ANNOTATION } from '../modules/local/tangram_annotation' include { FLUO_ANNOTATION } from '../modules/local/fluo_annotation' include { SPACERANGER } from '../subworkflows/local/spaceranger' -include { ArgsCLI } from '../modules/local/utils' +include { argsCLI } from '../modules/local/utils' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -59,82 +59,81 @@ workflow SOPA { ch_explorer_raw = ch_spatialdata.map { meta, sdata_path -> [meta, sdata_path, params.technology == "xenium" ? meta.data_dir : []] } EXPLORER_RAW(ch_explorer_raw) - // if (params.segmentation.tissue) { - // (ch_tissue_seg, _out) = TISSUE_SEGMENTATION(ch_spatialdata, ArgsCLI(params.segmentation.tissue)) - // } - // else { - // ch_tissue_seg = ch_spatialdata - // } + if (params.use_tissue_segmentation) { + (ch_tissue_seg, _out) = TISSUE_SEGMENTATION(ch_spatialdata, argsCLI(null, "tissue_segmentation")) + } + else { + ch_tissue_seg = ch_spatialdata + } - // if (params.segmentation.cellpose) { - // (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(params.patchify, "pixel")) - // (ch_resolved, versions) = CELLPOSE(ch_image_patches, params) + if (params.use_cellpose) { + (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, argsCLI(null, "image_patches")) + (ch_resolved, versions) = CELLPOSE(ch_image_patches, params) - // ch_versions = ch_versions.mix(versions) - // } + ch_versions = ch_versions.mix(versions) + } - // if (params.segmentation.stardist) { - // (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, ArgsCLI(params.patchify, "pixel")) - // (ch_resolved, versions) = STARDIST(ch_image_patches, params) + if (params.use_stardist) { + (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, argsCLI(null, "image_patches")) + (ch_resolved, versions) = STARDIST(ch_image_patches, params) - // ch_versions = ch_versions.mix(versions) - // } + ch_versions = ch_versions.mix(versions) + } - // if (params.segmentation.baysor) { - // ch_input_baysor = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg + if (params.use_baysor) { + ch_input_baysor = params.use_cellpose ? ch_resolved : ch_tissue_seg - // ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_baysor, transcriptPatchesArgs(params, "baysor")) - // (ch_resolved, versions) = BAYSOR(ch_transcripts_patches, params) + ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_baysor, argsCLI(null, "transcript_patches")) + (ch_resolved, versions) = BAYSOR(ch_transcripts_patches, params) - // ch_versions = ch_versions.mix(versions) - // } + ch_versions = ch_versions.mix(versions) + } - // if (params.segmentation.comseg) { - // ch_input_comseg = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg + if (params.use_comseg) { + ch_input_comseg = params.use_cellpose ? ch_resolved : ch_tissue_seg - // ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_comseg, transcriptPatchesArgs(params, "comseg")) - // (ch_resolved, versions) = COMSEG(ch_transcripts_patches, params) + ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_comseg, argsCLI(null, "transcript_patches") + " --write-cells-centroids ") + (ch_resolved, versions) = COMSEG(ch_transcripts_patches, params) - // ch_versions = ch_versions.mix(versions) - // } + ch_versions = ch_versions.mix(versions) + } - // if (params.use_proseg) { - // ch_input_proseg = params.segmentation.cellpose ? ch_resolved : ch_tissue_seg + if (params.use_proseg) { + ch_input_proseg = params.use_cellpose ? ch_resolved : ch_tissue_seg - // ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, transcriptPatchesArgs(params, "proseg")) - // (ch_resolved, versions) = PROSEG(ch_proseg_patches, params) + ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, argsCLI(null, "transcript_patches")) + (ch_resolved, versions) = PROSEG(ch_proseg_patches) - // ch_versions = ch_versions.mix(versions) - // } + ch_versions = ch_versions.mix(versions) + } - // (ch_aggregated, _out) = AGGREGATE(ch_resolved, ArgsCLI(params.aggregate)) + (ch_aggregated, _out) = AGGREGATE(ch_resolved, argsCLI(null, "aggregate")) - // if (params.annotation && params.annotation.method == "tangram") { - // sc_reference = file(params.annotation.args.sc_reference_path) - // params.annotation.args.remove('sc_reference_path') + if (params.use_tangram) { + sc_reference = file(params.sc_reference_path) - // (ch_annotated, _out, versions) = TANGRAM_ANNOTATION(ch_aggregated, sc_reference, ArgsCLI(params.annotation.args)) - // ch_versions = ch_versions.mix(versions) - // } + (ch_annotated, _out, versions) = TANGRAM_ANNOTATION(ch_aggregated, sc_reference, argsCLI(null, "tangram")) + ch_versions = ch_versions.mix(versions) + } // else if (params.annotation && params.annotation.method == "fluorescence") { - // (ch_annotated, _out, versions) = FLUO_ANNOTATION(ch_aggregated, ArgsCLI(params.annotation.args)) + // (ch_annotated, _out, versions) = FLUO_ANNOTATION(ch_aggregated, argsCLI(params.annotation.args)) // ch_versions = ch_versions.mix(versions) // } - // else { - // ch_annotated = ch_aggregated - // } + else { + ch_annotated = ch_aggregated + } - // if (params.scanpy_preprocess) { - // (ch_preprocessed, _out, versions) = SCANPY_PREPROCESS(ch_annotated, ArgsCLI(params.scanpy_preprocess)) - // ch_versions = ch_versions.mix(versions) - // } - // else { - // ch_preprocessed = ch_annotated - // } + if (params.use_scanpy_preprocessing) { + (ch_preprocessed, _out, versions) = SCANPY_PREPROCESS(ch_annotated, argsCLI(null, "scanpy_preprocessing")) + ch_versions = ch_versions.mix(versions) + } + else { + ch_preprocessed = ch_annotated + } - // EXPLORER(ch_preprocessed, ArgsCLI(params.explorer)) + EXPLORER(ch_preprocessed) - // REPORT(ch_preprocessed) + REPORT(ch_preprocessed) // // Collate and save software versions @@ -164,7 +163,7 @@ workflow CELLPOSE { main: ch_versions = Channel.empty() - cellpose_args = ArgsCLI(config.segmentation.cellpose) + cellpose_args = argsCLI(config.segmentation.cellpose) ch_patches .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } @@ -190,7 +189,7 @@ workflow STARDIST { main: ch_versions = Channel.empty() - stardist_args = ArgsCLI(config.segmentation.stardist) + stardist_args = argsCLI(config.segmentation.stardist) ch_patches .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } @@ -208,25 +207,6 @@ workflow STARDIST { ch_versions } -workflow PROSEG { - take: - ch_patches - config - - main: - ch_versions = Channel.empty() - - proseg_args = ArgsCLI(config.segmentation.proseg, null, ["command_line_suffix"]) - - (ch_segmented, _out, versions) = PATCH_SEGMENTATION_PROSEG(ch_patches, proseg_args) - - ch_versions = ch_versions.mix(versions) - - emit: - ch_segmented - ch_versions -} - workflow BAYSOR { take: @@ -236,7 +216,7 @@ workflow BAYSOR { main: ch_versions = Channel.empty() - baysor_args = ArgsCLI(config.segmentation.baysor, null, ["config"]) + baysor_args = argsCLI(config.segmentation.baysor, null, ["config"]) ch_patches .map { meta, sdata_path, patches_file_transcripts, _patches -> [meta, sdata_path, patches_file_transcripts.splitText()] } @@ -245,7 +225,7 @@ workflow BAYSOR { ch_segmented = PATCH_SEGMENTATION_BAYSOR(ch_baysor).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - (ch_resolved, _out, versions) = RESOLVE_BAYSOR(ch_segmented, resolveArgs(config)) + (ch_resolved, _out, versions) = RESOLVE_BAYSOR(ch_segmented, resolveArgs()) ch_versions = ch_versions.mix(versions) @@ -262,7 +242,7 @@ workflow COMSEG { main: ch_versions = Channel.empty() - comseg_args = ArgsCLI(config.segmentation.comseg, null, ["config"]) + comseg_args = argsCLI(config.segmentation.comseg, null, ["config"]) ch_patches .map { meta, sdata_path, patches_file_transcripts, _patches -> [meta, sdata_path, patches_file_transcripts.splitText()] } @@ -271,7 +251,7 @@ workflow COMSEG { ch_segmented = PATCH_SEGMENTATION_COMSEG(ch_comseg).map { meta, sdata_path, _out1, _out2, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - (ch_resolved, _out, versions) = RESOLVE_COMSEG(ch_segmented, resolveArgs(config)) + (ch_resolved, _out, versions) = RESOLVE_COMSEG(ch_segmented, resolveArgs()) ch_versions = ch_versions.mix(versions) @@ -280,27 +260,40 @@ workflow COMSEG { ch_versions } -def transcriptPatchesArgs(Map config, String method) { - def prior_args = ArgsCLI(config.segmentation[method], null, ["prior_shapes_key", "unassigned_value"]) - return ArgsCLI(config.patchify, "micron") + ("comseg" in config.segmentation ? " --write-cells-centroids " : " ") + prior_args -} - -def resolveArgs(Map config) { +def resolveArgs() { def gene_column def min_area - if ("comseg" in config.segmentation) { - gene_column = config.segmentation.comseg.config.gene_column - min_area = config.segmentation.comseg.min_area ?: 0 - } - else if ("baysor" in config.segmentation) { - gene_column = config.segmentation.baysor.config.data.gene - min_area = config.segmentation.baysor.min_area ?: 0 - } - else { - throw new IllegalArgumentException("Unknown segmentation method in config for resolveArgs") - } + // if (params.use_comseg) { + // gene_column = config.segmentation.comseg.config.gene_column + // min_area = config.segmentation.comseg.min_area ?: 0 + // } + // else if (params.use_baysor) { + // gene_column = config.segmentation.baysor.config.data.gene + // min_area = config.segmentation.baysor.min_area ?: 0 + // } + // else { + // throw new IllegalArgumentException("Unknown segmentation method in config for resolveArgs") + // } return "--gene-column ${gene_column} --min-area ${min_area}" } + +workflow PROSEG { + take: + ch_patches + + main: + ch_versions = Channel.empty() + + proseg_args = argsCLI(null, "proseg") + + (ch_segmented, _out, versions) = PATCH_SEGMENTATION_PROSEG(ch_patches, proseg_args) + + ch_versions = ch_versions.mix(versions) + + emit: + ch_segmented + ch_versions +} From 2fa432bfd0713483767d1864c042f0a43650de8c Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 12 Dec 2025 18:52:55 +0100 Subject: [PATCH 205/227] fix and cleanup --- conf/test.config | 1 - modules/local/explorer/main.nf | 3 +- modules/local/utils.nf | 22 ++++++++++---- nextflow.config | 1 - nextflow_schema.json | 4 --- workflows/sopa.nf | 55 ++++++++++++++++------------------ 6 files changed, 45 insertions(+), 41 deletions(-) diff --git a/conf/test.config b/conf/test.config index fb07bba..aeba8af 100644 --- a/conf/test.config +++ b/conf/test.config @@ -27,7 +27,6 @@ params { // Reading technology = "toy_dataset" - toy_dataset_genes = 500 // Patches patch_width_microns = -1 diff --git a/modules/local/explorer/main.nf b/modules/local/explorer/main.nf index e02ca8a..307da53 100644 --- a/modules/local/explorer/main.nf +++ b/modules/local/explorer/main.nf @@ -10,6 +10,7 @@ process EXPLORER { input: tuple val(meta), path(sdata_path) + val cli_arguments output: path "${meta.explorer_dir}/experiment.xenium" @@ -20,6 +21,6 @@ process EXPLORER { script: """ - sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} --mode "-it" + sopa explorer write ${sdata_path} --output-path ${meta.explorer_dir} ${cli_arguments} --mode "-it" """ } diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 2af0cb5..4c5b4b2 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -41,6 +41,18 @@ def extractSubArgs(Map args, String group) { infer_presets: args.infer_presets, prior_shapes_key: args.visium_hd_prior_shapes_key, ] + } else if (group == "cellpose") { + return [ // TODO + ] + } else if (group == "baysor") { + return [ // TODO + ] + } else if (group == "comseg") { + return [ // TODO + ] + } else if (group == "stardist") { + return [ // TODO + ] } else if (group == "aggregate") { return [ aggregate_genes: args.aggregate_genes, @@ -78,7 +90,7 @@ def extractSubArgs(Map args, String group) { resolution: args.resolution, hvg: args.hvg, ] - } else if (group == "explorer_raw") { + } else if (group == "explorer") { return [ pixel_size: args.pixel_size, ram_threshold_gb: args.ram_threshold_gb, @@ -89,7 +101,7 @@ def extractSubArgs(Map args, String group) { } } -def argsCLI(Map args = null, String group = null) { +def argsCLI(String group = null, Map args = null) { args = args ?: params if (group != null) { @@ -121,15 +133,15 @@ def argsToSpatialData(Map meta, String fullres_image_file) { args.kwargs["fullres_image_file"] = fullres_image_file } - return argsCLI(args) + return argsCLI(null, args) } def argsExplorerRaw(String raw_data_path) { - def args = extractSubArgs(params, "explorer_raw") + def args = extractSubArgs(params, "explorer") if (params.technology == "xenium") { args["raw_data_path"] = raw_data_path } - return argsCLI(args) + return argsCLI(null, args) } diff --git a/nextflow.config b/nextflow.config index 0b80918..0c6451c 100644 --- a/nextflow.config +++ b/nextflow.config @@ -14,7 +14,6 @@ params { // Reader options technology = null - toy_dataset_genes = null visium_hd_imread_page = null // Patchify options diff --git a/nextflow_schema.json b/nextflow_schema.json index 77b1a7c..9124528 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -220,10 +220,6 @@ "visium_hd_imread_page": { "type": "number", "description": "Optional page for the imageio reader" - }, - "toy_dataset_genes": { - "type": "number", - "description": "Used on toy dataset for testing purpose" } }, "required": ["technology"] diff --git a/workflows/sopa.nf b/workflows/sopa.nf index e2936ca..dda2558 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -41,7 +41,7 @@ workflow SOPA { main: - ch_versions = Channel.empty() + ch_versions = channel.empty() if (params.technology == "visium_hd") { (ch_input_spatialdata, versions) = SPACERANGER(ch_samplesheet) @@ -60,22 +60,22 @@ workflow SOPA { EXPLORER_RAW(ch_explorer_raw) if (params.use_tissue_segmentation) { - (ch_tissue_seg, _out) = TISSUE_SEGMENTATION(ch_spatialdata, argsCLI(null, "tissue_segmentation")) + (ch_tissue_seg, _out) = TISSUE_SEGMENTATION(ch_spatialdata, argsCLI("tissue_segmentation")) } else { ch_tissue_seg = ch_spatialdata } if (params.use_cellpose) { - (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, argsCLI(null, "image_patches")) - (ch_resolved, versions) = CELLPOSE(ch_image_patches, params) + (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, argsCLI("image_patches")) + (ch_resolved, versions) = CELLPOSE(ch_image_patches) ch_versions = ch_versions.mix(versions) } if (params.use_stardist) { - (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, argsCLI(null, "image_patches")) - (ch_resolved, versions) = STARDIST(ch_image_patches, params) + (ch_image_patches, _out) = MAKE_IMAGE_PATCHES(ch_tissue_seg, argsCLI("image_patches")) + (ch_resolved, versions) = STARDIST(ch_image_patches) ch_versions = ch_versions.mix(versions) } @@ -83,8 +83,8 @@ workflow SOPA { if (params.use_baysor) { ch_input_baysor = params.use_cellpose ? ch_resolved : ch_tissue_seg - ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_baysor, argsCLI(null, "transcript_patches")) - (ch_resolved, versions) = BAYSOR(ch_transcripts_patches, params) + ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_baysor, argsCLI("transcript_patches")) + (ch_resolved, versions) = BAYSOR(ch_transcripts_patches) ch_versions = ch_versions.mix(versions) } @@ -92,8 +92,8 @@ workflow SOPA { if (params.use_comseg) { ch_input_comseg = params.use_cellpose ? ch_resolved : ch_tissue_seg - ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_comseg, argsCLI(null, "transcript_patches") + " --write-cells-centroids ") - (ch_resolved, versions) = COMSEG(ch_transcripts_patches, params) + ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_comseg, argsCLI("transcript_patches") + " --write-cells-centroids ") + (ch_resolved, versions) = COMSEG(ch_transcripts_patches) ch_versions = ch_versions.mix(versions) } @@ -101,18 +101,18 @@ workflow SOPA { if (params.use_proseg) { ch_input_proseg = params.use_cellpose ? ch_resolved : ch_tissue_seg - ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, argsCLI(null, "transcript_patches")) + ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, argsCLI("transcript_patches")) (ch_resolved, versions) = PROSEG(ch_proseg_patches) ch_versions = ch_versions.mix(versions) } - (ch_aggregated, _out) = AGGREGATE(ch_resolved, argsCLI(null, "aggregate")) + (ch_aggregated, _out) = AGGREGATE(ch_resolved, argsCLI("aggregate")) if (params.use_tangram) { sc_reference = file(params.sc_reference_path) - (ch_annotated, _out, versions) = TANGRAM_ANNOTATION(ch_aggregated, sc_reference, argsCLI(null, "tangram")) + (ch_annotated, _out, versions) = TANGRAM_ANNOTATION(ch_aggregated, sc_reference, argsCLI("tangram")) ch_versions = ch_versions.mix(versions) } // else if (params.annotation && params.annotation.method == "fluorescence") { @@ -124,14 +124,14 @@ workflow SOPA { } if (params.use_scanpy_preprocessing) { - (ch_preprocessed, _out, versions) = SCANPY_PREPROCESS(ch_annotated, argsCLI(null, "scanpy_preprocessing")) + (ch_preprocessed, _out, versions) = SCANPY_PREPROCESS(ch_annotated, argsCLI("scanpy_preprocessing")) ch_versions = ch_versions.mix(versions) } else { ch_preprocessed = ch_annotated } - EXPLORER(ch_preprocessed) + EXPLORER(ch_preprocessed, argsCLI("explorer")) REPORT(ch_preprocessed) @@ -158,12 +158,11 @@ workflow SOPA { workflow CELLPOSE { take: ch_patches - config main: - ch_versions = Channel.empty() + ch_versions = channel.empty() - cellpose_args = argsCLI(config.segmentation.cellpose) + cellpose_args = argsCLI("cellpose") ch_patches .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } @@ -184,12 +183,11 @@ workflow CELLPOSE { workflow STARDIST { take: ch_patches - config main: - ch_versions = Channel.empty() + ch_versions = channel.empty() - stardist_args = argsCLI(config.segmentation.stardist) + stardist_args = argsCLI("stardist") ch_patches .map { meta, sdata_path, patches_file_image -> [meta, sdata_path, patches_file_image.text.trim().toInteger()] } @@ -211,12 +209,11 @@ workflow STARDIST { workflow BAYSOR { take: ch_patches - config main: - ch_versions = Channel.empty() + ch_versions = channel.empty() - baysor_args = argsCLI(config.segmentation.baysor, null, ["config"]) + baysor_args = argsCLI("baysor") ch_patches .map { meta, sdata_path, patches_file_transcripts, _patches -> [meta, sdata_path, patches_file_transcripts.splitText()] } @@ -237,12 +234,11 @@ workflow BAYSOR { workflow COMSEG { take: ch_patches - config main: - ch_versions = Channel.empty() + ch_versions = channel.empty() - comseg_args = argsCLI(config.segmentation.comseg, null, ["config"]) + comseg_args = argsCLI("comseg") ch_patches .map { meta, sdata_path, patches_file_transcripts, _patches -> [meta, sdata_path, patches_file_transcripts.splitText()] } @@ -265,6 +261,7 @@ def resolveArgs() { def gene_column def min_area + // TODO // if (params.use_comseg) { // gene_column = config.segmentation.comseg.config.gene_column // min_area = config.segmentation.comseg.min_area ?: 0 @@ -285,9 +282,9 @@ workflow PROSEG { ch_patches main: - ch_versions = Channel.empty() + ch_versions = channel.empty() - proseg_args = argsCLI(null, "proseg") + proseg_args = argsCLI("proseg") (ch_segmented, _out, versions) = PATCH_SEGMENTATION_PROSEG(ch_patches, proseg_args) From d1b4569caad8cc42896e0b4d863000dea500ec13 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 18 Dec 2025 14:15:15 +0100 Subject: [PATCH 206/227] add all flat parameters - WIP --- conf/test.config | 13 +- modules/local/utils.nf | 91 ++++-- nextflow.config | 52 +++- nextflow_schema.json | 262 +++++++++++++++++- .../local/utils_nfcore_sopa_pipeline/main.nf | 4 + workflows/sopa.nf | 39 +-- 6 files changed, 387 insertions(+), 74 deletions(-) diff --git a/conf/test.config b/conf/test.config index aeba8af..1a79803 100644 --- a/conf/test.config +++ b/conf/test.config @@ -39,16 +39,9 @@ params { aggregate_channels = true min_transcripts = 5 - // annotation = [ - // method: "fluorescence", - // args: [ - // marker_cell_dict: [ - // CK: "Tumoral cell", - // CD3: "T cell", - // CD20: "B cell", - // ] - // ], - // ] + // Annotation + use_fluorescence_annotation = true + marker_cell_dict = '{"CK": "Tumoral cell", "CD3": "T cell", "CD20": "B cell"}' // Scanpy preprocessing use_scanpy_preprocessing = true diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 4c5b4b2..e24c915 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -42,36 +42,92 @@ def extractSubArgs(Map args, String group) { prior_shapes_key: args.visium_hd_prior_shapes_key, ] } else if (group == "cellpose") { - return [ // TODO + return [ + diameter: args.cellpose_diameter, + channels: args.cellpose_channels, + flow_threshold: args.flow_threshold, + model_type: args.cellpose_model_type, + pretrained_model: args.pretrained_model, + use_gpu: args.cellpose_use_gpu, + min_area: args.min_area, + clip_limit: args.clip_limit, + clahe_kernel_size: args.clahe_kernel_size, + gaussian_sigma: args.gaussian_sigma, + method_kwargs: args.cellpose_kwargs, + ] + } else if (group == "stardist") { + return [ + model_type: args.stardist_model_type, + prob_thresh: args.prob_thresh, + nms_thresh: args.nms_thresh, + channels: args.stardist_channels, + min_area: args.min_area, + clip_limit: args.clip_limit, + clahe_kernel_size: args.clahe_kernel_size, + gaussian_sigma: args.gaussian_sigma, + method_kwargs: args.stardist_kwargs, ] } else if (group == "baysor") { - return [ // TODO + return [ + config: [ + data: [ + x: "x", + y: "y", + z: "z", + force_2d: args.force_2d, + min_molecules_per_cell: args.min_molecules_per_cell, + min_molecules_per_gene: args.min_molecules_per_gene, + min_molecules_per_segment: args.min_molecules_per_segment, + confidence_nn_id: args.confidence_nn_id, + ], + segmentation: [ + scale: args.baysor_scale, + scale_std: args.baysor_scale_std, + prior_segmentation_confidence: args.prior_segmentation_confidence, + ], + ], + min_area: args.min_area, ] } else if (group == "comseg") { - return [ // TODO - ] - } else if (group == "stardist") { - return [ // TODO + return [ + config: [ + dict_scale: [ + x: 1, + y: 1, + z: 1, + ], + allow_disconnected_polygon: args.allow_disconnected_polygon, + norm_vector: args.norm_vector, + mean_cell_diameter: args.mean_cell_diameter, + max_cell_radius: args.max_cell_radius, + alpha: args.alpha, + min_rna_per_cell: args.min_rna_per_cell, + ], + min_area: args.min_area, ] } else if (group == "aggregate") { return [ aggregate_genes: args.aggregate_genes, aggregate_channels: args.aggregate_channels, + expand_radius_ratio: args.expand_radius_ratio, min_transcripts: args.min_transcripts, min_intensity_ratio: args.min_intensity_ratio, - expand_radius_ratio: args.expand_radius_ratio, ] } else if (group == "tissue_segmentation") { return [ level: args.level, mode: args.mode, ] + } else if (group == "resolve") { + return [ + min_area: args.min_area, + ] } else if (group == "transcript_patches") { return [ - prior_shapes_key: args.prior_shapes_key, - unassigned_value: args.unassigned_value, patch_width_microns: args.patch_width_microns, - patch_overlap_microns: args.patch_overlap_microns + patch_overlap_microns: args.patch_overlap_microns, + unassigned_value: args.unassigned_value, + prior_shapes_key: args.prior_shapes_key, ] } else if (group == "image_patches") { return [ @@ -82,12 +138,19 @@ def extractSubArgs(Map args, String group) { return [ sc_reference_path: args.sc_reference_path, cell_type_key: args.cell_type_key, - reference_preprocessing: args.reference_preprocessing + reference_preprocessing: args.reference_preprocessing, + bag_size: args.bag_size, + max_obs_reference: args.max_obs_reference, + ] + } else if (group == "fluorescence_annotation") { + return [ + cell_type_key: args.cell_type_key, + marker_cell_dict: args.marker_cell_dict, ] } else if (group == "scanpy_preprocessing") { return [ - check_counts: args.check_counts, resolution: args.resolution, + check_counts: args.check_counts, hvg: args.hvg, ] } else if (group == "explorer") { @@ -120,10 +183,6 @@ def argsToSpatialData(Map meta, String fullres_image_file) { kwargs: [:], ] - if (params.toy_dataset_genes != null) { - args.kwargs['genes'] = params.toy_dataset_genes - } - if (params.visium_hd_imread_page != null) { args.kwargs['imread_kwargs'] = ["page": params.visium_hd_imread_page] } diff --git a/nextflow.config b/nextflow.config index 0c6451c..7911c00 100644 --- a/nextflow.config +++ b/nextflow.config @@ -13,7 +13,7 @@ params { input = null // Reader options - technology = null + technology = "xenium" visium_hd_imread_page = null // Patchify options @@ -24,6 +24,11 @@ params { prior_shapes_key = null unassigned_value = null + // Image preprocessing options + gaussian_sigma = null + clip_limit = null + clahe_kernel_size = null + // Tissue segmentation options use_tissue_segmentation = false @@ -33,29 +38,66 @@ params { infer_presets = null visium_hd_prior_shapes_key = null + // Baysor segmentation options + use_baysor = false + baysor_scale = null + baysor_scale_std = null + prior_segmentation_confidence = null + min_molecules_per_cell = null + min_molecules_per_gene = null + min_molecules_per_segment = null + confidence_nn_id = null + force_2d = true + // Comseg segmentation options use_comseg = false + mean_cell_diameter = null + max_cell_radius = null + alpha = null + min_rna_per_cell = null + allow_disconnected_polygon = false + norm_vector = false - // Baysor segmentation options - use_baysor = false // Cellpose segmentation options use_cellpose = false + cellpose_diameter = null + cellpose_channels = null + flow_threshold = null + cellpose_model_type = null + pretrained_model = null + cellpose_use_gpu = false + cellpose_kwargs = null // Stardist segmentation options use_stardist = false + stardist_model_type = null + prob_thresh = null + nms_thresh = null + stardist_channels = null + stardist_kwargs = null // Tangram options use_tangram = false sc_reference_path = null cell_type_key = null reference_preprocessing = null + bag_size = null + max_obs_reference = null + + // Fluorescence annotation options + use_fluorescence_annotation = false + cell_type_key = null + marker_cell_dict = null + + // Cell filtering options + min_area = 0 + min_transcripts = null + min_intensity_ratio = null // Aggregation options aggregate_genes = null aggregate_channels = null - min_transcripts = null - min_intensity_ratio = null expand_radius_ratio = null // Scanpy preprocessing diff --git a/nextflow_schema.json b/nextflow_schema.json index 9124528..a9bb3d2 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -215,14 +215,14 @@ "hyperion", "ome_tif", "toy_dataset" - ] + ], + "default": "xenium" }, "visium_hd_imread_page": { "type": "number", "description": "Optional page for the imageio reader" } - }, - "required": ["technology"] + } }, "patches": { "title": "Patches", @@ -272,6 +272,27 @@ } } }, + "filtering": { + "title": "Cell filtering", + "type": "object", + "description": "", + "default": "", + "properties": { + "min_area": { + "type": "number", + "description": "Cells with an area less than this value will be filtered. The unit is in microns^2 for Baysor/Comseg, and in pixels^2 for Stardist/Cellpose. Not used for Proseg.", + "default": 0 + }, + "min_transcripts": { + "type": "number", + "default": 0 + }, + "min_intensity_ratio": { + "type": "number", + "default": 0 + } + } + }, "aggregation": { "title": "Aggregation", "type": "object", @@ -286,14 +307,6 @@ "type": "boolean", "default": true }, - "min_transcripts": { - "type": "number", - "default": 0 - }, - "min_intensity_ratio": { - "type": "number", - "default": 0 - }, "expand_radius_ratio": { "type": "string", "default": "0" @@ -384,6 +397,184 @@ "type": "boolean", "description": "Whether to run comseg segmentation", "default": false + }, + "mean_cell_diameter": { + "type": "number", + "description": "Comseg `mean_cell_diameter` parameter", + "default": 30 + }, + "max_cell_radius": { + "type": "number", + "description": "Comseg `max_cell_radius` parameter", + "default": 15 + }, + "alpha": { + "type": "number", + "description": "Comseg `alpha` parameter", + "default": 0.2 + }, + "min_rna_per_cell": { + "type": "number", + "description": "Comseg `min_rna_per_cell` parameter", + "default": 10 + }, + "allow_disconnected_polygon": { + "type": "boolean", + "description": "Comseg `allow_disconnected_polygon` parameter", + "default": false + }, + "norm_vector": { + "type": "boolean", + "description": "Comseg `norm_vector` parameter", + "default": false + } + } + }, + "baysor": { + "title": "Baysor", + "type": "object", + "description": "", + "default": "", + "properties": { + "use_baysor": { + "type": "boolean", + "description": "Whether to run baysor segmentation", + "default": false + }, + "baysor_scale": { + "type": "number", + "description": "Baysor `scale` parameter", + "default": 20 + }, + "baysor_scale_std": { + "type": "number", + "description": "Baysor `scale_std` parameter", + "default": 4 + }, + "prior_segmentation_confidence": { + "type": "number", + "description": "Baysor `prior_segmentation_confidence` parameter", + "default": 0 + }, + "min_molecules_per_cell": { + "type": "number", + "description": "Baysor `min_molecules_per_cell` parameter", + "default": 20 + }, + "min_molecules_per_gene": { + "type": "number", + "description": "Baysor `min_molecules_per_gene` parameter", + "default": 5 + }, + "min_molecules_per_segment": { + "type": "number", + "description": "Baysor `min_molecules_per_segment` parameter", + "default": 0 + }, + "confidence_nn_id": { + "type": "number", + "description": "Baysor `confidence_nn_id` parameter", + "default": 10 + }, + "force_2d": { + "type": "boolean", + "description": "Baysor `force_2d` parameter", + "default": true + } + } + }, + "cellpose": { + "title": "Cellpose", + "type": "object", + "description": "", + "default": "", + "properties": { + "use_cellpose": { + "type": "boolean", + "description": "Whether to run cellpose segmentation", + "default": false + }, + "cellpose_diameter": { + "type": "number", + "description": "Cellpose `diameter` parameter" + }, + "cellpose_channels": { + "type": "string", + "description": "Channel names to use for cellpose segmentation." + }, + "flow_threshold": { + "type": "number", + "description": "Cellpose `flow_threshold` parameter" + }, + "cellpose_model_type": { + "type": "string", + "description": "Cellpose model type to use" + }, + "pretrained_model": { + "type": "string", + "description": "Cellpose `pretrained_model` parameter" + }, + "cellpose_use_gpu": { + "type": "boolean", + "description": "Whether to use GPU for Cellpose segmentation", + "default": false + }, + "cellpose_kwargs": { + "type": "string", + "description": "Additional cellpose parameters as a python dict string" + } + } + }, + "stardist": { + "title": "Stardist", + "type": "object", + "description": "", + "default": "", + "properties": { + "use_stardist": { + "type": "boolean", + "description": "Whether to run stardist segmentation", + "default": false + }, + "stardist_model_type": { + "type": "string", + "description": "Name of stardist model to use" + }, + "prob_thres": { + "type": "number", + "description": "Stardist `prob_thres` parameter" + }, + "nms_thres": { + "type": "number", + "description": "Stardist `nms_thres` parameter" + }, + "stardist_channels": { + "type": "string", + "description": "Optional channel names to use for stardist segmentation." + }, + "stardist_kwargs": { + "type": "string", + "description": "Additional stardist parameters as a python dict string" + } + } + }, + "image_preprocessing": { + "title": "Image preprocessing for channel-based segmentation", + "type": "object", + "description": "", + "default": "", + "properties": { + "gaussian_sigma": { + "type": "number", + "description": "Parameter for scipy gaussian_filter (applied before running the segmentation method)" + }, + "clip_limit": { + "type": "number", + "description": "Parameter for skimage.exposure.equalize_adapthist (applied before running the segmentation method)" + }, + "clahe_kernel_size": { + "type": "number", + "description": "Parameter for skimage.exposure.equalize_adapthist (applied before running the segmentation method)" } } }, @@ -409,6 +600,35 @@ "reference_preprocessing": { "type": "string", "description": "Preprocessing method applied to the reference. Either None (raw counts), or `normalized` (sc.pp.normalize_total) or `log1p` (sc.pp.normalize_total and sc.pp.log1p)" + }, + "bag_size": { + "type": "number", + "description": "Number of cells in each bag of the spatial table. Low values will decrease the memory usage" + }, + "max_obs_reference": { + "type": "number", + "description": "Maximum samples to be considered in the reference for tangram. Low values will decrease the memory usage" + } + } + }, + "fluorescence_annotation": { + "title": "Fluorescence annotation", + "type": "object", + "description": "", + "default": "", + "properties": { + "use_fluorescence_annotation": { + "type": "boolean", + "description": "Whether to run cell-type annotation based on a marker-to-cell dictionary", + "default": false + }, + "cell_type_key": { + "type": "string", + "description": "Key of `sdata.obs` containing the cell-types" + }, + "marker_cell_dict": { + "type": "string", + "description": "TODO" } } } @@ -442,16 +662,34 @@ "$ref": "#/$defs/explorer" }, { - "$ref": "#/$defs/proseg" + "$ref": "#/$defs/image_preprocessing" }, { "$ref": "#/$defs/tissue_segmentation" }, + { + "$ref": "#/$defs/proseg" + }, { "$ref": "#/$defs/comseg" }, + { + "$ref": "#/$defs/baysor" + }, + { + "$ref": "#/$defs/cellpose" + }, + { + "$ref": "#/$defs/stardist" + }, { "$ref": "#/$defs/tangram" + }, + { + "$ref": "#/$defs/fluorescence_annotation" + }, + { + "$ref": "#/$defs/filtering" } ] } diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index 2d28876..6178e22 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -271,6 +271,10 @@ def methodsDescriptionText(mqc_methods_yaml) { } def validateParams(params) { + if (params.containsKey("read")) { + exit 1, "You use a deprecated Sopa params format. We flattened all parameters to conform to the future nextflow 26.04 strict syntax check.\nSee the nf-core/sopa docs for more details on the new syntax usage: https://nf-co.re/sopa/dev/docs/usage/." + } + def TRANSCRIPT_BASED_METHODS = ['use_proseg', 'use_baysor', 'use_comseg'] def STAINING_BASED_METHODS = ['use_stardist', 'use_cellpose'] diff --git a/workflows/sopa.nf b/workflows/sopa.nf index dda2558..9bebf08 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -92,7 +92,7 @@ workflow SOPA { if (params.use_comseg) { ch_input_comseg = params.use_cellpose ? ch_resolved : ch_tissue_seg - ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_comseg, argsCLI("transcript_patches") + " --write-cells-centroids ") + ch_transcripts_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_comseg, argsCLI("transcript_patches") + " --write-cells-centroids") (ch_resolved, versions) = COMSEG(ch_transcripts_patches) ch_versions = ch_versions.mix(versions) @@ -115,10 +115,10 @@ workflow SOPA { (ch_annotated, _out, versions) = TANGRAM_ANNOTATION(ch_aggregated, sc_reference, argsCLI("tangram")) ch_versions = ch_versions.mix(versions) } - // else if (params.annotation && params.annotation.method == "fluorescence") { - // (ch_annotated, _out, versions) = FLUO_ANNOTATION(ch_aggregated, argsCLI(params.annotation.args)) - // ch_versions = ch_versions.mix(versions) - // } + else if (params.use_fluorescence_annotation) { + (ch_annotated, _out, versions) = FLUO_ANNOTATION(ch_aggregated, argsCLI("fluorescence_annotation")) + ch_versions = ch_versions.mix(versions) + } else { ch_annotated = ch_aggregated } @@ -222,7 +222,7 @@ workflow BAYSOR { ch_segmented = PATCH_SEGMENTATION_BAYSOR(ch_baysor).map { meta, sdata_path, _out, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - (ch_resolved, _out, versions) = RESOLVE_BAYSOR(ch_segmented, resolveArgs()) + (ch_resolved, _out, versions) = RESOLVE_BAYSOR(ch_segmented, argsCLI("resolve")) ch_versions = ch_versions.mix(versions) @@ -247,7 +247,7 @@ workflow COMSEG { ch_segmented = PATCH_SEGMENTATION_COMSEG(ch_comseg).map { meta, sdata_path, _out1, _out2, n_patches -> [groupKey(meta.sdata_dir, n_patches), [meta, sdata_path]] }.groupTuple().map { it -> it[1][0] } - (ch_resolved, _out, versions) = RESOLVE_COMSEG(ch_segmented, resolveArgs()) + (ch_resolved, _out, versions) = RESOLVE_COMSEG(ch_segmented, argsCLI("resolve")) ch_versions = ch_versions.mix(versions) @@ -256,27 +256,6 @@ workflow COMSEG { ch_versions } - -def resolveArgs() { - def gene_column - def min_area - - // TODO - // if (params.use_comseg) { - // gene_column = config.segmentation.comseg.config.gene_column - // min_area = config.segmentation.comseg.min_area ?: 0 - // } - // else if (params.use_baysor) { - // gene_column = config.segmentation.baysor.config.data.gene - // min_area = config.segmentation.baysor.min_area ?: 0 - // } - // else { - // throw new IllegalArgumentException("Unknown segmentation method in config for resolveArgs") - // } - - return "--gene-column ${gene_column} --min-area ${min_area}" -} - workflow PROSEG { take: ch_patches @@ -284,9 +263,7 @@ workflow PROSEG { main: ch_versions = channel.empty() - proseg_args = argsCLI("proseg") - - (ch_segmented, _out, versions) = PATCH_SEGMENTATION_PROSEG(ch_patches, proseg_args) + (ch_segmented, _out, versions) = PATCH_SEGMENTATION_PROSEG(ch_patches, argsCLI("proseg")) ch_versions = ch_versions.mix(versions) From ff03bdb72525d40796f28e4c56f61a865a053ca3 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 18 Dec 2025 14:32:06 +0100 Subject: [PATCH 207/227] fix minor schema issues --- modules/local/utils.nf | 5 ++-- nextflow.config | 15 +++++++----- nextflow_schema.json | 52 ++++++++++++++++++++++-------------------- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/modules/local/utils.nf b/modules/local/utils.nf index e24c915..c552a71 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -117,6 +117,7 @@ def extractSubArgs(Map args, String group) { return [ level: args.level, mode: args.mode, + kwargs: args.tissue_segmentation_kwargs, ] } else if (group == "resolve") { return [ @@ -137,14 +138,14 @@ def extractSubArgs(Map args, String group) { } else if (group == "tangram") { return [ sc_reference_path: args.sc_reference_path, - cell_type_key: args.cell_type_key, + cell_type_key: args.tangram_cell_type_key, reference_preprocessing: args.reference_preprocessing, bag_size: args.bag_size, max_obs_reference: args.max_obs_reference, ] } else if (group == "fluorescence_annotation") { return [ - cell_type_key: args.cell_type_key, + cell_type_key: args.fluorescence_cell_type_key, marker_cell_dict: args.marker_cell_dict, ] } else if (group == "scanpy_preprocessing") { diff --git a/nextflow.config b/nextflow.config index 7911c00..2db4519 100644 --- a/nextflow.config +++ b/nextflow.config @@ -31,6 +31,9 @@ params { // Tissue segmentation options use_tissue_segmentation = false + level = null + mode = null + tissue_segmentation_kwargs = null // Proseg segmentation options use_proseg = false @@ -80,15 +83,15 @@ params { // Tangram options use_tangram = false sc_reference_path = null - cell_type_key = null + tangram_cell_type_key = null reference_preprocessing = null bag_size = null max_obs_reference = null // Fluorescence annotation options use_fluorescence_annotation = false - cell_type_key = null - marker_cell_dict = null + fluorescence_cell_type_key = null + marker_cell_dict = null // Cell filtering options min_area = 0 @@ -107,9 +110,9 @@ params { hvg = null // Explorer options - ram_threshold_gb = null - pixel_size = null - lazy = null + ram_threshold_gb = 4 + pixel_size = 0.2125 + lazy = true // Spaceranger options spaceranger_reference = "https://cf.10xgenomics.com/supp/spatial-exp/refdata-gex-GRCh38-2020-A.tar.gz" diff --git a/nextflow_schema.json b/nextflow_schema.json index a9bb3d2..908050c 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -269,6 +269,10 @@ "type": "string", "description": "Mode for the tissue segmentation: 'staining' or 'saturation' (for H&E images).", "enum": ["staining", "saturation"] + }, + "tissue_segmentation_kwargs": { + "type": "string", + "description": "Additional tissue segmentation parameters as a python dict string" } } }, @@ -281,15 +285,15 @@ "min_area": { "type": "number", "description": "Cells with an area less than this value will be filtered. The unit is in microns^2 for Baysor/Comseg, and in pixels^2 for Stardist/Cellpose. Not used for Proseg.", - "default": 0 + "default": 0.0 }, "min_transcripts": { "type": "number", - "default": 0 + "default": 0.0 }, "min_intensity_ratio": { "type": "number", - "default": 0 + "default": 0.0 } } }, @@ -300,12 +304,10 @@ "default": "", "properties": { "aggregate_genes": { - "type": "boolean", - "default": true + "type": "boolean" }, "aggregate_channels": { - "type": "boolean", - "default": true + "type": "boolean" }, "expand_radius_ratio": { "type": "string", @@ -327,7 +329,7 @@ "resolution": { "type": "number", "description": "Resolution parameter for the leiden clustering", - "default": 1 + "default": 1.0 }, "check_counts": { "type": "boolean", @@ -358,7 +360,7 @@ "ram_threshold_gb": { "type": "number", "description": "Threshold (in gygabytes) from which image can be loaded in memory.", - "default": 4 + "default": 4.0 } } }, @@ -401,12 +403,12 @@ "mean_cell_diameter": { "type": "number", "description": "Comseg `mean_cell_diameter` parameter", - "default": 30 + "default": 30.0 }, "max_cell_radius": { "type": "number", "description": "Comseg `max_cell_radius` parameter", - "default": 15 + "default": 15.0 }, "alpha": { "type": "number", @@ -416,7 +418,7 @@ "min_rna_per_cell": { "type": "number", "description": "Comseg `min_rna_per_cell` parameter", - "default": 10 + "default": 10.0 }, "allow_disconnected_polygon": { "type": "boolean", @@ -444,37 +446,37 @@ "baysor_scale": { "type": "number", "description": "Baysor `scale` parameter", - "default": 20 + "default": 20.0 }, "baysor_scale_std": { "type": "number", "description": "Baysor `scale_std` parameter", - "default": 4 + "default": 4.0 }, "prior_segmentation_confidence": { "type": "number", "description": "Baysor `prior_segmentation_confidence` parameter", - "default": 0 + "default": 0.0 }, "min_molecules_per_cell": { "type": "number", "description": "Baysor `min_molecules_per_cell` parameter", - "default": 20 + "default": 20.0 }, "min_molecules_per_gene": { "type": "number", "description": "Baysor `min_molecules_per_gene` parameter", - "default": 5 + "default": 5.0 }, "min_molecules_per_segment": { "type": "number", "description": "Baysor `min_molecules_per_segment` parameter", - "default": 0 + "default": 0.0 }, "confidence_nn_id": { "type": "number", "description": "Baysor `confidence_nn_id` parameter", - "default": 10 + "default": 10.0 }, "force_2d": { "type": "boolean", @@ -540,13 +542,13 @@ "type": "string", "description": "Name of stardist model to use" }, - "prob_thres": { + "prob_thresh": { "type": "number", - "description": "Stardist `prob_thres` parameter" + "description": "Stardist `prob_thresh` parameter" }, - "nms_thres": { + "nms_thresh": { "type": "number", - "description": "Stardist `nms_thres` parameter" + "description": "Stardist `nms_thresh` parameter" }, "stardist_channels": { "type": "string", @@ -593,7 +595,7 @@ "type": "string", "description": "Path to the scRNAseq annotated reference, as a `.h5ad` file" }, - "cell_type_key": { + "tangram_cell_type_key": { "type": "string", "description": "Key of `adata_ref.obs` containing the cell-types" }, @@ -622,7 +624,7 @@ "description": "Whether to run cell-type annotation based on a marker-to-cell dictionary", "default": false }, - "cell_type_key": { + "fluorescence_cell_type_key": { "type": "string", "description": "Key of `sdata.obs` containing the cell-types" }, From 62bfa284bf90073cba728b39485c5bb1b9e2b410 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 18 Dec 2025 14:37:29 +0100 Subject: [PATCH 208/227] use nf-core pipeline schema checker --- nextflow_schema.json | 117 +++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 66 deletions(-) diff --git a/nextflow_schema.json b/nextflow_schema.json index 908050c..a4e19a1 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -222,7 +222,8 @@ "type": "number", "description": "Optional page for the imageio reader" } - } + }, + "required": ["technology"] }, "patches": { "title": "Patches", @@ -258,8 +259,7 @@ "properties": { "use_tissue_segmentation": { "type": "boolean", - "description": "Whether to run tissue segmentation", - "default": false + "description": "Whether to run tissue segmentation" }, "level": { "type": "number", @@ -274,7 +274,8 @@ "type": "string", "description": "Additional tissue segmentation parameters as a python dict string" } - } + }, + "required": ["use_tissue_segmentation"] }, "filtering": { "title": "Cell filtering", @@ -288,12 +289,10 @@ "default": 0.0 }, "min_transcripts": { - "type": "number", - "default": 0.0 + "type": "number" }, "min_intensity_ratio": { - "type": "number", - "default": 0.0 + "type": "number" } } }, @@ -310,10 +309,10 @@ "type": "boolean" }, "expand_radius_ratio": { - "type": "string", - "default": "0" + "type": "string" } - } + }, + "required": ["aggregate_genes", "aggregate_channels"] }, "scanpy_preprocessing": { "title": "Scanpy preprocessing", @@ -323,13 +322,11 @@ "properties": { "use_scanpy_preprocessing": { "type": "boolean", - "description": "Whether to run scanpy preprocessing", - "default": false + "description": "Whether to run scanpy preprocessing" }, "resolution": { "type": "number", - "description": "Resolution parameter for the leiden clustering", - "default": 1.0 + "description": "Resolution parameter for the leiden clustering" }, "check_counts": { "type": "boolean", @@ -339,7 +336,8 @@ "type": "boolean", "description": "Whether to compute highly variable genes before computing the UMAP and clustering" } - } + }, + "required": ["use_scanpy_preprocessing"] }, "explorer": { "title": "Explorer", @@ -362,7 +360,8 @@ "description": "Threshold (in gygabytes) from which image can be loaded in memory.", "default": 4.0 } - } + }, + "required": ["pixel_size"] }, "proseg": { "title": "Proseg", @@ -372,8 +371,7 @@ "properties": { "use_proseg": { "type": "boolean", - "description": "Whether to run proseg segmentation", - "default": false + "description": "Whether to run proseg segmentation" }, "command_line_suffix": { "type": "string", @@ -387,7 +385,8 @@ "type": "string", "description": "**Only for Visium HD data.** Key of `sdata` containing the prior cell boundaries. If `'auto'`, use the latest performed segmentation (e.g., stardist or the 10X Genomics segmentation)." } - } + }, + "required": ["use_proseg"] }, "comseg": { "title": "Comseg", @@ -397,40 +396,34 @@ "properties": { "use_comseg": { "type": "boolean", - "description": "Whether to run comseg segmentation", - "default": false + "description": "Whether to run comseg segmentation" }, "mean_cell_diameter": { "type": "number", - "description": "Comseg `mean_cell_diameter` parameter", - "default": 30.0 + "description": "Comseg `mean_cell_diameter` parameter" }, "max_cell_radius": { "type": "number", - "description": "Comseg `max_cell_radius` parameter", - "default": 15.0 + "description": "Comseg `max_cell_radius` parameter" }, "alpha": { "type": "number", - "description": "Comseg `alpha` parameter", - "default": 0.2 + "description": "Comseg `alpha` parameter" }, "min_rna_per_cell": { "type": "number", - "description": "Comseg `min_rna_per_cell` parameter", - "default": 10.0 + "description": "Comseg `min_rna_per_cell` parameter" }, "allow_disconnected_polygon": { "type": "boolean", - "description": "Comseg `allow_disconnected_polygon` parameter", - "default": false + "description": "Comseg `allow_disconnected_polygon` parameter" }, "norm_vector": { "type": "boolean", - "description": "Comseg `norm_vector` parameter", - "default": false + "description": "Comseg `norm_vector` parameter" } - } + }, + "required": ["use_comseg"] }, "baysor": { "title": "Baysor", @@ -440,50 +433,43 @@ "properties": { "use_baysor": { "type": "boolean", - "description": "Whether to run baysor segmentation", - "default": false + "description": "Whether to run baysor segmentation" }, "baysor_scale": { "type": "number", - "description": "Baysor `scale` parameter", - "default": 20.0 + "description": "Baysor `scale` parameter" }, "baysor_scale_std": { "type": "number", - "description": "Baysor `scale_std` parameter", - "default": 4.0 + "description": "Baysor `scale_std` parameter" }, "prior_segmentation_confidence": { "type": "number", - "description": "Baysor `prior_segmentation_confidence` parameter", - "default": 0.0 + "description": "Baysor `prior_segmentation_confidence` parameter" }, "min_molecules_per_cell": { "type": "number", - "description": "Baysor `min_molecules_per_cell` parameter", - "default": 20.0 + "description": "Baysor `min_molecules_per_cell` parameter" }, "min_molecules_per_gene": { "type": "number", - "description": "Baysor `min_molecules_per_gene` parameter", - "default": 5.0 + "description": "Baysor `min_molecules_per_gene` parameter" }, "min_molecules_per_segment": { "type": "number", - "description": "Baysor `min_molecules_per_segment` parameter", - "default": 0.0 + "description": "Baysor `min_molecules_per_segment` parameter" }, "confidence_nn_id": { "type": "number", - "description": "Baysor `confidence_nn_id` parameter", - "default": 10.0 + "description": "Baysor `confidence_nn_id` parameter" }, "force_2d": { "type": "boolean", "description": "Baysor `force_2d` parameter", "default": true } - } + }, + "required": ["use_baysor"] }, "cellpose": { "title": "Cellpose", @@ -493,8 +479,7 @@ "properties": { "use_cellpose": { "type": "boolean", - "description": "Whether to run cellpose segmentation", - "default": false + "description": "Whether to run cellpose segmentation" }, "cellpose_diameter": { "type": "number", @@ -518,14 +503,14 @@ }, "cellpose_use_gpu": { "type": "boolean", - "description": "Whether to use GPU for Cellpose segmentation", - "default": false + "description": "Whether to use GPU for Cellpose segmentation" }, "cellpose_kwargs": { "type": "string", "description": "Additional cellpose parameters as a python dict string" } - } + }, + "required": ["use_cellpose"] }, "stardist": { "title": "Stardist", @@ -535,8 +520,7 @@ "properties": { "use_stardist": { "type": "boolean", - "description": "Whether to run stardist segmentation", - "default": false + "description": "Whether to run stardist segmentation" }, "stardist_model_type": { "type": "string", @@ -558,7 +542,8 @@ "type": "string", "description": "Additional stardist parameters as a python dict string" } - } + }, + "required": ["use_stardist"] }, "image_preprocessing": { "title": "Image preprocessing for channel-based segmentation", @@ -588,8 +573,7 @@ "properties": { "use_tangram": { "type": "boolean", - "description": "Whether to run tangram cell-type annotation", - "default": false + "description": "Whether to run tangram cell-type annotation" }, "sc_reference_path": { "type": "string", @@ -611,7 +595,8 @@ "type": "number", "description": "Maximum samples to be considered in the reference for tangram. Low values will decrease the memory usage" } - } + }, + "required": ["use_tangram"] }, "fluorescence_annotation": { "title": "Fluorescence annotation", @@ -621,8 +606,7 @@ "properties": { "use_fluorescence_annotation": { "type": "boolean", - "description": "Whether to run cell-type annotation based on a marker-to-cell dictionary", - "default": false + "description": "Whether to run cell-type annotation based on a marker-to-cell dictionary" }, "fluorescence_cell_type_key": { "type": "string", @@ -632,7 +616,8 @@ "type": "string", "description": "TODO" } - } + }, + "required": ["use_fluorescence_annotation"] } }, "allOf": [ From 0ccc7ba254dbe070a8a6f1c5b90046fc1616f83d Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 18 Dec 2025 17:19:37 +0100 Subject: [PATCH 209/227] describe parameters and minor fixes --- conf/test.config | 2 +- conf/test_baysor.config | 78 ++++---- conf/test_cellpose.config | 36 ++-- conf/test_cellpose_CK_DAPI.config | 51 +++++ conf/test_comseg.config | 61 +++--- conf/test_full.config | 48 ++--- modules/local/utils.nf | 32 +++- nextflow.config | 24 +-- nextflow_schema.json | 180 ++++++++++-------- .../local/utils_nfcore_sopa_pipeline/main.nf | 8 +- 10 files changed, 296 insertions(+), 224 deletions(-) create mode 100644 conf/test_cellpose_CK_DAPI.config diff --git a/conf/test.config b/conf/test.config index 1a79803..700ebd2 100644 --- a/conf/test.config +++ b/conf/test.config @@ -25,7 +25,7 @@ params { // Input data input = "${baseDir}/tests/samplesheet.csv" - // Reading + // Reader technology = "toy_dataset" // Patches diff --git a/conf/test_baysor.config b/conf/test_baysor.config index 0f4a3b9..ad44e6f 100644 --- a/conf/test_baysor.config +++ b/conf/test_baysor.config @@ -25,50 +25,36 @@ params { // Input data input = "${baseDir}/tests/samplesheet.csv" - read.technology = "toy_dataset" - - patchify = [ - patch_width_microns: 400, - patch_overlap_microns: 20, - ] - - segmentation.baysor = [ - min_area: 10, - config: [ - data: [ - force_2d: true, - min_molecules_per_cell: 10, - x: "x", - y: "y", - z: "z", - gene: "genes", - min_molecules_per_gene: 0, - min_molecules_per_segment: 3, - confidence_nn_id: 6, - ], - segmentation: [ - scale: 3, - scale_std: "25%", - prior_segmentation_confidence: 0, - ], - ], - ] - - aggregate = [ - aggregate_channels: true, - min_transcripts: 5, - ] - - annotation = [ - method: "tangram", - args: [ - sc_reference_path: "https://github.com/gustaveroussy/sopa/raw/refs/heads/main/tests/toy_tangram_ref.h5ad", - cell_type_key: "ct", - ], - ] - - explorer = [ - ram_threshold_gb: 4, - pixel_size: 0.1, - ] + // Reader + technology = "toy_dataset" + + // Patches options + patch_width_microns = 400 + patch_overlap_microns = 20 + + // Baysor segmentation + use_baysor = true + baysor_scale = 3 + baysor_scale_std = "25%" + min_molecules_per_cell = 10 + min_molecules_per_gene = 0 + min_molecules_per_segment = 3 + confidence_nn_id = 6 + prior_segmentation_confidence = 0 + + // Filtering + min_area = 10 + min_transcripts = 5 + + // Agregation + aggregate_channels = true + + // Annotation + use_tangram = true + sc_reference_path = "https://github.com/gustaveroussy/sopa/raw/refs/heads/main/tests/toy_tangram_ref.h5ad" + tangram_cell_type_key = "ct" + + // Explorer + ram_threshold_gb = 4 + pixel_size = 0.1 } diff --git a/conf/test_cellpose.config b/conf/test_cellpose.config index 0351f7e..0d7c356 100644 --- a/conf/test_cellpose.config +++ b/conf/test_cellpose.config @@ -25,25 +25,27 @@ params { // Input data input = "${baseDir}/tests/samplesheet.csv" - read.technology = "toy_dataset" + // Reader + technology = "toy_dataset" - patchify = [ - patch_width_pixel: 5000, - patch_overlap_pixel: 50, - ] + // Patches options + patch_width_pixel = 5000 + patch_overlap_pixel = 50 - segmentation.cellpose = [ - diameter: 35, - channels: ["DAPI"], - flow_threshold: 2, - cellprob_threshold: -6, - min_area: 2500, - ] + // Cellpose segmentation + use_cellpose = true + cellpose_diameter = 35 + cellpose_channels = 'DAPI' + flow_threshold = 2 + cellprob_threshold = -6 - aggregate.aggregate_channels = true + // Filtering + min_area = 2500 - explorer = [ - ram_threshold_gb: 4, - pixel_size: 0.1, - ] + // Aggregation + aggregate_channels = true + + // Explorer + ram_threshold_gb = 4 + pixel_size = 0.1 } diff --git a/conf/test_cellpose_CK_DAPI.config b/conf/test_cellpose_CK_DAPI.config new file mode 100644 index 0000000..d358512 --- /dev/null +++ b/conf/test_cellpose_CK_DAPI.config @@ -0,0 +1,51 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/sopa -profile test_cellpose, --outdir + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h', + ] +} + +params { + config_profile_name = 'Test profile with Cellpose' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Input data + input = "${baseDir}/tests/samplesheet.csv" + + // Reader + technology = "toy_dataset" + + // Patches options + patch_width_pixel = 5000 + patch_overlap_pixel = 50 + + // Cellpose segmentation + use_cellpose = true + cellpose_diameter = 35 + cellpose_channels = 'CK DAPI' + flow_threshold = 2 + cellprob_threshold = -6 + + // Filtering + min_area = 2500 + + // Aggregation + aggregate_channels = true + + // Explorer + ram_threshold_gb = 4 + pixel_size = 0.1 +} diff --git a/conf/test_comseg.config b/conf/test_comseg.config index e79d265..880bb8e 100644 --- a/conf/test_comseg.config +++ b/conf/test_comseg.config @@ -25,40 +25,29 @@ params { // Input data input = "${baseDir}/tests/samplesheet.csv" - read.technology = "toy_dataset" - - - patchify = [ - patch_width_microns: 400, - patch_overlap_microns: 20, - ] - - segmentation.comseg = [ - min_area: 10, - prior_shapes_key: "cells", - config: [ - dict_scale: [ - x: 1, - y: 1, - z: 1, - ], - mean_cell_diameter: 15, - max_cell_radius: 25, - allow_disconnected_polygon: false, - alpha: 0.5, - min_rna_per_cell: 5, - gene_column: "genes", - norm_vector: false, - ], - ] - - aggregate = [ - aggregate_channels: true, - min_transcripts: 5, - ] - - explorer = [ - ram_threshold_gb: 4, - pixel_size: 0.1, - ] + // Reader + technology = "toy_dataset" + + // Patches options + patch_width_microns = 400 + patch_overlap_microns = 20 + prior_shapes_key = "cells" + + // Comseg segmentation + use_comseg = true + mean_cell_diameter = 15 + max_cell_radius = 25 + alpha = 0.5 + min_rna_per_cell = 5 + + // Filtering + min_area = 10 + min_transcripts = 5 + + // Aggregation + aggregate_channels = true + + // Explorer + ram_threshold_gb = 4 + pixel_size = 0.1 } diff --git a/conf/test_full.config b/conf/test_full.config index 509e3ca..e368839 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -17,28 +17,28 @@ params { // Input data input = "${baseDir}/tests/samplesheet.csv" - read = [ - technology: "toy_dataset", - kwargs: [ - genes: 500, - length: 10000, - ], - ] - - patchify = [ - patch_width_microns: 400, - patch_overlap_microns: 20, - ] - - segmentation.proseg.prior_shapes_key = "auto" - - aggregate = [ - aggregate_channels: true, - min_transcripts: 5, - ] - - explorer = [ - ram_threshold_gb: 4, - pixel_size: 0.1, - ] + // Reader + technology = "toy_dataset" + + // Patches + patch_width_microns = -1 + prior_shapes_key = "auto" + + // Proseg segmentation + use_proseg = true + + // Aggregation + aggregate_channels = true + min_transcripts = 5 + + // Annotation + use_fluorescence_annotation = true + marker_cell_dict = '{"CK": "Tumoral cell", "CD3": "T cell", "CD20": "B cell"}' + + // Scanpy preprocessing + use_scanpy_preprocessing = true + + // Explorer + ram_threshold_gb = 4 + pixel_size = 0.1 } diff --git a/modules/local/utils.nf b/modules/local/utils.nf index c552a71..08c746d 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -44,11 +44,11 @@ def extractSubArgs(Map args, String group) { } else if (group == "cellpose") { return [ diameter: args.cellpose_diameter, - channels: args.cellpose_channels, + channels: getChannels(args.cellpose_channels, false), flow_threshold: args.flow_threshold, model_type: args.cellpose_model_type, pretrained_model: args.pretrained_model, - use_gpu: args.cellpose_use_gpu, + gpu: args.cellpose_use_gpu, min_area: args.min_area, clip_limit: args.clip_limit, clahe_kernel_size: args.clahe_kernel_size, @@ -60,7 +60,7 @@ def extractSubArgs(Map args, String group) { model_type: args.stardist_model_type, prob_thresh: args.prob_thresh, nms_thresh: args.nms_thresh, - channels: args.stardist_channels, + channels: getChannels(args.stardist_channels, true), min_area: args.min_area, clip_limit: args.clip_limit, clahe_kernel_size: args.clahe_kernel_size, @@ -128,16 +128,15 @@ def extractSubArgs(Map args, String group) { patch_width_microns: args.patch_width_microns, patch_overlap_microns: args.patch_overlap_microns, unassigned_value: args.unassigned_value, - prior_shapes_key: args.prior_shapes_key, + prior_shapes_key: getPriorShapesKey(), ] } else if (group == "image_patches") { return [ - patch_width_pixels: args.patch_width_pixels, - patch_overlap_pixels: args.patch_overlap_pixels + patch_width_pixel: args.patch_width_pixel, + patch_overlap_pixel: args.patch_overlap_pixel ] } else if (group == "tangram") { return [ - sc_reference_path: args.sc_reference_path, cell_type_key: args.tangram_cell_type_key, reference_preprocessing: args.reference_preprocessing, bag_size: args.bag_size, @@ -165,6 +164,25 @@ def extractSubArgs(Map args, String group) { } } +def getPriorShapesKey() { + if (params.use_cellpose) { + return "cellpose_boundaries" + } else { + return params.prior_shapes_key + } +} + +def getChannels(String channels, Boolean allow_null = false) { + if (channels instanceof String) { + return channels.split(/[ ,|]+/) + } else { + if (allow_null && channels == null) { + return null + } + exit 1, "The channels parameter must be a string of channel names separated by space, comma or pipe characters." + } +} + def argsCLI(String group = null, Map args = null) { args = args ?: params diff --git a/nextflow.config b/nextflow.config index 2db4519..d4b2a84 100644 --- a/nextflow.config +++ b/nextflow.config @@ -43,21 +43,21 @@ params { // Baysor segmentation options use_baysor = false - baysor_scale = null - baysor_scale_std = null - prior_segmentation_confidence = null - min_molecules_per_cell = null - min_molecules_per_gene = null - min_molecules_per_segment = null - confidence_nn_id = null + baysor_scale = -1 + baysor_scale_std = "25%" + prior_segmentation_confidence = 0.2 + min_molecules_per_cell = 20 + min_molecules_per_gene = 10 + min_molecules_per_segment = 0 + confidence_nn_id = 0 force_2d = true // Comseg segmentation options use_comseg = false - mean_cell_diameter = null - max_cell_radius = null - alpha = null - min_rna_per_cell = null + mean_cell_diameter = 10 + max_cell_radius = 15 + alpha = 0.5 + min_rna_per_cell = 1 allow_disconnected_polygon = false norm_vector = false @@ -67,6 +67,7 @@ params { cellpose_diameter = null cellpose_channels = null flow_threshold = null + cellprob_threshold = null cellpose_model_type = null pretrained_model = null cellpose_use_gpu = false @@ -263,6 +264,7 @@ profiles { test_baysor { includeConfig 'conf/test_baysor.config' } test_comseg { includeConfig 'conf/test_comseg.config' } test_cellpose { includeConfig 'conf/test_cellpose.config' } + test_cellpose_CK_DAPI { includeConfig 'conf/test_cellpose_CK_DAPI.config' } test_full { includeConfig 'conf/test_full.config' } xenium_baysor { includeConfig 'conf/predefined/xenium_baysor.config' } diff --git a/nextflow_schema.json b/nextflow_schema.json index a4e19a1..2f4f694 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -223,38 +223,46 @@ "description": "Optional page for the imageio reader" } }, - "required": ["technology"] + "required": ["technology"], + "fa_icon": "fas fa-arrows-alt-h" }, "patches": { "title": "Patches", "type": "object", - "description": "", + "description": "Creation of the image and transcript patches before segmentation", "default": "", "properties": { "patch_width_pixel": { - "type": "number" + "type": "number", + "description": "Width (and height) of each patch in pixels" }, "patch_overlap_pixel": { - "type": "number" + "type": "number", + "description": "Number of overlapping pixels between the patches. We advise to choose approximately twice the diameter of a cell" }, "patch_width_microns": { - "type": "number" + "type": "number", + "description": "Width (and height) of each patch in microns" }, "patch_overlap_microns": { - "type": "number" + "type": "number", + "description": "Number of overlapping microns between the patches. We advise to choose approximately twice the diameter of a cell" }, "prior_shapes_key": { - "type": "string" + "type": "string", + "description": "Optional name of the boundaries element to use as a segmentation prior. Either a column name for the transcript dataframe, or a key of `sdata` containing the shapes names." }, "unassigned_value": { - "type": "string" + "type": "string", + "description": "If `prior_shapes_key` is provided, this is the value given to transcripts that are not inside any cell (if it's already 0, don't provide this argument)" } - } + }, + "fa_icon": "far fa-square" }, "tissue_segmentation": { "title": "Tissue segmentation", "type": "object", - "description": "Parameters related to tissue segmentation", + "description": "Parameters related to the tissue segmentation", "default": "", "properties": { "use_tissue_segmentation": { @@ -275,12 +283,12 @@ "description": "Additional tissue segmentation parameters as a python dict string" } }, - "required": ["use_tissue_segmentation"] + "fa_icon": "fab fa-bitbucket" }, "filtering": { "title": "Cell filtering", "type": "object", - "description": "", + "description": "Filtering low-quality cells during and after segmentation", "default": "", "properties": { "min_area": { @@ -289,30 +297,36 @@ "default": 0.0 }, "min_transcripts": { - "type": "number" + "type": "number", + "description": "Cells with less transcripts than this value will be filtered." }, "min_intensity_ratio": { - "type": "number" + "type": "number", + "description": "Cells whose mean channel intensity is less than `min_intensity_ratio * quantile_90` will be filtered." } - } + }, + "fa_icon": "fas fa-filter" }, "aggregation": { "title": "Aggregation", "type": "object", - "description": "", + "description": "Aggregation of genes and channels inside each cell", "default": "", "properties": { "aggregate_genes": { - "type": "boolean" + "type": "boolean", + "description": "Whether to aggregate the genes (counts) inside each cell" }, "aggregate_channels": { - "type": "boolean" + "type": "boolean", + "description": "Whether to aggregate the channels (intensity) inside each cell" }, "expand_radius_ratio": { - "type": "string" + "type": "string", + "description": "Cells polygons will be expanded by `expand_radius_ratio * mean_radius` for channels averaging **only**. This help better aggregate boundary stainings" } }, - "required": ["aggregate_genes", "aggregate_channels"] + "fa_icon": "fas fa-calculator" }, "scanpy_preprocessing": { "title": "Scanpy preprocessing", @@ -337,12 +351,12 @@ "description": "Whether to compute highly variable genes before computing the UMAP and clustering" } }, - "required": ["use_scanpy_preprocessing"] + "fa_icon": "fas fa-tools" }, "explorer": { "title": "Explorer", "type": "object", - "description": "", + "description": "Parameters related to the Xenium Explorer visualization tool", "default": "", "properties": { "pixel_size": { @@ -361,12 +375,33 @@ "default": 4.0 } }, - "required": ["pixel_size"] + "fa_icon": "fas fa-tools" + }, + "image_preprocessing": { + "title": "Image preprocessing", + "type": "object", + "description": "Image preprocessing applied before channel-based segmentation methods (cellpose, stardist)", + "default": "", + "properties": { + "gaussian_sigma": { + "type": "number", + "description": "Parameter for scipy gaussian_filter (applied before running the segmentation method)" + }, + "clip_limit": { + "type": "number", + "description": "Parameter for skimage.exposure.equalize_adapthist (applied before running the segmentation method)" + }, + "clahe_kernel_size": { + "type": "number", + "description": "Parameter for skimage.exposure.equalize_adapthist (applied before running the segmentation method)" + } + }, + "fa_icon": "fas fa-file-image" }, "proseg": { "title": "Proseg", "type": "object", - "description": "", + "description": "Parameters related to the proseg segmentation method", "default": "", "properties": { "use_proseg": { @@ -386,12 +421,12 @@ "description": "**Only for Visium HD data.** Key of `sdata` containing the prior cell boundaries. If `'auto'`, use the latest performed segmentation (e.g., stardist or the 10X Genomics segmentation)." } }, - "required": ["use_proseg"] + "fa_icon": "fas fa-tools" }, "comseg": { "title": "Comseg", "type": "object", - "description": "", + "description": "Parameters related to the comseg segmentation method", "default": "", "properties": { "use_comseg": { @@ -400,19 +435,23 @@ }, "mean_cell_diameter": { "type": "number", - "description": "Comseg `mean_cell_diameter` parameter" + "description": "Comseg `mean_cell_diameter` parameter", + "default": 10.0 }, "max_cell_radius": { "type": "number", - "description": "Comseg `max_cell_radius` parameter" + "description": "Comseg `max_cell_radius` parameter", + "default": 15.0 }, "alpha": { "type": "number", - "description": "Comseg `alpha` parameter" + "description": "Comseg `alpha` parameter", + "default": 0.5 }, "min_rna_per_cell": { "type": "number", - "description": "Comseg `min_rna_per_cell` parameter" + "description": "Comseg `min_rna_per_cell` parameter", + "default": 1.0 }, "allow_disconnected_polygon": { "type": "boolean", @@ -423,12 +462,12 @@ "description": "Comseg `norm_vector` parameter" } }, - "required": ["use_comseg"] + "fa_icon": "fas fa-tools" }, "baysor": { "title": "Baysor", "type": "object", - "description": "", + "description": "Parameters related to the baysor segmentation method", "default": "", "properties": { "use_baysor": { @@ -437,23 +476,28 @@ }, "baysor_scale": { "type": "number", - "description": "Baysor `scale` parameter" + "description": "Baysor `scale` parameter", + "default": -1.0 }, "baysor_scale_std": { - "type": "number", - "description": "Baysor `scale_std` parameter" + "type": "string", + "description": "Baysor `scale_std` parameter", + "default": "25%" }, "prior_segmentation_confidence": { "type": "number", - "description": "Baysor `prior_segmentation_confidence` parameter" + "description": "Baysor `prior_segmentation_confidence` parameter", + "default": 0.2 }, "min_molecules_per_cell": { "type": "number", - "description": "Baysor `min_molecules_per_cell` parameter" + "description": "Baysor `min_molecules_per_cell` parameter", + "default": 20.0 }, "min_molecules_per_gene": { "type": "number", - "description": "Baysor `min_molecules_per_gene` parameter" + "description": "Baysor `min_molecules_per_gene` parameter", + "default": 10.0 }, "min_molecules_per_segment": { "type": "number", @@ -469,12 +513,12 @@ "default": true } }, - "required": ["use_baysor"] + "fa_icon": "fas fa-tools" }, "cellpose": { "title": "Cellpose", "type": "object", - "description": "", + "description": "Parameters related to the cellpose segmentation method", "default": "", "properties": { "use_cellpose": { @@ -487,12 +531,16 @@ }, "cellpose_channels": { "type": "string", - "description": "Channel names to use for cellpose segmentation." + "description": "Channel name(s) to use for cellpose segmentation. If multiple, separate by space, comma or pipe characters." }, "flow_threshold": { "type": "number", "description": "Cellpose `flow_threshold` parameter" }, + "cellprob_threshold": { + "type": "number", + "description": "Cellpose `cellprob_threshold` parameter" + }, "cellpose_model_type": { "type": "string", "description": "Cellpose model type to use" @@ -510,12 +558,12 @@ "description": "Additional cellpose parameters as a python dict string" } }, - "required": ["use_cellpose"] + "fa_icon": "fas fa-tools" }, "stardist": { "title": "Stardist", "type": "object", - "description": "", + "description": "Parameters related to the stardist segmentation method", "default": "", "properties": { "use_stardist": { @@ -536,39 +584,19 @@ }, "stardist_channels": { "type": "string", - "description": "Optional channel names to use for stardist segmentation." + "description": "Optional channel name(s) to use for stardist segmentation. If multiple, separate by space, comma or pipe characters." }, "stardist_kwargs": { "type": "string", "description": "Additional stardist parameters as a python dict string" } }, - "required": ["use_stardist"] - }, - "image_preprocessing": { - "title": "Image preprocessing for channel-based segmentation", - "type": "object", - "description": "", - "default": "", - "properties": { - "gaussian_sigma": { - "type": "number", - "description": "Parameter for scipy gaussian_filter (applied before running the segmentation method)" - }, - "clip_limit": { - "type": "number", - "description": "Parameter for skimage.exposure.equalize_adapthist (applied before running the segmentation method)" - }, - "clahe_kernel_size": { - "type": "number", - "description": "Parameter for skimage.exposure.equalize_adapthist (applied before running the segmentation method)" - } - } + "fa_icon": "fas fa-tools" }, "tangram": { "title": "Tangram", "type": "object", - "description": "", + "description": "Parameters related to the tangram cell-type annotation method", "default": "", "properties": { "use_tangram": { @@ -596,12 +624,12 @@ "description": "Maximum samples to be considered in the reference for tangram. Low values will decrease the memory usage" } }, - "required": ["use_tangram"] + "fa_icon": "fas fa-scroll" }, "fluorescence_annotation": { "title": "Fluorescence annotation", "type": "object", - "description": "", + "description": "Parameters related to the fluorescence-based cell-type annotation method", "default": "", "properties": { "use_fluorescence_annotation": { @@ -614,10 +642,10 @@ }, "marker_cell_dict": { "type": "string", - "description": "TODO" + "description": "Dictionary mapping whose keys are marker channel names and values are the cell types associated to each marker. Should be provided as a string representation of a python dictionary." } }, - "required": ["use_fluorescence_annotation"] + "fa_icon": "fas fa-scroll" } }, "allOf": [ @@ -639,6 +667,12 @@ { "$ref": "#/$defs/patches" }, + { + "$ref": "#/$defs/tissue_segmentation" + }, + { + "$ref": "#/$defs/filtering" + }, { "$ref": "#/$defs/aggregation" }, @@ -651,9 +685,6 @@ { "$ref": "#/$defs/image_preprocessing" }, - { - "$ref": "#/$defs/tissue_segmentation" - }, { "$ref": "#/$defs/proseg" }, @@ -674,9 +705,6 @@ }, { "$ref": "#/$defs/fluorescence_annotation" - }, - { - "$ref": "#/$defs/filtering" } ] } diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index 6178e22..49a7c04 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -277,17 +277,13 @@ def validateParams(params) { def TRANSCRIPT_BASED_METHODS = ['use_proseg', 'use_baysor', 'use_comseg'] def STAINING_BASED_METHODS = ['use_stardist', 'use_cellpose'] + def NON_VALID_STARDIST_METHODS = ['use_baysor', 'use_comseg'] // check segmentation methods assert TRANSCRIPT_BASED_METHODS.count { params[it] } <= 1 : "Only one of ${TRANSCRIPT_BASED_METHODS} may be used" assert STAINING_BASED_METHODS.count { params[it] } <= 1 : "Only one of ${STAINING_BASED_METHODS} may be used" if (params.use_stardist) { - assert TRANSCRIPT_BASED_METHODS.every { !params[it] } : "'stardist' cannot be combined with transcript-based methods" - } - - // check prior shapes key - if (params.use_cellpose) { - params.prior_shapes_key = "cellpose_boundaries" + assert NON_VALID_STARDIST_METHODS.every { !params[it] } : "'stardist' cannot be combined with transcript-based methods, except proseg." } return params From 4c9099491d38ba66c236ca4b3386928ee5870cd3 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Thu, 18 Dec 2025 18:16:23 +0100 Subject: [PATCH 210/227] channels to list --- modules/local/utils.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 08c746d..0132a5b 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -174,7 +174,7 @@ def getPriorShapesKey() { def getChannels(String channels, Boolean allow_null = false) { if (channels instanceof String) { - return channels.split(/[ ,|]+/) + return channels.split(/[ ,|]+/).findAll { it } } else { if (allow_null && channels == null) { return null From ab64aad22ffc8a11808561dcbf397457677228d9 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 19 Dec 2025 10:40:44 +0100 Subject: [PATCH 211/227] flatten all configs and use two min_area params --- .github/CONTRIBUTING.md | 19 ---- conf/predefined/convert.nf | 25 ------ conf/predefined/convert.sh | 21 ----- conf/predefined/convert_list.sh | 12 --- conf/predefined/cosmx_baysor.config | 66 +++++--------- conf/predefined/cosmx_cellpose.config | 45 +++++----- conf/predefined/cosmx_cellpose_baysor.config | 86 +++++++----------- conf/predefined/cosmx_proseg.config | 34 ++++--- conf/predefined/hyperion_base.config | 51 +++++------ conf/predefined/macsima_base.config | 51 +++++------ .../merscope_baysor_cellpose.config | 90 ++++++++----------- conf/predefined/merscope_baysor_vizgen.config | 70 ++++++--------- conf/predefined/merscope_cellpose.config | 49 +++++----- conf/predefined/merscope_proseg.config | 38 ++++---- conf/predefined/phenocycler_base_10X.config | 51 +++++------ conf/predefined/phenocycler_base_20X.config | 51 +++++------ conf/predefined/phenocycler_base_40X.config | 51 +++++------ conf/predefined/visium_hd_stardist.config | 35 ++++---- conf/predefined/xenium_baysor.config | 65 +++++--------- conf/predefined/xenium_baysor_prior.config | 67 +++++--------- .../xenium_baysor_prior_small_cells.config | 67 +++++--------- conf/predefined/xenium_cellpose.config | 45 +++++----- conf/predefined/xenium_cellpose_baysor.config | 85 +++++++----------- conf/predefined/xenium_proseg.config | 34 ++++--- conf/test_baysor.config | 3 +- conf/test_cellpose.config | 2 +- conf/test_cellpose_CK_DAPI.config | 2 +- conf/test_comseg.config | 2 +- modules/local/utils.nf | 10 +-- nextflow.config | 3 +- nextflow_schema.json | 9 +- 31 files changed, 477 insertions(+), 762 deletions(-) delete mode 100644 conf/predefined/convert.nf delete mode 100644 conf/predefined/convert.sh delete mode 100644 conf/predefined/convert_list.sh diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 5e513ab..00bbbcf 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -59,25 +59,6 @@ These tests are run both with the latest available version of `Nextflow` and als - Fix the bug, and bump version (X.Y.Z+1). - Open a pull-request from `patch` to `main`/`master` with the changes. -## Updating the Sopa parameters profiles - -Some Sopa parameters profiles are stored in the [Python Sopa repository](https://github.com/gustaveroussy/sopa). They have to be synchronized with the profiles in `conf/predefined`. -To do that, we can convert each config from `gustavroussy/sopa` to a nextflow profile as follows: - -```sh -# clone the python repo wherever you want -git clone https://github.com/gustaveroussy/sopa.git - -# now, inside the nf-core/sopa repo: -cd conf/predefined - -# set SOPA_DIR depending on where you cloned gustaveroussy/sopa.git -SOPA_DIR=/path/to/gustaveroussy/sopa sh convert.sh -sh convert_list.sh # showing all profile imports, to be added to nextflow.config -``` - -Submit only the non-toy configs, and run file formatting before pushing the changes (if any). - ## Getting help For further information/help, please consult the [nf-core/sopa documentation](https://nf-co.re/sopa/usage) and don't hesitate to get in touch on the nf-core Slack [#sopa](https://nfcore.slack.com/channels/sopa) channel ([join our Slack here](https://nf-co.re/join/slack)). diff --git a/conf/predefined/convert.nf b/conf/predefined/convert.nf deleted file mode 100644 index 1c42d7c..0000000 --- a/conf/predefined/convert.nf +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) The nf-core/sopa team - -def convert(v) { - if (v instanceof Map) { - return '[\n' + v.collect { k, val -> "${k}: ${convert(val)}" }.join(', ') + '\n]' - } - if (v instanceof List) { - return '[\n' + v.collect { convert(it) }.join(', ') + '\n]' - } - if (v instanceof String) { - return "'${v.replace("'", "\\'")}'" - } - if (v == null) { - return 'null' - } - return v.toString() -} - -workflow { - def output = params.output - - params.remove('output') - - new File(output).text = "params {\n " + params.collect { k, v -> "${k} = ${convert(v)}" }.join('\n ') + "\n}\n" -} diff --git a/conf/predefined/convert.sh b/conf/predefined/convert.sh deleted file mode 100644 index 3709a4b..0000000 --- a/conf/predefined/convert.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Copyright (c) The nf-core/sopa team -# -# Convert all YAML config files in subdirectories to Nextflow config files -# Needs to set the SOPA_DIR environment variable to the repository root - -if [ -z "${SOPA_DIR:-}" ]; then - echo "Error: SOPA_DIR environment variable is not set. Please clone https://github.com/gustaveroussy/sopa.git and set SOPA_DIR to the repository root." >&2 - exit 1 -fi - -find "$SOPA_DIR/workflow/config" -mindepth 2 -maxdepth 2 -type f -name '*.yaml' | while read -r file; do - parent_dir=$(basename "$(dirname "$file")") - filename=$(basename "$file") - name_no_suffix="${filename%.*}" - output_file="${parent_dir}_${name_no_suffix}.config" - - nextflow run convert.nf -params-file "$file" --output "$output_file" - echo "$output_file generated." -done diff --git a/conf/predefined/convert_list.sh b/conf/predefined/convert_list.sh deleted file mode 100644 index 4fbc4d9..0000000 --- a/conf/predefined/convert_list.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -# Copyright (c) The nf-core/sopa team -# -# List all the predefined config files, to be added to the nextflow.config profiles section - -find . -type f -name '*.config' | while read -r file; do - filename=$(basename "$file") - name_no_suffix="${filename%.*}" - - echo " $name_no_suffix { includeConfig 'conf/predefined/$name_no_suffix.config' }" -done diff --git a/conf/predefined/cosmx_baysor.config b/conf/predefined/cosmx_baysor.config index 1ff1a64..86f3a3b 100644 --- a/conf/predefined/cosmx_baysor.config +++ b/conf/predefined/cosmx_baysor.config @@ -1,45 +1,23 @@ -params { - read = [ - technology: 'cosmx' - ] - patchify = [ - patch_width_microns: 8000, - patch_overlap_microns: 150, - ] - segmentation = [ - baysor: [ - min_area: 2000, - config: [ - data: [ - force_2d: true, - min_molecules_per_cell: 10, - x: 'x', - y: 'y', - z: 'z', - gene: 'target', - min_molecules_per_gene: 0, - min_molecules_per_segment: 3, - confidence_nn_id: 6, - ], - segmentation: [ - scale: 6.25, - scale_std: '25%', - prior_segmentation_confidence: 0, - estimate_scale_from_centers: false, - n_clusters: 4, - iters: 500, - n_cells_init: 0, - nuclei_genes: '', - cyto_genes: '', - ], - ], - ] - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4 - ] +params {// Reader + technology = 'cosmx' + + // Patches + patch_width_microns = 8000 + patch_overlap_microns = 150 + + // Filtering + min_transcripts = 10 + min_area_microns2 = 20 + + // Baysor + use_baysor = true + baysor_scale = 6.25 + min_molecules_per_cell = 10 + min_molecules_per_gene = 0 + min_molecules_per_segment = 3 + confidence_nn_id = 6 + prior_segmentation_confidence = 0 + + // Aggregation + aggregate_channels = true } diff --git a/conf/predefined/cosmx_cellpose.config b/conf/predefined/cosmx_cellpose.config index 3cd7e7d..efbbd3f 100644 --- a/conf/predefined/cosmx_cellpose.config +++ b/conf/predefined/cosmx_cellpose.config @@ -1,27 +1,22 @@ params { - read = [ - technology: 'cosmx' - ] - patchify = [ - patch_width_pixel: 6000, - patch_overlap_pixel: 150, - ] - segmentation = [ - cellpose: [ - diameter: 60, - channels: [ - 'DNA' - ], - flow_threshold: 2, - cellprob_threshold: -6, - min_area: 2000, - ] - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4 - ] + // Reader + technology = 'cosmx' + + // Patches + patch_width_pixel = 6000 + patch_overlap_pixel = 150 + + // Cellpose + use_cellpose = true + cellpose_diameter = 60 + cellpose_channels = 'DNA' + flow_threshold = 2 + cellprob_threshold = -6 + + // Filtering + min_area_pixels2 = 2000 + min_transcripts = 10 + + // Aggregation + aggregate_channels = true } diff --git a/conf/predefined/cosmx_cellpose_baysor.config b/conf/predefined/cosmx_cellpose_baysor.config index 9506b45..debfaa6 100644 --- a/conf/predefined/cosmx_cellpose_baysor.config +++ b/conf/predefined/cosmx_cellpose_baysor.config @@ -1,56 +1,32 @@ -params { - read = [ - technology: 'cosmx' - ] - patchify = [ - patch_width_pixel: 6000, - patch_overlap_pixel: 150, - patch_width_microns: 8000, - patch_overlap_microns: 150, - ] - segmentation = [ - cellpose: [ - diameter: 60, - channels: [ - 'DNA' - ], - flow_threshold: 2, - cellprob_threshold: -6, - min_area: 2000, - ], - baysor: [ - min_area: 2000, - config: [ - data: [ - force_2d: true, - min_molecules_per_cell: 10, - x: 'x', - y: 'y', - z: 'z', - gene: 'target', - min_molecules_per_gene: 0, - min_molecules_per_segment: 3, - confidence_nn_id: 6, - ], - segmentation: [ - scale: 6.25, - scale_std: '25%', - prior_segmentation_confidence: 1, - estimate_scale_from_centers: false, - n_clusters: 4, - iters: 500, - n_cells_init: 0, - nuclei_genes: '', - cyto_genes: '', - ], - ], - ], - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4 - ] +params {// Reader + technology = 'cosmx' + + // Patches + patch_width_pixel = 6000 + patch_overlap_pixel = 150 + patch_width_microns = 8000 + patch_overlap_microns = 150 + + // Cellpose + use_cellpose = true + cellpose_diameter = 60 + cellpose_channels = 'DNA' + flow_threshold = 2 + cellprob_threshold = -6 + + // Baysor + use_baysor = true + baysor_scale = 6.25 + min_molecules_per_cell = 10 + min_molecules_per_gene = 0 + min_molecules_per_segment = 3 + confidence_nn_id = 6 + prior_segmentation_confidence = 1 + + // Filtering + min_transcripts = 10 + min_area_pixels2 = 2000 + + // Aggregation + aggregate_channels = true } diff --git a/conf/predefined/cosmx_proseg.config b/conf/predefined/cosmx_proseg.config index 313bc21..c995365 100644 --- a/conf/predefined/cosmx_proseg.config +++ b/conf/predefined/cosmx_proseg.config @@ -1,21 +1,17 @@ params { - read = [ - technology: 'cosmx' - ] - patchify = [ - patch_width_microns: -1, - patch_overlap_microns: 0, - ] - segmentation = [ - proseg: [ - prior_shapes_key: 'auto' - ] - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4 - ] + // Reader + technology = 'cosmx' + + // Patches + patch_width_microns = -1 + prior_shapes_key = 'auto' + + // Proseg + use_proseg = true + + // Filtering + min_transcripts = 10 + + // Aggregation + aggregate_channels = true } diff --git a/conf/predefined/hyperion_base.config b/conf/predefined/hyperion_base.config index 3a24534..8400743 100644 --- a/conf/predefined/hyperion_base.config +++ b/conf/predefined/hyperion_base.config @@ -1,29 +1,26 @@ params { - read = [ - technology: 'hyperion' - ] - patchify = [ - patch_width_pixel: 3000, - patch_overlap_pixel: 40, - ] - segmentation = [ - cellpose: [ - diameter: 8, - channels: [ - 'DNA1' - ], - flow_threshold: 2, - cellprob_threshold: -6, - min_area: 16, - ] - ] - aggregate = [ - aggregate_channels: true, - min_intensity_ratio: 0.1, - expand_radius_ratio: 0.1, - ] - explorer = [ - ram_threshold_gb: 4, - pixel_size: 1, - ] + // Reader + technology = 'hyperion' + + // Patches + patch_width_pixel = 3000 + patch_overlap_pixel = 40 + + // Cellpose + use_cellpose = true + cellpose_diameter = 8 + cellpose_channels = 'DNA1' + flow_threshold = 2 + cellprob_threshold = -6 + + // Filtering + min_area_pixels2 = 16 + min_intensity_ratio = 0.1 + + // Aggregation + aggregate_channels = true + expand_radius_ratio = 0.1 + + // Explorer + pixel_size = 1 } diff --git a/conf/predefined/macsima_base.config b/conf/predefined/macsima_base.config index 33dcb88..c73a757 100644 --- a/conf/predefined/macsima_base.config +++ b/conf/predefined/macsima_base.config @@ -1,29 +1,26 @@ params { - read = [ - technology: 'macsima' - ] - patchify = [ - patch_width_pixel: 3000, - patch_overlap_pixel: 40, - ] - segmentation = [ - cellpose: [ - diameter: 35, - channels: [ - 'DAPI' - ], - flow_threshold: 2, - cellprob_threshold: -6, - min_area: 400, - ] - ] - aggregate = [ - aggregate_channels: true, - min_intensity_ratio: 0.1, - expand_radius_ratio: 0.1, - ] - explorer = [ - ram_threshold_gb: 4, - pixel_size: 0.17, - ] + // Reader + technology = 'macsima' + + // Patches + patch_width_pixel = 3000 + patch_overlap_pixel = 40 + + // Cellpose + use_cellpose = true + cellpose_diameter = 35 + cellpose_channels = 'DAPI' + flow_threshold = 2 + cellprob_threshold = -6 + + // Filtering + min_area_pixels2 = 400 + min_intensity_ratio = 0.1 + + // Aggregation + aggregate_channels = true + expand_radius_ratio = 0.1 + + // Explorer + pixel_size = 0.17 } diff --git a/conf/predefined/merscope_baysor_cellpose.config b/conf/predefined/merscope_baysor_cellpose.config index a9f80c2..fbf6d58 100644 --- a/conf/predefined/merscope_baysor_cellpose.config +++ b/conf/predefined/merscope_baysor_cellpose.config @@ -1,57 +1,37 @@ params { - read = [ - technology: 'merscope' - ] - patchify = [ - patch_width_pixel: 6000, - patch_overlap_pixel: 150, - patch_width_microns: 1000, - patch_overlap_microns: 20, - ] - segmentation = [ - cellpose: [ - diameter: 60, - channels: [ - 'DAPI' - ], - flow_threshold: 2, - cellprob_threshold: -6, - min_area: 2000, - ], - baysor: [ - min_area: 20, - config: [ - data: [ - force_2d: true, - min_molecules_per_cell: 10, - x: 'x', - y: 'y', - z: 'z', - gene: 'gene', - min_molecules_per_gene: 0, - min_molecules_per_segment: 3, - confidence_nn_id: 6, - ], - segmentation: [ - scale: 6.25, - scale_std: '25%', - prior_segmentation_confidence: 1, - estimate_scale_from_centers: false, - n_clusters: 4, - iters: 500, - n_cells_init: 0, - nuclei_genes: '', - cyto_genes: '', - ], - ], - ], - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4, - pixel_size: 0.108, - ] + // Reader + technology = 'merscope' + + // Patches + patch_width_pixel = 6000 + patch_overlap_pixel = 150 + patch_width_microns = 1000 + patch_overlap_microns = 20 + + // Cellpose + use_cellpose = true + cellpose_diameter = 60 + cellpose_channels = 'DAPI' + flow_threshold = 2 + cellprob_threshold = -6 + + // Baysor + use_baysor = true + baysor_scale = 6.25 + min_molecules_per_cell = 10 + min_molecules_per_gene = 0 + min_molecules_per_segment = 3 + confidence_nn_id = 6 + prior_segmentation_confidence = 1 + + // Filtering + min_area_pixels2 = 2000 + min_area_microns2 = 20 + min_transcripts = 10 + + // Aggregation + aggregate_channels = true + + // Explorer + pixel_size = 0.108 } diff --git a/conf/predefined/merscope_baysor_vizgen.config b/conf/predefined/merscope_baysor_vizgen.config index 3b2349c..5b75b8a 100644 --- a/conf/predefined/merscope_baysor_vizgen.config +++ b/conf/predefined/merscope_baysor_vizgen.config @@ -1,47 +1,27 @@ params { - read = [ - technology: 'merscope' - ] - patchify = [ - patch_width_pixel: 6000, - patch_overlap_pixel: 150, - ] - segmentation = [ - baysor: [ - min_area: 20, - prior_shapes_key: 'auto', - config: [ - data: [ - force_2d: true, - min_molecules_per_cell: 10, - x: 'x', - y: 'y', - z: 'z', - gene: 'gene', - min_molecules_per_gene: 0, - min_molecules_per_segment: 3, - confidence_nn_id: 6, - ], - segmentation: [ - scale: 6.25, - scale_std: '25%', - prior_segmentation_confidence: 0.75, - estimate_scale_from_centers: false, - n_clusters: 4, - iters: 500, - n_cells_init: 0, - nuclei_genes: '', - cyto_genes: '', - ], - ], - ] - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4, - pixel_size: 0.108, - ] + // Reader + technology = 'merscope' + + // Patches + patch_width_pixel = 6000 + patch_overlap_pixel = 150 + prior_shapes_key = 'auto' + + // Baysor + baysor_scale = 6.25 + min_molecules_per_cell = 10 + min_molecules_per_gene = 0 + min_molecules_per_segment = 3 + confidence_nn_id = 6 + prior_segmentation_confidence = 0.75 + + // Filtering + min_area_microns2 = 20 + min_transcripts = 10 + + // Aggregation + aggregate_channels = true + + // Explorer + pixel_size = 0.108 } diff --git a/conf/predefined/merscope_cellpose.config b/conf/predefined/merscope_cellpose.config index fed588e..7fff29d 100644 --- a/conf/predefined/merscope_cellpose.config +++ b/conf/predefined/merscope_cellpose.config @@ -1,28 +1,25 @@ params { - read = [ - technology: 'merscope' - ] - patchify = [ - patch_width_pixel: 6000, - patch_overlap_pixel: 150, - ] - segmentation = [ - cellpose: [ - diameter: 60, - channels: [ - 'DAPI' - ], - flow_threshold: 2, - cellprob_threshold: -6, - min_area: 2000, - ] - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4, - pixel_size: 0.108, - ] + // Reader + technology = 'merscope' + + // Patches + patch_width_pixel = 6000 + patch_overlap_pixel = 150 + + // Cellpose + use_cellpose = true + cellpose_diameter = 60 + cellpose_channels = 'DAPI' + flow_threshold = 2 + cellprob_threshold = -6 + + // Filtering + min_area_pixels2 = 2000 + min_transcripts = 10 + + // Aggregation + aggregate_channels = true + + // Explorer + pixel_size = 0.108 } diff --git a/conf/predefined/merscope_proseg.config b/conf/predefined/merscope_proseg.config index 776f13d..b6627d3 100644 --- a/conf/predefined/merscope_proseg.config +++ b/conf/predefined/merscope_proseg.config @@ -1,22 +1,20 @@ params { - read = [ - technology: 'merscope' - ] - patchify = [ - patch_width_microns: -1, - patch_overlap_microns: 0, - ] - segmentation = [ - proseg: [ - prior_shapes_key: 'auto' - ] - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4, - pixel_size: 0.108, - ] + // Reader + technology = 'merscope' + + // Patches + patch_width_microns = -1 + prior_shapes_key = 'auto' + + // Proseg + use_proseg = true + + // Filtering + min_transcripts = 10 + + // Aggregation + aggregate_channels = true + + // Explorer + pixel_size = 0.108 } diff --git a/conf/predefined/phenocycler_base_10X.config b/conf/predefined/phenocycler_base_10X.config index d04af62..6fd3b01 100644 --- a/conf/predefined/phenocycler_base_10X.config +++ b/conf/predefined/phenocycler_base_10X.config @@ -1,29 +1,26 @@ params { - read = [ - technology: 'phenocycler' - ] - patchify = [ - patch_width_pixel: 3000, - patch_overlap_pixel: 40, - ] - segmentation = [ - cellpose: [ - diameter: 8, - channels: [ - 'DAPI' - ], - flow_threshold: 2, - cellprob_threshold: -6, - min_area: 16, - ] - ] - aggregate = [ - aggregate_channels: true, - min_intensity_ratio: 0.1, - expand_radius_ratio: 0.1, - ] - explorer = [ - ram_threshold_gb: 4, - pixel_size: 1, - ] + // Reader + technology = 'phenocycler' + + // Patches + patch_width_pixel = 3000 + patch_overlap_pixel = 40 + + // Cellpose + use_cellpose = true + cellpose_diameter = 8 + cellpose_channels = 'DAPI' + flow_threshold = 2 + cellprob_threshold = -6 + + // Filtering + min_area_pixels2 = 16 + min_intensity_ratio = 0.1 + + // Aggregation + aggregate_channels = true + expand_radius_ratio = 0.1 + + // Explorer + pixel_size = 1 } diff --git a/conf/predefined/phenocycler_base_20X.config b/conf/predefined/phenocycler_base_20X.config index b2842e3..77fb98f 100644 --- a/conf/predefined/phenocycler_base_20X.config +++ b/conf/predefined/phenocycler_base_20X.config @@ -1,29 +1,26 @@ params { - read = [ - technology: 'phenocycler' - ] - patchify = [ - patch_width_pixel: 3000, - patch_overlap_pixel: 40, - ] - segmentation = [ - cellpose: [ - diameter: 12, - channels: [ - 'DAPI' - ], - flow_threshold: 2, - cellprob_threshold: -6, - min_area: 38, - ] - ] - aggregate = [ - aggregate_channels: true, - min_intensity_ratio: 0.1, - expand_radius_ratio: 0.1, - ] - explorer = [ - ram_threshold_gb: 4, - pixel_size: 0.5, - ] + // Reader + technology = 'phenocycler' + + // Patches + patch_width_pixel = 3000 + patch_overlap_pixel = 40 + + // Cellpose + use_cellpose = true + cellpose_diameter = 12 + cellpose_channels = 'DAPI' + flow_threshold = 2 + cellprob_threshold = -6 + + // Filtering + min_area_pixels2 = 38 + min_intensity_ratio = 0.1 + + // Aggregation + aggregate_channels = true + expand_radius_ratio = 0.1 + + // Explorer + pixel_size = 0.5 } diff --git a/conf/predefined/phenocycler_base_40X.config b/conf/predefined/phenocycler_base_40X.config index ca19a06..a6453c3 100644 --- a/conf/predefined/phenocycler_base_40X.config +++ b/conf/predefined/phenocycler_base_40X.config @@ -1,29 +1,26 @@ params { - read = [ - technology: 'phenocycler' - ] - patchify = [ - patch_width_pixel: 3000, - patch_overlap_pixel: 40, - ] - segmentation = [ - cellpose: [ - diameter: 24, - channels: [ - 'DAPI' - ], - flow_threshold: 2, - cellprob_threshold: -6, - min_area: 120, - ] - ] - aggregate = [ - aggregate_channels: true, - min_intensity_ratio: 0.1, - expand_radius_ratio: 0.1, - ] - explorer = [ - ram_threshold_gb: 4, - pixel_size: 0.25, - ] + // Reader + technology = 'phenocycler' + + // Patches + patch_width_pixel = 3000 + patch_overlap_pixel = 40 + + // Cellpose + use_cellpose = true + cellpose_diameter = 24 + cellpose_channels = 'DAPI' + flow_threshold = 2 + cellprob_threshold = -6 + + // Filtering + min_area_pixels2 = 120 + min_intensity_ratio = 0.1 + + // Aggregation + aggregate_channels = true + expand_radius_ratio = 0.1 + + // Explorer + pixel_size = 0.25 } diff --git a/conf/predefined/visium_hd_stardist.config b/conf/predefined/visium_hd_stardist.config index b963d15..319ff9b 100644 --- a/conf/predefined/visium_hd_stardist.config +++ b/conf/predefined/visium_hd_stardist.config @@ -1,21 +1,18 @@ params { - read = [ - technology: 'visium_hd' - ] - patchify = [ - patch_width_pixel: 2000, - patch_overlap_pixel: 50, - ] - segmentation = [ - stardist: [ - min_area: 30 - ] - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4 - ] + // Reader + technology = 'visium_hd' + + // Patches + patch_width_pixel = 2000 + patch_overlap_pixel = 50 + + // Stardist + use_stardist = true + + // Filtering + min_area_pixels2 = 30 + min_transcripts = 10 + + // Aggregation + aggregate_channels = true } diff --git a/conf/predefined/xenium_baysor.config b/conf/predefined/xenium_baysor.config index 0dbff62..502270d 100644 --- a/conf/predefined/xenium_baysor.config +++ b/conf/predefined/xenium_baysor.config @@ -1,45 +1,24 @@ params { - read = [ - technology: 'xenium' - ] - patchify = [ - patch_width_microns: 1000, - patch_overlap_microns: 20, - ] - segmentation = [ - baysor: [ - min_area: 20, - config: [ - data: [ - force_2d: true, - min_molecules_per_cell: 10, - x: 'x', - y: 'y', - z: 'z', - gene: 'feature_name', - min_molecules_per_gene: 0, - min_molecules_per_segment: 3, - confidence_nn_id: 6, - ], - segmentation: [ - scale: 6.25, - scale_std: '25%', - prior_segmentation_confidence: 0, - estimate_scale_from_centers: false, - n_clusters: 4, - iters: 500, - n_cells_init: 0, - nuclei_genes: '', - cyto_genes: '', - ], - ], - ] - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4 - ] + // Reader + technology = 'xenium' + + // Patches + patch_width_microns = 1000 + patch_overlap_microns = 20 + + // Baysor + use_baysor = true + baysor_scale = 6.25 + min_molecules_per_cell = 10 + min_molecules_per_gene = 0 + min_molecules_per_segment = 3 + confidence_nn_id = 6 + prior_segmentation_confidence = 0 + + // Filtering + min_area_microns2 = 20 + min_transcripts = 10 + + // Aggregation + aggregate_channels = true } diff --git a/conf/predefined/xenium_baysor_prior.config b/conf/predefined/xenium_baysor_prior.config index ac989cd..2ef7439 100644 --- a/conf/predefined/xenium_baysor_prior.config +++ b/conf/predefined/xenium_baysor_prior.config @@ -1,46 +1,25 @@ params { - read = [ - technology: 'xenium' - ] - patchify = [ - patch_width_microns: 1000, - patch_overlap_microns: 20, - ] - segmentation = [ - baysor: [ - min_area: 20, - prior_shapes_key: 'auto', - config: [ - data: [ - force_2d: true, - min_molecules_per_cell: 10, - x: 'x', - y: 'y', - z: 'z', - gene: 'feature_name', - min_molecules_per_gene: 0, - min_molecules_per_segment: 3, - confidence_nn_id: 6, - ], - segmentation: [ - scale: 6.25, - scale_std: '25%', - prior_segmentation_confidence: 0.8, - estimate_scale_from_centers: false, - n_clusters: 4, - iters: 500, - n_cells_init: 0, - nuclei_genes: '', - cyto_genes: '', - ], - ], - ] - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4 - ] + // Reader + technology = 'xenium' + + // Patches + patch_width_microns = 1000 + patch_overlap_microns = 20 + prior_shapes_key = 'auto' + + // Baysor + use_baysor = true + baysor_scale = 6.25 + min_molecules_per_cell = 10 + min_molecules_per_gene = 0 + min_molecules_per_segment = 3 + confidence_nn_id = 6 + prior_segmentation_confidence = 0.8 + + // Filtering + min_area_microns2 = 20 + min_transcripts = 10 + + // Aggregation + aggregate_channels = true } diff --git a/conf/predefined/xenium_baysor_prior_small_cells.config b/conf/predefined/xenium_baysor_prior_small_cells.config index 52af923..ca3670b 100644 --- a/conf/predefined/xenium_baysor_prior_small_cells.config +++ b/conf/predefined/xenium_baysor_prior_small_cells.config @@ -1,46 +1,25 @@ params { - read = [ - technology: 'xenium' - ] - patchify = [ - patch_width_microns: 1000, - patch_overlap_microns: 20, - ] - segmentation = [ - baysor: [ - min_area: 20, - prior_shapes_key: 'auto', - config: [ - data: [ - force_2d: true, - min_molecules_per_cell: 10, - x: 'x', - y: 'y', - z: 'z', - gene: 'feature_name', - min_molecules_per_gene: 0, - min_molecules_per_segment: 3, - confidence_nn_id: 6, - ], - segmentation: [ - scale: 4, - scale_std: '25%', - prior_segmentation_confidence: 0.8, - estimate_scale_from_centers: false, - n_clusters: 4, - iters: 500, - n_cells_init: 0, - nuclei_genes: '', - cyto_genes: '', - ], - ], - ] - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4 - ] + // Reader + technology = 'xenium' + + // Patches + patch_width_microns = 1000 + patch_overlap_microns = 20 + prior_shapes_key = 'auto' + + // Baysor + use_baysor = true + baysor_scale = 4 + min_molecules_per_cell = 10 + min_molecules_per_gene = 0 + min_molecules_per_segment = 3 + confidence_nn_id = 6 + prior_segmentation_confidence = 0.8 + + // Filtering + min_area_microns2 = 20 + min_transcripts = 10 + + // Aggregation + aggregate_channels = true } diff --git a/conf/predefined/xenium_cellpose.config b/conf/predefined/xenium_cellpose.config index 9449777..4d78a58 100644 --- a/conf/predefined/xenium_cellpose.config +++ b/conf/predefined/xenium_cellpose.config @@ -1,27 +1,22 @@ params { - read = [ - technology: 'xenium' - ] - patchify = [ - patch_width_pixel: 6000, - patch_overlap_pixel: 150, - ] - segmentation = [ - cellpose: [ - diameter: 30, - channels: [ - 'DAPI' - ], - flow_threshold: 2, - cellprob_threshold: -6, - min_area: 400, - ] - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4 - ] + // Reader + technology = 'xenium' + + // Patches + patch_width_pixel = 6000 + patch_overlap_pixel = 150 + + // Cellpose + use_cellpose = true + cellpose_diameter = 30 + cellpose_channels = 'DAPI' + flow_threshold = 2 + cellprob_threshold = -6 + + // Filtering + min_area_pixels2 = 400 + min_transcripts = 10 + + // Aggregation + aggregate_channels = true } diff --git a/conf/predefined/xenium_cellpose_baysor.config b/conf/predefined/xenium_cellpose_baysor.config index 42b53dd..7c0bb39 100644 --- a/conf/predefined/xenium_cellpose_baysor.config +++ b/conf/predefined/xenium_cellpose_baysor.config @@ -1,56 +1,33 @@ params { - read = [ - technology: 'xenium' - ] - patchify = [ - patch_width_pixel: 6000, - patch_overlap_pixel: 150, - patch_width_microns: 1000, - patch_overlap_microns: 20, - ] - segmentation = [ - cellpose: [ - diameter: 30, - channels: [ - 'DAPI' - ], - flow_threshold: 2, - cellprob_threshold: -6, - min_area: 400, - ], - baysor: [ - min_area: 20, - config: [ - data: [ - force_2d: true, - min_molecules_per_cell: 10, - x: 'x', - y: 'y', - z: 'z', - gene: 'feature_name', - min_molecules_per_gene: 0, - min_molecules_per_segment: 3, - confidence_nn_id: 6, - ], - segmentation: [ - scale: 6.25, - scale_std: '25%', - prior_segmentation_confidence: 1, - estimate_scale_from_centers: false, - n_clusters: 4, - iters: 500, - n_cells_init: 0, - nuclei_genes: '', - cyto_genes: '', - ], - ], - ], - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4 - ] + // Reader + technology = 'xenium' + + // Patches + patch_width_pixel = 6000 + patch_overlap_pixel = 150 + patch_width_microns = 1000 + patch_overlap_microns = 20 + + // Cellpose + use_cellpose = true + cellpose_diameter = 30 + cellpose_channels = 'DAPI' + flow_threshold = 2 + cellprob_threshold = -6 + + // Baysor + baysor_scale = 6.25 + min_molecules_per_cell = 10 + min_molecules_per_gene = 0 + min_molecules_per_segment = 3 + confidence_nn_id = 6 + prior_segmentation_confidence = 1 + + // Filtering + min_transcripts = 10 + min_area_pixels2 = 400 + min_area_microns2 = 20 + + // Aggregation + aggregate_channels = true } diff --git a/conf/predefined/xenium_proseg.config b/conf/predefined/xenium_proseg.config index e5729e0..22533c6 100644 --- a/conf/predefined/xenium_proseg.config +++ b/conf/predefined/xenium_proseg.config @@ -1,21 +1,17 @@ params { - read = [ - technology: 'xenium' - ] - patchify = [ - patch_width_microns: -1, - patch_overlap_microns: 0, - ] - segmentation = [ - proseg: [ - prior_shapes_key: 'auto' - ] - ] - aggregate = [ - aggregate_channels: true, - min_transcripts: 10, - ] - explorer = [ - ram_threshold_gb: 4 - ] + // Reader + technology = 'xenium' + + // Patches + patch_width_microns = -1 + prior_shapes_key = 'auto' + + // Proseg + use_proseg = true + + // Filtering + min_transcripts = 10 + + // Aggregation + aggregate_channels = true } diff --git a/conf/test_baysor.config b/conf/test_baysor.config index ad44e6f..14c37b7 100644 --- a/conf/test_baysor.config +++ b/conf/test_baysor.config @@ -35,7 +35,6 @@ params { // Baysor segmentation use_baysor = true baysor_scale = 3 - baysor_scale_std = "25%" min_molecules_per_cell = 10 min_molecules_per_gene = 0 min_molecules_per_segment = 3 @@ -43,7 +42,7 @@ params { prior_segmentation_confidence = 0 // Filtering - min_area = 10 + min_area_microns2 = 10 min_transcripts = 5 // Agregation diff --git a/conf/test_cellpose.config b/conf/test_cellpose.config index 0d7c356..e17187d 100644 --- a/conf/test_cellpose.config +++ b/conf/test_cellpose.config @@ -40,7 +40,7 @@ params { cellprob_threshold = -6 // Filtering - min_area = 2500 + min_area_pixels2 = 2500 // Aggregation aggregate_channels = true diff --git a/conf/test_cellpose_CK_DAPI.config b/conf/test_cellpose_CK_DAPI.config index d358512..c18abf0 100644 --- a/conf/test_cellpose_CK_DAPI.config +++ b/conf/test_cellpose_CK_DAPI.config @@ -40,7 +40,7 @@ params { cellprob_threshold = -6 // Filtering - min_area = 2500 + min_area_pixels2 = 2500 // Aggregation aggregate_channels = true diff --git a/conf/test_comseg.config b/conf/test_comseg.config index 880bb8e..974ab20 100644 --- a/conf/test_comseg.config +++ b/conf/test_comseg.config @@ -41,7 +41,7 @@ params { min_rna_per_cell = 5 // Filtering - min_area = 10 + min_area_microns2 = 10 min_transcripts = 5 // Aggregation diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 0132a5b..0df0f6d 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -49,7 +49,7 @@ def extractSubArgs(Map args, String group) { model_type: args.cellpose_model_type, pretrained_model: args.pretrained_model, gpu: args.cellpose_use_gpu, - min_area: args.min_area, + min_area: args.min_area_pixels2, clip_limit: args.clip_limit, clahe_kernel_size: args.clahe_kernel_size, gaussian_sigma: args.gaussian_sigma, @@ -61,7 +61,7 @@ def extractSubArgs(Map args, String group) { prob_thresh: args.prob_thresh, nms_thresh: args.nms_thresh, channels: getChannels(args.stardist_channels, true), - min_area: args.min_area, + min_area: args.min_area_pixels2, clip_limit: args.clip_limit, clahe_kernel_size: args.clahe_kernel_size, gaussian_sigma: args.gaussian_sigma, @@ -86,7 +86,7 @@ def extractSubArgs(Map args, String group) { prior_segmentation_confidence: args.prior_segmentation_confidence, ], ], - min_area: args.min_area, + min_area: args.min_area_microns2, ] } else if (group == "comseg") { return [ @@ -103,7 +103,7 @@ def extractSubArgs(Map args, String group) { alpha: args.alpha, min_rna_per_cell: args.min_rna_per_cell, ], - min_area: args.min_area, + min_area: args.min_area_microns2, ] } else if (group == "aggregate") { return [ @@ -121,7 +121,7 @@ def extractSubArgs(Map args, String group) { ] } else if (group == "resolve") { return [ - min_area: args.min_area, + min_area: args.min_area_microns2, ] } else if (group == "transcript_patches") { return [ diff --git a/nextflow.config b/nextflow.config index d4b2a84..fc199d3 100644 --- a/nextflow.config +++ b/nextflow.config @@ -95,7 +95,8 @@ params { marker_cell_dict = null // Cell filtering options - min_area = 0 + min_area_pixels2 = 0 + min_area_microns2 = 0 min_transcripts = null min_intensity_ratio = null diff --git a/nextflow_schema.json b/nextflow_schema.json index 2f4f694..9caedff 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -291,9 +291,14 @@ "description": "Filtering low-quality cells during and after segmentation", "default": "", "properties": { - "min_area": { + "min_area_pixels2": { "type": "number", - "description": "Cells with an area less than this value will be filtered. The unit is in microns^2 for Baysor/Comseg, and in pixels^2 for Stardist/Cellpose. Not used for Proseg.", + "description": "Cells with an area less than this value will be filtered. The unit is in pixels^2, and used by Stardist/Cellpose.", + "default": 0.0 + }, + "min_area_microns2": { + "type": "number", + "description": "Cells with an area less than this value will be filtered. The unit is in microns^2, and used by Baysor/Comseg. Not used by Proseg.", "default": 0.0 }, "min_transcripts": { From 9115df10dda6a548e427b68ccac336e0c0f5de28 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 19 Dec 2025 11:07:27 +0100 Subject: [PATCH 212/227] use sopa 2.1.11 version --- conf/predefined/cosmx_baysor.config | 3 ++- conf/predefined/cosmx_cellpose_baysor.config | 3 ++- conf/predefined/merscope_baysor_vizgen.config | 1 + conf/predefined/xenium_cellpose_baysor.config | 1 + modules/local/aggregate/main.nf | 4 ++-- modules/local/explorer/main.nf | 4 ++-- modules/local/explorer_raw/main.nf | 4 ++-- modules/local/fluo_annotation/main.nf | 4 ++-- modules/local/make_image_patches/main.nf | 4 ++-- modules/local/make_transcript_patches/main.nf | 4 ++-- modules/local/patch_segmentation_baysor/main.nf | 4 ++-- modules/local/patch_segmentation_cellpose/main.nf | 4 ++-- modules/local/patch_segmentation_comseg/main.nf | 4 ++-- modules/local/patch_segmentation_proseg/main.nf | 4 ++-- modules/local/patch_segmentation_stardist/main.nf | 4 ++-- modules/local/report/main.nf | 4 ++-- modules/local/resolve_baysor/main.nf | 4 ++-- modules/local/resolve_cellpose/main.nf | 4 ++-- modules/local/resolve_comseg/main.nf | 4 ++-- modules/local/resolve_stardist/main.nf | 4 ++-- modules/local/scanpy_preprocess/main.nf | 4 ++-- modules/local/tangram_annotation/main.nf | 4 ++-- modules/local/tissue_segmentation/main.nf | 4 ++-- modules/local/to_spatialdata/main.nf | 4 ++-- 24 files changed, 46 insertions(+), 42 deletions(-) diff --git a/conf/predefined/cosmx_baysor.config b/conf/predefined/cosmx_baysor.config index 86f3a3b..be736a0 100644 --- a/conf/predefined/cosmx_baysor.config +++ b/conf/predefined/cosmx_baysor.config @@ -1,4 +1,5 @@ -params {// Reader +params { + // Reader technology = 'cosmx' // Patches diff --git a/conf/predefined/cosmx_cellpose_baysor.config b/conf/predefined/cosmx_cellpose_baysor.config index debfaa6..bb62b53 100644 --- a/conf/predefined/cosmx_cellpose_baysor.config +++ b/conf/predefined/cosmx_cellpose_baysor.config @@ -1,4 +1,5 @@ -params {// Reader +params { + // Reader technology = 'cosmx' // Patches diff --git a/conf/predefined/merscope_baysor_vizgen.config b/conf/predefined/merscope_baysor_vizgen.config index 5b75b8a..338d640 100644 --- a/conf/predefined/merscope_baysor_vizgen.config +++ b/conf/predefined/merscope_baysor_vizgen.config @@ -8,6 +8,7 @@ params { prior_shapes_key = 'auto' // Baysor + use_baysor = true baysor_scale = 6.25 min_molecules_per_cell = 10 min_molecules_per_gene = 0 diff --git a/conf/predefined/xenium_cellpose_baysor.config b/conf/predefined/xenium_cellpose_baysor.config index 7c0bb39..67aa3fa 100644 --- a/conf/predefined/xenium_cellpose_baysor.config +++ b/conf/predefined/xenium_cellpose_baysor.config @@ -16,6 +16,7 @@ params { cellprob_threshold = -6 // Baysor + use_baysor = true baysor_scale = 6.25 min_molecules_per_cell = 10 min_molecules_per_gene = 0 diff --git a/modules/local/aggregate/main.nf b/modules/local/aggregate/main.nf index 2b5da49..dc58458 100644 --- a/modules/local/aggregate/main.nf +++ b/modules/local/aggregate/main.nf @@ -3,8 +3,8 @@ process AGGREGATE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.11' + : 'docker.io/quentinblampey/sopa:2.1.11'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/explorer/main.nf b/modules/local/explorer/main.nf index 307da53..552cb6d 100644 --- a/modules/local/explorer/main.nf +++ b/modules/local/explorer/main.nf @@ -3,8 +3,8 @@ process EXPLORER { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.11' + : 'docker.io/quentinblampey/sopa:2.1.11'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/explorer_raw/main.nf b/modules/local/explorer_raw/main.nf index 1ce5e2e..05a1e9d 100644 --- a/modules/local/explorer_raw/main.nf +++ b/modules/local/explorer_raw/main.nf @@ -5,8 +5,8 @@ process EXPLORER_RAW { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.11' + : 'docker.io/quentinblampey/sopa:2.1.11'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/fluo_annotation/main.nf b/modules/local/fluo_annotation/main.nf index 3608926..06c5a74 100644 --- a/modules/local/fluo_annotation/main.nf +++ b/modules/local/fluo_annotation/main.nf @@ -3,8 +3,8 @@ process FLUO_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.11' + : 'docker.io/quentinblampey/sopa:2.1.11'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_image_patches/main.nf b/modules/local/make_image_patches/main.nf index fdae2e0..3aa98b2 100644 --- a/modules/local/make_image_patches/main.nf +++ b/modules/local/make_image_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_IMAGE_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.11' + : 'docker.io/quentinblampey/sopa:2.1.11'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/make_transcript_patches/main.nf b/modules/local/make_transcript_patches/main.nf index 78c0d60..080caa8 100644 --- a/modules/local/make_transcript_patches/main.nf +++ b/modules/local/make_transcript_patches/main.nf @@ -3,8 +3,8 @@ process MAKE_TRANSCRIPT_PATCHES { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.11' + : 'docker.io/quentinblampey/sopa:2.1.11'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/patch_segmentation_baysor/main.nf b/modules/local/patch_segmentation_baysor/main.nf index ae529a9..3998483 100644 --- a/modules/local/patch_segmentation_baysor/main.nf +++ b/modules/local/patch_segmentation_baysor/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-baysor' - : 'docker.io/quentinblampey/sopa:2.1.9-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.11-baysor' + : 'docker.io/quentinblampey/sopa:2.1.11-baysor'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_cellpose/main.nf b/modules/local/patch_segmentation_cellpose/main.nf index 55e4391..10f935c 100644 --- a/modules/local/patch_segmentation_cellpose/main.nf +++ b/modules/local/patch_segmentation_cellpose/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.9-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.11-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.11-cellpose'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_comseg/main.nf b/modules/local/patch_segmentation_comseg/main.nf index 48ce4be..15e0d93 100644 --- a/modules/local/patch_segmentation_comseg/main.nf +++ b/modules/local/patch_segmentation_comseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-comseg' - : 'docker.io/quentinblampey/sopa:2.1.9-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.11-comseg' + : 'docker.io/quentinblampey/sopa:2.1.11-comseg'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/patch_segmentation_proseg/main.nf b/modules/local/patch_segmentation_proseg/main.nf index c3d13d4..072d3de 100644 --- a/modules/local/patch_segmentation_proseg/main.nf +++ b/modules/local/patch_segmentation_proseg/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_PROSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-proseg' - : 'docker.io/quentinblampey/sopa:2.1.9-proseg'}" + ? 'docker://quentinblampey/sopa:2.1.11-proseg' + : 'docker.io/quentinblampey/sopa:2.1.11-proseg'}" input: tuple val(meta), path(sdata_path), path(patches_file_transcripts), path(transcript_patches) diff --git a/modules/local/patch_segmentation_stardist/main.nf b/modules/local/patch_segmentation_stardist/main.nf index 0761e07..5598c90 100644 --- a/modules/local/patch_segmentation_stardist/main.nf +++ b/modules/local/patch_segmentation_stardist/main.nf @@ -3,8 +3,8 @@ process PATCH_SEGMENTATION_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-stardist' - : 'docker.io/quentinblampey/sopa:2.1.9-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.11-stardist' + : 'docker.io/quentinblampey/sopa:2.1.11-stardist'}" input: tuple val(meta), path(sdata_path), val(cli_arguments), val(index), val(n_patches) diff --git a/modules/local/report/main.nf b/modules/local/report/main.nf index b68af19..aa7b406 100644 --- a/modules/local/report/main.nf +++ b/modules/local/report/main.nf @@ -3,8 +3,8 @@ process REPORT { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.11' + : 'docker.io/quentinblampey/sopa:2.1.11'}" publishDir "${params.outdir}", mode: params.publish_dir_mode diff --git a/modules/local/resolve_baysor/main.nf b/modules/local/resolve_baysor/main.nf index fb16778..0ffb944 100644 --- a/modules/local/resolve_baysor/main.nf +++ b/modules/local/resolve_baysor/main.nf @@ -3,8 +3,8 @@ process RESOLVE_BAYSOR { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-baysor' - : 'docker.io/quentinblampey/sopa:2.1.9-baysor'}" + ? 'docker://quentinblampey/sopa:2.1.11-baysor' + : 'docker.io/quentinblampey/sopa:2.1.11-baysor'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_cellpose/main.nf b/modules/local/resolve_cellpose/main.nf index 3af7531..50acff3 100644 --- a/modules/local/resolve_cellpose/main.nf +++ b/modules/local/resolve_cellpose/main.nf @@ -3,8 +3,8 @@ process RESOLVE_CELLPOSE { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-cellpose' - : 'docker.io/quentinblampey/sopa:2.1.9-cellpose'}" + ? 'docker://quentinblampey/sopa:2.1.11-cellpose' + : 'docker.io/quentinblampey/sopa:2.1.11-cellpose'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_comseg/main.nf b/modules/local/resolve_comseg/main.nf index a4ddaeb..2ed4a1b 100644 --- a/modules/local/resolve_comseg/main.nf +++ b/modules/local/resolve_comseg/main.nf @@ -3,8 +3,8 @@ process RESOLVE_COMSEG { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-comseg' - : 'docker.io/quentinblampey/sopa:2.1.9-comseg'}" + ? 'docker://quentinblampey/sopa:2.1.11-comseg' + : 'docker.io/quentinblampey/sopa:2.1.11-comseg'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/resolve_stardist/main.nf b/modules/local/resolve_stardist/main.nf index 1340847..08016c3 100644 --- a/modules/local/resolve_stardist/main.nf +++ b/modules/local/resolve_stardist/main.nf @@ -3,8 +3,8 @@ process RESOLVE_STARDIST { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-stardist' - : 'docker.io/quentinblampey/sopa:2.1.9-stardist'}" + ? 'docker://quentinblampey/sopa:2.1.11-stardist' + : 'docker.io/quentinblampey/sopa:2.1.11-stardist'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/scanpy_preprocess/main.nf b/modules/local/scanpy_preprocess/main.nf index bbb8c2b..48e10db 100644 --- a/modules/local/scanpy_preprocess/main.nf +++ b/modules/local/scanpy_preprocess/main.nf @@ -3,8 +3,8 @@ process SCANPY_PREPROCESS { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.11' + : 'docker.io/quentinblampey/sopa:2.1.11'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tangram_annotation/main.nf b/modules/local/tangram_annotation/main.nf index f9a7e80..0542b39 100644 --- a/modules/local/tangram_annotation/main.nf +++ b/modules/local/tangram_annotation/main.nf @@ -3,8 +3,8 @@ process TANGRAM_ANNOTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9-tangram' - : 'docker.io/quentinblampey/sopa:2.1.9-tangram'}" + ? 'docker://quentinblampey/sopa:2.1.11-tangram' + : 'docker.io/quentinblampey/sopa:2.1.11-tangram'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/tissue_segmentation/main.nf b/modules/local/tissue_segmentation/main.nf index 046dc44..fb3b34a 100644 --- a/modules/local/tissue_segmentation/main.nf +++ b/modules/local/tissue_segmentation/main.nf @@ -3,8 +3,8 @@ process TISSUE_SEGMENTATION { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.11' + : 'docker.io/quentinblampey/sopa:2.1.11'}" input: tuple val(meta), path(sdata_path) diff --git a/modules/local/to_spatialdata/main.nf b/modules/local/to_spatialdata/main.nf index b322c73..af18d2f 100644 --- a/modules/local/to_spatialdata/main.nf +++ b/modules/local/to_spatialdata/main.nf @@ -5,8 +5,8 @@ process TO_SPATIALDATA { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'apptainer' && !task.ext.singularity_pull_docker_container - ? 'docker://quentinblampey/sopa:2.1.9' - : 'docker.io/quentinblampey/sopa:2.1.9'}" + ? 'docker://quentinblampey/sopa:2.1.11' + : 'docker.io/quentinblampey/sopa:2.1.11'}" input: tuple val(meta), path(data_dir), path(fullres_image_file) From 2389e61e3571e49a6bf259b945e6e07d357335a1 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 19 Dec 2025 12:27:18 +0100 Subject: [PATCH 213/227] update snapshots --- tests/baysor.nf.test.snap | 8 +++--- tests/cellpose.nf.test.snap | 6 ++--- tests/default.nf.test.snap | 54 ++++--------------------------------- 3 files changed, 12 insertions(+), 56 deletions(-) diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index ec571dc..d044633 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -4,15 +4,15 @@ 9, { "RESOLVE_BAYSOR": { - "sopa": "2.1.9", + "sopa": "2.1.11", "baysor": "0.7.1" }, "TANGRAM_ANNOTATION": { - "sopa": "2.1.9", + "sopa": "2.1.11", "tangram": "1.0.4" }, "TO_SPATIALDATA": { - "sopa": "2.1.9", + "sopa": "2.1.11", "spatialdata": "0.5.0", "spatialdata_io": "0.5.1" }, @@ -359,6 +359,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-15T11:14:18.110413" + "timestamp": "2025-12-19T11:10:10.223067" } } \ No newline at end of file diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index 4b76d0d..f3924e5 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -4,11 +4,11 @@ 8, { "RESOLVE_CELLPOSE": { - "sopa": "2.1.9", + "sopa": "2.1.11", "cellpose": "4.0.7" }, "TO_SPATIALDATA": { - "sopa": "2.1.9", + "sopa": "2.1.11", "spatialdata": "0.5.0", "spatialdata_io": "0.5.1" }, @@ -284,6 +284,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-08-01T16:10:22.8482" + "timestamp": "2025-12-19T11:30:36.152793" } } \ No newline at end of file diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 63577d6..48be043 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -3,18 +3,18 @@ "content": [ { "FLUO_ANNOTATION": { - "sopa": "2.1.9" + "sopa": "2.1.11" }, "PATCH_SEGMENTATION_PROSEG": { - "sopa": "2.1.9", + "sopa": "2.1.11", "proseg": "3.0.11" }, "SCANPY_PREPROCESS": { - "sopa": "2.1.9", + "sopa": "2.1.11", "scanpy": "1.11.5" }, "TO_SPATIALDATA": { - "sopa": "2.1.9", + "sopa": "2.1.11", "spatialdata": "0.5.0", "spatialdata_io": "0.5.1" }, @@ -256,11 +256,6 @@ "sample_name.zarr/tables/table/obsm", "sample_name.zarr/tables/table/obsm/.zattrs", "sample_name.zarr/tables/table/obsm/.zgroup", - "sample_name.zarr/tables/table/obsm/X_pca", - "sample_name.zarr/tables/table/obsm/X_pca/.zarray", - "sample_name.zarr/tables/table/obsm/X_pca/.zattrs", - "sample_name.zarr/tables/table/obsm/X_pca/0", - "sample_name.zarr/tables/table/obsm/X_pca/0/0", "sample_name.zarr/tables/table/obsm/X_umap", "sample_name.zarr/tables/table/obsm/X_umap/.zarray", "sample_name.zarr/tables/table/obsm/X_umap/.zattrs", @@ -344,10 +339,6 @@ "sample_name.zarr/tables/table/obsp/distances/indptr", "sample_name.zarr/tables/table/obsp/distances/indptr/.zarray", "sample_name.zarr/tables/table/obsp/distances/indptr/0", - "sample_name.zarr/tables/table/raw", - "sample_name.zarr/tables/table/raw/.zarray", - "sample_name.zarr/tables/table/raw/.zattrs", - "sample_name.zarr/tables/table/raw/0", "sample_name.zarr/tables/table/uns", "sample_name.zarr/tables/table/uns/.zattrs", "sample_name.zarr/tables/table/uns/.zgroup", @@ -372,10 +363,6 @@ "sample_name.zarr/tables/table/uns/log1p", "sample_name.zarr/tables/table/uns/log1p/.zattrs", "sample_name.zarr/tables/table/uns/log1p/.zgroup", - "sample_name.zarr/tables/table/uns/log1p/base", - "sample_name.zarr/tables/table/uns/log1p/base/.zarray", - "sample_name.zarr/tables/table/uns/log1p/base/.zattrs", - "sample_name.zarr/tables/table/uns/log1p/base/0", "sample_name.zarr/tables/table/uns/neighbors", "sample_name.zarr/tables/table/uns/neighbors/.zattrs", "sample_name.zarr/tables/table/uns/neighbors/.zgroup", @@ -406,32 +393,6 @@ "sample_name.zarr/tables/table/uns/neighbors/params/random_state/.zarray", "sample_name.zarr/tables/table/uns/neighbors/params/random_state/.zattrs", "sample_name.zarr/tables/table/uns/neighbors/params/random_state/0", - "sample_name.zarr/tables/table/uns/pca", - "sample_name.zarr/tables/table/uns/pca/.zattrs", - "sample_name.zarr/tables/table/uns/pca/.zgroup", - "sample_name.zarr/tables/table/uns/pca/params", - "sample_name.zarr/tables/table/uns/pca/params/.zattrs", - "sample_name.zarr/tables/table/uns/pca/params/.zgroup", - "sample_name.zarr/tables/table/uns/pca/params/mask_var", - "sample_name.zarr/tables/table/uns/pca/params/mask_var/.zarray", - "sample_name.zarr/tables/table/uns/pca/params/mask_var/.zattrs", - "sample_name.zarr/tables/table/uns/pca/params/mask_var/0", - "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable", - "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/.zarray", - "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/.zattrs", - "sample_name.zarr/tables/table/uns/pca/params/use_highly_variable/0", - "sample_name.zarr/tables/table/uns/pca/params/zero_center", - "sample_name.zarr/tables/table/uns/pca/params/zero_center/.zarray", - "sample_name.zarr/tables/table/uns/pca/params/zero_center/.zattrs", - "sample_name.zarr/tables/table/uns/pca/params/zero_center/0", - "sample_name.zarr/tables/table/uns/pca/variance", - "sample_name.zarr/tables/table/uns/pca/variance/.zarray", - "sample_name.zarr/tables/table/uns/pca/variance/.zattrs", - "sample_name.zarr/tables/table/uns/pca/variance/0", - "sample_name.zarr/tables/table/uns/pca/variance_ratio", - "sample_name.zarr/tables/table/uns/pca/variance_ratio/.zarray", - "sample_name.zarr/tables/table/uns/pca/variance_ratio/.zattrs", - "sample_name.zarr/tables/table/uns/pca/variance_ratio/0", "sample_name.zarr/tables/table/uns/proseg_run", "sample_name.zarr/tables/table/uns/proseg_run/.zattrs", "sample_name.zarr/tables/table/uns/proseg_run/.zgroup", @@ -513,11 +474,6 @@ "sample_name.zarr/tables/table/varm", "sample_name.zarr/tables/table/varm/.zattrs", "sample_name.zarr/tables/table/varm/.zgroup", - "sample_name.zarr/tables/table/varm/PCs", - "sample_name.zarr/tables/table/varm/PCs/.zarray", - "sample_name.zarr/tables/table/varm/PCs/.zattrs", - "sample_name.zarr/tables/table/varm/PCs/0", - "sample_name.zarr/tables/table/varm/PCs/0/0", "sample_name.zarr/tables/table/varp", "sample_name.zarr/tables/table/varp/.zattrs", "sample_name.zarr/tables/table/varp/.zgroup", @@ -541,6 +497,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-15T11:11:22.043613" + "timestamp": "2025-12-19T12:22:58.714199" } } \ No newline at end of file From 314f710f536a6f479eada9c146a9d76757aca2f7 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 19 Dec 2025 15:05:24 +0100 Subject: [PATCH 214/227] update snapshots and docs --- README.md | 5 ++--- docs/usage.md | 4 ++-- tests/baysor.nf.test.snap | 2 +- tests/cellpose.nf.test.snap | 4 ++-- tests/default.nf.test.snap | 24 ++++++++++++++++++++++-- 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index b6923ef..0a3b1fc 100644 --- a/README.md +++ b/README.md @@ -58,15 +58,14 @@ SAMPLE2,/path/to/one/merscope_directory > [!WARNING] > If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters). -Then, choose the Sopa parameters. You can find existing Sopa params files [here](https://github.com/gustaveroussy/sopa/tree/main/workflow/config), and follow the [corresponding README instructions](https://github.com/gustaveroussy/sopa/blob/main/workflow/config/README.md) of to get your `-params-file` argument. +Then, choose the Sopa parameters. To do that, you can provide an existing `-profile` containing all the dedicated Sopa parameters, depending on your technology, see the [available technology-specific profiles here](https://nf-co.re/sopa/dev/docs/usage/#sopa-parameters). Now, you can run the pipeline using: ```bash nextflow run nf-core/sopa \ - -profile \ + -profile , \ --input samplesheet.csv \ - -params-file \ --outdir ``` diff --git a/docs/usage.md b/docs/usage.md index 543d9d3..17be97e 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -123,10 +123,10 @@ You'll also need to choose some Sopa parameters to decide which reader/segmentat ## Running the pipeline -Once you have defined your samplesheet and `params-file`, you'll be able to run `nf-core/sopa`. The typical command for running the pipeline is as follows: +Once you have defined your samplesheet and technology `profile`, you'll be able to run `nf-core/sopa`. The typical command for running the pipeline is as follows: ```bash -nextflow run nf-core/sopa --input ./samplesheet.csv -params-file --outdir ./results -profile docker +nextflow run nf-core/sopa --input ./samplesheet.csv --outdir ./results -profile docker, ``` > [!NOTE] diff --git a/tests/baysor.nf.test.snap b/tests/baysor.nf.test.snap index 7082384..fe4582c 100644 --- a/tests/baysor.nf.test.snap +++ b/tests/baysor.nf.test.snap @@ -359,6 +359,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-19T11:10:10.223067" + "timestamp": "2025-12-19T12:52:56.282277" } } \ No newline at end of file diff --git a/tests/cellpose.nf.test.snap b/tests/cellpose.nf.test.snap index ef8bb27..77f46aa 100644 --- a/tests/cellpose.nf.test.snap +++ b/tests/cellpose.nf.test.snap @@ -5,7 +5,7 @@ { "RESOLVE_CELLPOSE": { "sopa": "2.1.11", - "cellpose": "4.0.7" + "cellpose": "4.0.8" }, "TO_SPATIALDATA": { "sopa": "2.1.11", @@ -284,6 +284,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-19T11:30:36.152793" + "timestamp": "2025-12-19T13:13:34.065435" } } \ No newline at end of file diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index d6842ab..7d31bf3 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -7,7 +7,7 @@ }, "PATCH_SEGMENTATION_PROSEG": { "sopa": "2.1.11", - "proseg": "3.0.11" + "proseg": "3.0.12" }, "SCANPY_PREPROCESS": { "sopa": "2.1.11", @@ -339,6 +339,22 @@ "sample_name.zarr/tables/table/obsp/distances/indptr", "sample_name.zarr/tables/table/obsp/distances/indptr/.zarray", "sample_name.zarr/tables/table/obsp/distances/indptr/0", + "sample_name.zarr/tables/table/obsp/transition_counts", + "sample_name.zarr/tables/table/obsp/transition_counts/.zattrs", + "sample_name.zarr/tables/table/obsp/transition_counts/.zgroup", + "sample_name.zarr/tables/table/obsp/transition_counts/data", + "sample_name.zarr/tables/table/obsp/transition_counts/data/.zarray", + "sample_name.zarr/tables/table/obsp/transition_counts/data/0", + "sample_name.zarr/tables/table/obsp/transition_counts/indices", + "sample_name.zarr/tables/table/obsp/transition_counts/indices/.zarray", + "sample_name.zarr/tables/table/obsp/transition_counts/indices/0", + "sample_name.zarr/tables/table/obsp/transition_counts/indptr", + "sample_name.zarr/tables/table/obsp/transition_counts/indptr/.zarray", + "sample_name.zarr/tables/table/obsp/transition_counts/indptr/0", + "sample_name.zarr/tables/table/raw", + "sample_name.zarr/tables/table/raw/.zarray", + "sample_name.zarr/tables/table/raw/.zattrs", + "sample_name.zarr/tables/table/raw/0", "sample_name.zarr/tables/table/uns", "sample_name.zarr/tables/table/uns/.zattrs", "sample_name.zarr/tables/table/uns/.zgroup", @@ -363,6 +379,10 @@ "sample_name.zarr/tables/table/uns/log1p", "sample_name.zarr/tables/table/uns/log1p/.zattrs", "sample_name.zarr/tables/table/uns/log1p/.zgroup", + "sample_name.zarr/tables/table/uns/log1p/base", + "sample_name.zarr/tables/table/uns/log1p/base/.zarray", + "sample_name.zarr/tables/table/uns/log1p/base/.zattrs", + "sample_name.zarr/tables/table/uns/log1p/base/0", "sample_name.zarr/tables/table/uns/neighbors", "sample_name.zarr/tables/table/uns/neighbors/.zattrs", "sample_name.zarr/tables/table/uns/neighbors/.zgroup", @@ -497,6 +517,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-19T12:22:58.714199" + "timestamp": "2025-12-19T15:00:26.838435" } } \ No newline at end of file From 145d6eed5178b877fac5dc4c1bdc1446935233b9 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 19 Dec 2025 15:06:33 +0100 Subject: [PATCH 215/227] fix ro-crate --- ro-crate-metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 322078e..4cf7ef3 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "Stable", "datePublished": "2025-11-20T09:32:15+00:00", - "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![Open in GitHub Codespaces](https://img.shields.io/badge/Open_In_GitHub_Codespaces-black?labelColor=grey&logo=github)](https://github.com/codespaces/new/nf-core/sopa)\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.04.0-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.5.1-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.5.1)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is a bioinformatics pipeline that ...\n\n\n\n\n\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\n\n\nNow, you can run the pipeline using:\n\n\n\n```bash\nnextflow run nf-core/sopa \\\n -profile \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by Quentin Blampey.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![Open in GitHub Codespaces](https://img.shields.io/badge/Open_In_GitHub_Codespaces-black?labelColor=grey&logo=github)](https://github.com/codespaces/new/nf-core/sopa)\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.04.0-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.5.1-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.5.1)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n> [!WARNING]\n> If you are interested in the main Sopa python package, refer to [this Sopa repository](https://github.com/gustaveroussy/sopa). Else, if you want to use Nextflow, you are in the good place.\n\n

    \n \"sopa_overview\"\n

    \n\n1. (Visium HD only) Raw data processing with Space Ranger\n2. (Optional) Tissue segmentation\n3. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n4. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n5. (Optional) Cell-type annotation\n6. User-friendly output creation for visualization and quick analysis\n7. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://github.com/gustaveroussy/sopa).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-of-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose the Sopa parameters. To do that, you can provide an existing `-profile` containing all the dedicated Sopa parameters, depending on your technology, see the [available technology-specific profiles here](https://nf-co.re/sopa/dev/docs/usage/#sopa-parameters).\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile , \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by [Quentin Blampey](https://github.com/quentinblampey) during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, Universit\u00e9 Paris-Saclay, and Cure51.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n- [Matthias H\u00f6rtenhuber](https://github.com/mashehu)\n- [Kevin Weiss](https://github.com/kweisscure51)\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" From 9181db239cdc35331548580e162123b7862e48f3 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Fri, 19 Dec 2025 15:45:35 +0100 Subject: [PATCH 216/227] support proseg on vhd --- conf/predefined/visium_hd_proseg.config | 14 ++++++++++++ .../visium_hd_stardist_proseg.config | 22 +++++++++++++++++++ docs/usage.md | 4 ++++ nextflow.config | 3 ++- workflows/sopa.nf | 13 ++++++++--- 5 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 conf/predefined/visium_hd_proseg.config create mode 100644 conf/predefined/visium_hd_stardist_proseg.config diff --git a/conf/predefined/visium_hd_proseg.config b/conf/predefined/visium_hd_proseg.config new file mode 100644 index 0000000..2e77105 --- /dev/null +++ b/conf/predefined/visium_hd_proseg.config @@ -0,0 +1,14 @@ +params { + // Reader + technology = 'visium_hd' + + // Proseg + use_proseg = true + visium_hd_prior_shapes_key = "auto" + + // Filtering + min_transcripts = 10 + + // Aggregation + aggregate_channels = true +} diff --git a/conf/predefined/visium_hd_stardist_proseg.config b/conf/predefined/visium_hd_stardist_proseg.config new file mode 100644 index 0000000..b2ae0f5 --- /dev/null +++ b/conf/predefined/visium_hd_stardist_proseg.config @@ -0,0 +1,22 @@ +params { + // Reader + technology = 'visium_hd' + + // Patches + patch_width_pixel = 2000 + patch_overlap_pixel = 50 + + // Stardist + use_stardist = true + + // Proseg + use_proseg = true + visium_hd_prior_shapes_key = "stardist_boundaries" + + // Filtering + min_area_pixels2 = 30 + min_transcripts = 10 + + // Aggregation + aggregate_channels = true +} diff --git a/docs/usage.md b/docs/usage.md index 17be97e..2852e19 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -110,6 +110,10 @@ You'll also need to choose some Sopa parameters to decide which reader/segmentat - A profile with Sopa parameters to run Cellpose as a prior for Baysor on CosMx data - `visium_hd_stardist` - A profile with Sopa parameters to run Stardist on Visium HD data +- `visium_hd_proseg` + - A profile with Sopa parameters to run Proseg on Visium HD data (it will use the 10X Genomics segmentation as a prior) +- `visium_hd_stardist_proseg` + - A profile with Sopa parameters to run Stardist on Visium HD data as a prior for Proseg - `phenocycler_base_10X` - A profile with Sopa parameters to run Cellpose on Phenocycler data at 10X resolution - `phenocycler_base_20X` diff --git a/nextflow.config b/nextflow.config index cc874fe..a92ee3b 100644 --- a/nextflow.config +++ b/nextflow.config @@ -61,7 +61,6 @@ params { allow_disconnected_polygon = false norm_vector = false - // Cellpose segmentation options use_cellpose = false cellpose_diameter = null @@ -283,6 +282,8 @@ profiles { merscope_baysor_vizgen { includeConfig 'conf/predefined/merscope_baysor_vizgen.config' } merscope_proseg { includeConfig 'conf/predefined/merscope_proseg.config' } visium_hd_stardist { includeConfig 'conf/predefined/visium_hd_stardist.config' } + visium_hd_proseg { includeConfig 'conf/predefined/visium_hd_proseg.config' } + visium_hd_stardist_proseg { includeConfig 'conf/predefined/visium_hd_stardist_proseg.config' } hyperion_base { includeConfig 'conf/predefined/hyperion_base.config' } macsima_base { includeConfig 'conf/predefined/macsima_base.config' } phenocycler_base_40X { includeConfig 'conf/predefined/phenocycler_base_40X.config' } diff --git a/workflows/sopa.nf b/workflows/sopa.nf index c607dd9..31c07b5 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -99,10 +99,17 @@ workflow SOPA { } if (params.use_proseg) { - ch_input_proseg = params.use_cellpose ? ch_resolved : ch_tissue_seg + if (params.use_stardist) { + if (!params.technology == "visium_hd") { + exit 1, "Proseg segmentation with StarDist prior shapes is only supported for Visium HD data." + } + ch_input_proseg = ch_resolved.map { meta, sdata_path -> [meta, sdata_path, [], []] } + } else { + ch_proseg_patches = params.use_cellpose ? ch_resolved : ch_tissue_seg + ch_input_proseg = MAKE_TRANSCRIPT_PATCHES(ch_proseg_patches, argsCLI("transcript_patches")) + } - ch_proseg_patches = MAKE_TRANSCRIPT_PATCHES(ch_input_proseg, argsCLI("transcript_patches")) - (ch_resolved, versions) = PROSEG(ch_proseg_patches) + (ch_resolved, versions) = PROSEG(ch_input_proseg) ch_versions = ch_versions.mix(versions) } From 0178da70e32f598b7ba8689c88239ac63b6dde59 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Mon, 22 Dec 2025 10:55:43 +0100 Subject: [PATCH 217/227] use stardist_boundaries by default if running proseg+stardist + minor things --- modules/local/utils.nf | 16 ++++++++++++---- nextflow_schema.json | 4 ++-- tests/default.nf.test.snap | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/modules/local/utils.nf b/modules/local/utils.nf index 0df0f6d..c6c4d32 100644 --- a/modules/local/utils.nf +++ b/modules/local/utils.nf @@ -39,7 +39,7 @@ def extractSubArgs(Map args, String group) { return [ command_line_suffix: args.command_line_suffix, infer_presets: args.infer_presets, - prior_shapes_key: args.visium_hd_prior_shapes_key, + prior_shapes_key: getProsegPriorShapesKey(), ] } else if (group == "cellpose") { return [ @@ -165,10 +165,18 @@ def extractSubArgs(Map args, String group) { } def getPriorShapesKey() { - if (params.use_cellpose) { - return "cellpose_boundaries" - } else { + if (params.prior_shapes_key != null) { return params.prior_shapes_key + } else { + return params.use_cellpose ? "cellpose_boundaries" : null + } +} + +def getProsegPriorShapesKey() { + if (params.visium_hd_prior_shapes_key != null) { + return params.visium_hd_prior_shapes_key + } else { + return params.use_stardist ? "stardist_boundaries" : null } } diff --git a/nextflow_schema.json b/nextflow_schema.json index 9caedff..6e72ac4 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -250,7 +250,7 @@ }, "prior_shapes_key": { "type": "string", - "description": "Optional name of the boundaries element to use as a segmentation prior. Either a column name for the transcript dataframe, or a key of `sdata` containing the shapes names." + "description": "Optional name of the boundaries element to use as a segmentation prior. Either a column name for the transcript dataframe, or a key of `sdata` containing the shapes names. If combining cellpose with proseg/baysor/comseg, it will be set automatically to `'cellpose_boundaries'`." }, "unassigned_value": { "type": "string", @@ -423,7 +423,7 @@ }, "visium_hd_prior_shapes_key": { "type": "string", - "description": "**Only for Visium HD data.** Key of `sdata` containing the prior cell boundaries. If `'auto'`, use the latest performed segmentation (e.g., stardist or the 10X Genomics segmentation)." + "description": "**Only for Visium HD data.** Key of `sdata` containing the prior cell boundaries. If `'auto'`, use the latest performed segmentation (e.g., stardist or the 10X Genomics segmentation). If combining stardist with proseg, it will be set automatically to `'stardist_boundaries'`." } }, "fa_icon": "fas fa-tools" diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index 7d31bf3..98608fb 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -7,7 +7,7 @@ }, "PATCH_SEGMENTATION_PROSEG": { "sopa": "2.1.11", - "proseg": "3.0.12" + "proseg": "3.1.0" }, "SCANPY_PREPROCESS": { "sopa": "2.1.11", From 1ef3f513e3b9f65c631cdbba57700813006ac3a2 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 7 Jan 2026 09:54:13 +0100 Subject: [PATCH 218/227] improve the docs --- README.md | 2 +- docs/usage.md | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0a3b1fc..0234abe 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ SAMPLE2,/path/to/one/merscope_directory > [!WARNING] > If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters). -Then, choose the Sopa parameters. To do that, you can provide an existing `-profile` containing all the dedicated Sopa parameters, depending on your technology, see the [available technology-specific profiles here](https://nf-co.re/sopa/dev/docs/usage/#sopa-parameters). +Then, choose the Sopa parameters (denoted below as ``). To do that, you can provide an existing `-profile` containing all the dedicated Sopa parameters, depending on your technology, see the [available technology-specific profiles here](https://nf-co.re/sopa/dev/docs/usage/#sopa-parameters). Now, you can run the pipeline using: diff --git a/docs/usage.md b/docs/usage.md index 2852e19..05aaa15 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -125,14 +125,18 @@ You'll also need to choose some Sopa parameters to decide which reader/segmentat - `macsima_base` - A profile with Sopa parameters to run Cellpose on MACSima data +These profiles contain the backbone of the pipeline, i.e. which technology to use and how to process the segmentation. For more customization, you can provide [other Sopa parameters](https://nf-co.re/sopa/dev/parameters/) via the command line, for instance `--use_scanpy_preprocessing true` if you want to have a UMAP and a leiden clustering on your output AnnData object. + ## Running the pipeline -Once you have defined your samplesheet and technology `profile`, you'll be able to run `nf-core/sopa`. The typical command for running the pipeline is as follows: +Once you have defined (i) your samplesheet and (ii) your Sopa parameters (denoted below as ``), you'll be able to run `nf-core/sopa`. The typical command for running the pipeline is as follows. ```bash nextflow run nf-core/sopa --input ./samplesheet.csv --outdir ./results -profile docker, ``` +This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles. + > [!NOTE] > For Visium HD data, you may also need to provide a `--spaceranger_probeset` argument with an official 10X Genomics probe set (see [here](https://www.10xgenomics.com/support/software/space-ranger/downloads)). For instance, you can use: > @@ -140,8 +144,6 @@ nextflow run nf-core/sopa --input ./samplesheet.csv --outdir ./results -profile > --spaceranger_probeset https://cf.10xgenomics.com/supp/spatial-exp/probeset/Visium_Human_Transcriptome_Probe_Set_v2.0_GRCh38-2020-A.csv > ``` -This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles. - Note that the pipeline will create the following files in your working directory: ```bash From 560878a70138b4015b786a896e1c1d3b00f87210 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 7 Jan 2026 09:55:04 +0100 Subject: [PATCH 219/227] ro-crate update --- ro-crate-metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 4cf7ef3..da688ba 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "Stable", "datePublished": "2025-11-20T09:32:15+00:00", - "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![Open in GitHub Codespaces](https://img.shields.io/badge/Open_In_GitHub_Codespaces-black?labelColor=grey&logo=github)](https://github.com/codespaces/new/nf-core/sopa)\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.04.0-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.5.1-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.5.1)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n> [!WARNING]\n> If you are interested in the main Sopa python package, refer to [this Sopa repository](https://github.com/gustaveroussy/sopa). Else, if you want to use Nextflow, you are in the good place.\n\n

    \n \"sopa_overview\"\n

    \n\n1. (Visium HD only) Raw data processing with Space Ranger\n2. (Optional) Tissue segmentation\n3. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n4. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n5. (Optional) Cell-type annotation\n6. User-friendly output creation for visualization and quick analysis\n7. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://github.com/gustaveroussy/sopa).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-of-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose the Sopa parameters. To do that, you can provide an existing `-profile` containing all the dedicated Sopa parameters, depending on your technology, see the [available technology-specific profiles here](https://nf-co.re/sopa/dev/docs/usage/#sopa-parameters).\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile , \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by [Quentin Blampey](https://github.com/quentinblampey) during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, Universit\u00e9 Paris-Saclay, and Cure51.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n- [Matthias H\u00f6rtenhuber](https://github.com/mashehu)\n- [Kevin Weiss](https://github.com/kweisscure51)\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

    \n \n \n \"nf-core/sopa\"\n \n

    \n\n[![Open in GitHub Codespaces](https://img.shields.io/badge/Open_In_GitHub_Codespaces-black?labelColor=grey&logo=github)](https://github.com/codespaces/new/nf-core/sopa)\n[![GitHub Actions CI Status](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/sopa/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/sopa/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/sopa/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.04.0-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.5.1-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.5.1)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/sopa)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23sopa-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/sopa)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/sopa** is the Nextflow version of [Sopa](https://github.com/gustaveroussy/sopa). Built on top of [SpatialData](https://github.com/scverse/spatialdata), Sopa enables processing and analyses of spatial omics data with single-cell resolution (spatial transcriptomics or multiplex imaging data) using a standard data structure and output. We currently support the following technologies: Xenium, Visium HD, MERSCOPE, CosMX, PhenoCycler, MACSima, Molecural Cartography, and others. It outputs a `.zarr` directory containing a processed [SpatialData](https://github.com/scverse/spatialdata) object, and a `.explorer` directory for visualization.\n\n> [!WARNING]\n> If you are interested in the main Sopa python package, refer to [this Sopa repository](https://github.com/gustaveroussy/sopa). Else, if you want to use Nextflow, you are in the good place.\n\n

    \n \"sopa_overview\"\n

    \n\n1. (Visium HD only) Raw data processing with Space Ranger\n2. (Optional) Tissue segmentation\n3. Cell segmentation with Cellpose, Baysor, Proseg, Comseg, Stardist, ...\n4. Aggregation, i.e. counting the transcripts inside the cells and/or averaging the channel intensities inside cells\n5. (Optional) Cell-type annotation\n6. User-friendly output creation for visualization and quick analysis\n7. Full [SpatialData](https://github.com/scverse/spatialdata) object export as a `.zarr` directory\n\nAfter running `nf-core/sopa`, you can continue analyzing your `SpatialData` object with [`sopa` as a Python package](https://github.com/gustaveroussy/sopa).\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet that lists the `data_path` to each sample data directory (typically, the per-sample output of the Xenium/MERSCOPE/etc, see more info [here](https://gustaveroussy.github.io/sopa/faq/#what-are-the-inputs-of-sopa)). You can optionally add `sample` to provide a name to your output directory, else it will be named based on `data_path`. Here is a samplesheet example:\n\n`samplesheet.csv`:\n\n```csv\nsample,data_path\nSAMPLE1,/path/to/one/merscope_directory\nSAMPLE2,/path/to/one/merscope_directory\n```\n\n> [!WARNING]\n> If you have Visium HD data, the samplesheet will have a different format than the one above. Directly refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\nThen, choose the Sopa parameters (denoted below as ``). To do that, you can provide an existing `-profile` containing all the dedicated Sopa parameters, depending on your technology, see the [available technology-specific profiles here](https://nf-co.re/sopa/dev/docs/usage/#sopa-parameters).\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/sopa \\\n -profile , \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/sopa/usage) and the [parameter documentation](https://nf-co.re/sopa/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/sopa/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/sopa/output).\n\n## Credits\n\nnf-core/sopa was originally written by [Quentin Blampey](https://github.com/quentinblampey) during his work at the following institutions: CentraleSup\u00e9lec, Gustave Roussy Institute, Universit\u00e9 Paris-Saclay, and Cure51.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n- [Matthias H\u00f6rtenhuber](https://github.com/mashehu)\n- [Kevin Weiss](https://github.com/kweisscure51)\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#sopa` channel](https://nfcore.slack.com/channels/sopa) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `sopa` publication as follows:\n\n> Sopa: a technology-invariant pipeline for analyses of image-based spatial omics.\n>\n> Quentin Blampey, Kevin Mulder, Margaux Gardet, Stergios Christodoulidis, Charles-Antoine Dutertre, Fabrice Andr\u00e9, Florent Ginhoux & Paul-Henry Courn\u00e8de.\n>\n> _Nat Commun._ 2024 June 11. doi: [10.1038/s41467-024-48981-z](https://doi.org/10.1038/s41467-024-48981-z)\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" From d2ce405d337e6be5e48f47640fbad4ee4efe2314 Mon Sep 17 00:00:00 2001 From: Quentin Blampey <33903498+quentinblampey@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:33:53 +0100 Subject: [PATCH 220/227] Update docs/usage.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 05aaa15..0a7669d 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -36,7 +36,7 @@ SAMPLE1,/path/to/one/merscope_directory SAMPLE2,/path/to/another/merscope_directory ``` -We also provide a detailed description of what `data_path` should contain, depending on the technologies: +#### `data_path` directory content | Technology | `data_path` directory content | | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | From 61cfddad7c5cf45087fe89655d8778f0cb45024a Mon Sep 17 00:00:00 2001 From: Quentin Blampey <33903498+quentinblampey@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:34:05 +0100 Subject: [PATCH 221/227] Update docs/usage.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 0a7669d..6f60741 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -125,7 +125,7 @@ You'll also need to choose some Sopa parameters to decide which reader/segmentat - `macsima_base` - A profile with Sopa parameters to run Cellpose on MACSima data -These profiles contain the backbone of the pipeline, i.e. which technology to use and how to process the segmentation. For more customization, you can provide [other Sopa parameters](https://nf-co.re/sopa/dev/parameters/) via the command line, for instance `--use_scanpy_preprocessing true` if you want to have a UMAP and a leiden clustering on your output AnnData object. +These profiles contain the backbone of the pipeline, i.e. which technology to use and how to process the segmentation. For more customization, you can provide [other Sopa parameters](https://nf-co.re/sopa/dev/parameters/) via the command line, for instance `--use_scanpy_preprocessing true` if you want to have a UMAP and a Leiden clustering on your output AnnData object. ## Running the pipeline From cfb81744a3932cb7674a73f038ef188c122d4896 Mon Sep 17 00:00:00 2001 From: Quentin Blampey <33903498+quentinblampey@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:34:15 +0100 Subject: [PATCH 222/227] Update docs/usage.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 6f60741..ff7d175 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -237,7 +237,7 @@ If `-profile` is not specified, the pipeline will run locally and expect all sof - A generic configuration profile to enable [Wave](https://seqera.io/wave/) containers. Use together with one of the above (requires Nextflow ` 24.03.0-edge` or later). - `conda` - A generic configuration profile to be used with [Conda](https://conda.io/docs/). Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker, Singularity, Podman, Shifter, Charliecloud, or Apptainer. -- Some Sopa-specific profiles are listed in the above "Sopa parameters" section. +- Some Sopa-specific profiles are listed in the above [Sopa parameters](#sopa-parameters) section. ### `-resume` From 7edabf1358e77e06a1b6c913b7b651709096ea55 Mon Sep 17 00:00:00 2001 From: Quentin Blampey <33903498+quentinblampey@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:34:25 +0100 Subject: [PATCH 223/227] Update docs/usage.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index ff7d175..72e93fb 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -140,7 +140,7 @@ This will launch the pipeline with the `docker` configuration profile. See below > [!NOTE] > For Visium HD data, you may also need to provide a `--spaceranger_probeset` argument with an official 10X Genomics probe set (see [here](https://www.10xgenomics.com/support/software/space-ranger/downloads)). For instance, you can use: > -> ``` +> ```bash > --spaceranger_probeset https://cf.10xgenomics.com/supp/spatial-exp/probeset/Visium_Human_Transcriptome_Probe_Set_v2.0_GRCh38-2020-A.csv > ``` From eb3302d40ee8368a04b06abdbf0c73e0c9d44c87 Mon Sep 17 00:00:00 2001 From: Quentin Blampey <33903498+quentinblampey@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:34:33 +0100 Subject: [PATCH 224/227] Update subworkflows/local/utils_nfcore_sopa_pipeline/main.nf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- subworkflows/local/utils_nfcore_sopa_pipeline/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index b54d124..03e803d 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -272,7 +272,7 @@ def methodsDescriptionText(mqc_methods_yaml) { def validateParams(params) { if (params.containsKey("read")) { - exit 1, "You use a deprecated Sopa params format. We flattened all parameters to conform to the future nextflow 26.04 strict syntax check.\nSee the nf-core/sopa docs for more details on the new syntax usage: https://nf-co.re/sopa/dev/docs/usage/." + error("You use a deprecated Sopa params format. We flattened all parameters to conform to the future nextflow 26.04 strict syntax check.\nSee the nf-core/sopa docs for more details on the new syntax usage: https://nf-co.re/sopa/dev/docs/usage/.") } def TRANSCRIPT_BASED_METHODS = ['use_proseg', 'use_baysor', 'use_comseg'] From 36b2b5bee4cfba1646c2d1ea17b76273f8303b92 Mon Sep 17 00:00:00 2001 From: Quentin Blampey <33903498+quentinblampey@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:34:41 +0100 Subject: [PATCH 225/227] Update workflows/sopa.nf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- workflows/sopa.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/sopa.nf b/workflows/sopa.nf index 31c07b5..9de933d 100644 --- a/workflows/sopa.nf +++ b/workflows/sopa.nf @@ -101,7 +101,7 @@ workflow SOPA { if (params.use_proseg) { if (params.use_stardist) { if (!params.technology == "visium_hd") { - exit 1, "Proseg segmentation with StarDist prior shapes is only supported for Visium HD data." + error("Proseg segmentation with StarDist prior shapes is only supported for Visium HD data.") } ch_input_proseg = ch_resolved.map { meta, sdata_path -> [meta, sdata_path, [], []] } } else { From 77e04a5d8a57b42805c284c31cbc6c30177c6820 Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Tue, 3 Feb 2026 15:49:30 +0100 Subject: [PATCH 226/227] fix #18 --- subworkflows/local/spaceranger.nf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/subworkflows/local/spaceranger.nf b/subworkflows/local/spaceranger.nf index d5c06f7..e0b4c76 100644 --- a/subworkflows/local/spaceranger.nf +++ b/subworkflows/local/spaceranger.nf @@ -30,11 +30,10 @@ workflow SPACERANGER { // Combine extracted and directory inputs into one channel ch_spaceranger_combined = UNTAR_SPACERANGER_INPUT.out.untar - .mix(ch_spaceranger.dir) - .map { meta, dir -> meta + [fastq_dir: dir] } + .mix ( ch_spaceranger.dir.map { meta, dir -> [meta, file(dir)] } ) // Create final meta map and check input existance - ch_spaceranger_input = ch_spaceranger_combined.map { create_channel_spaceranger(it) } + ch_spaceranger_input = ch_spaceranger_combined.map { meta, dir -> create_channel_spaceranger(meta, dir) } // @@ -85,7 +84,7 @@ workflow SPACERANGER { // Function to get list of [ meta, [ fastq_dir, tissue_hires_image, slide, area ]] -def create_channel_spaceranger(LinkedHashMap meta) { +def create_channel_spaceranger(LinkedHashMap meta, File fastq_dir) { // Convert a path in `meta` to a file object and return it. If `key` is not contained in `meta` // return an empty list which is recognized as 'no file' by nextflow. def get_file_from_meta = { key -> @@ -95,8 +94,9 @@ def create_channel_spaceranger(LinkedHashMap meta) { def slide = meta.remove("slide") def area = meta.remove("area") - def fastq_dir = meta.remove("fastq_dir") - def fastq_files = file("${fastq_dir}/${meta['id']}*.fastq.gz") + def fastq_files = fastq_dir.listFiles().findAll { file -> + file.name.startsWith(meta['id']) && file.name.endsWith('.fastq.gz') + } def manual_alignment = get_file_from_meta("manual_alignment") def slidefile = get_file_from_meta("slidefile") def image = get_file_from_meta("image") From 030dc0553c134de923c79df0f3069fa4a94cb16a Mon Sep 17 00:00:00 2001 From: Quentin Blampey Date: Wed, 4 Feb 2026 17:05:17 +0100 Subject: [PATCH 227/227] remove file typing and remove identity function --- subworkflows/local/spaceranger.nf | 2 +- subworkflows/local/utils_nfcore_sopa_pipeline/main.nf | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/subworkflows/local/spaceranger.nf b/subworkflows/local/spaceranger.nf index e0b4c76..e143bf9 100644 --- a/subworkflows/local/spaceranger.nf +++ b/subworkflows/local/spaceranger.nf @@ -84,7 +84,7 @@ workflow SPACERANGER { // Function to get list of [ meta, [ fastq_dir, tissue_hires_image, slide, area ]] -def create_channel_spaceranger(LinkedHashMap meta, File fastq_dir) { +def create_channel_spaceranger(LinkedHashMap meta, fastq_dir) { // Convert a path in `meta` to a file object and return it. If `key` is not contained in `meta` // return an empty list which is recognized as 'no file' by nextflow. def get_file_from_meta = { key -> diff --git a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf index 03e803d..3f5b42a 100644 --- a/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_sopa_pipeline/main.nf @@ -130,9 +130,6 @@ workflow PIPELINE_INITIALISATION { return meta } - .map { samplesheet -> - validateInputSamplesheet(samplesheet) - } .set { ch_samplesheet } // @@ -196,12 +193,6 @@ workflow PIPELINE_COMPLETION { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -// -// Validate channels from input samplesheet -// -def validateInputSamplesheet(input) { - return input -} // // Generate methods description for MultiQC //