Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .nf-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ repository_type: pipeline
template:
author: M. Bonfanti, S. Terzoli
description: Analysis of spatial omics dataset
force: true
force: true
is_nfcore: false
name: spatialomics
org: nfdata-omics
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ Initial release of nfdata-omics/spatialomics, created with the [nf-core](https:/

### `Added`

- Implemented alignment with spaceranger [2](https://github.com/nfdata-omics/spatialomics/pull/2)
- Implemented conversion from spaceranger output to zarr, possibility of direct input of a spaceranger out folder, collecting metrics file from spaceranger to multiQC [7](https://github.com/nfdata-omics/spatialomics/pull/7)

### `Fixed`

- Template update to 3.5.2 [3](https://github.com/nfdata-omics/spatialomics/pull/3)

### `Dependencies`

### `Deprecated`
30 changes: 30 additions & 0 deletions assets/multiqc_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ report_comment: >
This report has been generated by the <a href="https://github.com/nfdata-omics/spatialomics/tree/dev" target="_blank">nfdata-omics/spatialomics</a>
analysis pipeline.
report_section_order:
fastqc:
order: 5000
spaceranger_metrics:
order: 4000
"nfdata-omics-spatialomics-methods-description":
order: -1000
software_versions:
Expand All @@ -12,3 +16,29 @@ report_section_order:
export_plots: true

disable_version_detection: true

# Run only these modules
run_modules:
- custom_content
- fastqc
- spaceranger

# Customize file name patterns
sp:
spaceranger:
fn: "*web_summary.html"
contents: None
spaceranger_metrics:
fn: "spaceranger_metrics.csv"

custom_data:
spaceranger_metrics:
id: "spaceranger_metrics"
section_name: "Space Ranger metrics"
description: |
This table summarizes key metrics from the Space Ranger analysis across all samples.
It includes information such as the number of reads, the percentage of reads mapped to the probe set,
and other relevant statistics that can help assess the quality of the spatial transcriptomics data.
plot_type: "table"
pconfig:
id: "spaceranger_metrics_table"
8 changes: 7 additions & 1 deletion assets/schema_input.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,14 @@
"format": "file-path",
"exists": true,
"meta": ["slidefile"]
},
"spaceranger": {
"type": "string",
"format": "path",
"exists": true,
"errorMessage": "Path to Space Ranger output directory must exist"
}
},
"required": ["sample", "fastq_1"]
"anyOf": [{ "required": ["sample", "fastq_1"] }, { "required": ["sample", "spaceranger"] }]
}
}
29 changes: 25 additions & 4 deletions conf/modules.config
Original file line number Diff line number Diff line change
Expand Up @@ -102,20 +102,41 @@ process {
[
path: { "${params.outdir}/count/" },
mode: params.publish_dir_mode,
pattern: "outs/web_summary.html",
pattern: "*web_summary.html",
saveAs: { "${meta.id}_web_summary.html" }
],
[
path: { "${params.outdir}/count/${meta.id}" },
path: { "${params.outdir}/count/" },
mode: params.publish_dir_mode,
pattern: "outs/**",
saveAs: { filename -> filename.contains('/') ? filename.substring(filename.indexOf('/') + 1) : filename }
pattern: "outs",
saveAs: { "${meta.id}" }
]
]
ext.args = "--create-bam true"
time = { 240.h * task.attempt }
}

withName: 'COLLECT_SPACERANGER_METRICS' {
publishDir = [
enabled: false
]
}

withName: 'SPACERANGER_TO_ZARR' {
publishDir = [
enabled: false
]
}

withName: 'TAR' {
ext.prefix = { "${meta.id}.zarr" }
publishDir = [
path: "${params.outdir}/count",
mode: params.publish_dir_mode,
saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
]
}

withName: 'MULTIQC' {
ext.args = { params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' }
publishDir = [
Expand Down
5 changes: 4 additions & 1 deletion main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ workflow NFDATAOMICS_SPATIALOMICS {

take:
samplesheet // channel: samplesheet read in from --input
spaceranger_outs // channel: spaceranger output paths read in from --input

main:

Expand All @@ -56,6 +57,7 @@ workflow NFDATAOMICS_SPATIALOMICS {
//
SPATIALOMICS (
samplesheet,
spaceranger_outs,
ch_fasta,
ch_gtf,
ch_gff,
Expand Down Expand Up @@ -93,7 +95,8 @@ workflow {
// WORKFLOW: Run main workflow
//
NFDATAOMICS_SPATIALOMICS (
PIPELINE_INITIALISATION.out.samplesheet
PIPELINE_INITIALISATION.out.samplesheet,
PIPELINE_INITIALISATION.out.spaceranger_outs
)

//
Expand Down
5 changes: 5 additions & 0 deletions modules.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
"git_sha": "41dfa3f7c0ffabb96a6a813fe321c6d1cc5b6e46",
"installed_by": ["modules"]
},
"tar": {
"branch": "master",
"git_sha": "5c9f8d5b7671237c906abadc9ff732b301ca15ca",
"installed_by": ["modules"]
},
"untar": {
"branch": "master",
"git_sha": "00ee87ebb541af0008596400ce6d5f66d79d5408",
Expand Down
101 changes: 101 additions & 0 deletions modules/local/collect_spaceranger_metrics/main.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
process COLLECT_SPACERANGER_METRICS {
tag "all samples"
label 'process_low'

container 'docker.io/nfdata/spatialdata:v0.7.2'

input:
path "outs_*"

output:
path "spaceranger_metrics.csv", emit: metrics
path "versions.yml", emit: versions

when:
task.ext.when == null || task.ext.when

script:
"""
#!/usr/bin/env python3

import sys
import importlib
import pkg_resources
import glob
import yaml
import pandas as pd

input_files = glob.glob("outs_*/metrics_summary.csv")

dfs = []
for file in input_files:
df = pd.read_csv(file)
dfs.append(df)

# Concatenate all DataFrames
combined = pd.concat(dfs, ignore_index=True)

# Save to a single CSV file
combined.to_csv("spaceranger_metrics.csv", index=False)

# ----------------------------------
# Print versions of relevant libraries
# ----------------------------------

versions = {}
versions["${task.process}"] = {}
for lib in ['pandas']:
try:
version = pkg_resources.get_distribution(lib).version
except Exception:
try:
module = importlib.import_module(lib)
version = getattr(module, '__version__', 'unknown')
except Exception:
version = None
if version is not None:
versions["${task.process}"][lib] = version
versions["${task.process}"]['python'] = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"

with open('versions.yml', 'w') as f:
yaml.dump(versions, f)
"""

stub:
"""
#!/usr/bin/env python3

import sys
import importlib
import pkg_resources
import glob
import yaml

open('spaceranger_metrics.csv', 'w').close()

# ----------------------------------
# Print versions of relevant libraries
# ----------------------------------

versions = {}
versions["${task.process}"] = {}
for lib in ['pandas']:
try:
version = pkg_resources.get_distribution(lib).version
except Exception:
try:
module = importlib.import_module(lib)
version = getattr(module, '__version__', 'unknown')
except Exception:
version = None
if version is not None:
versions["${task.process}"][lib] = version
versions["${task.process}"]['python'] = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"

with open('versions.yml', 'w') as f:
yaml.dump(versions, f)

"""


}
106 changes: 106 additions & 0 deletions modules/local/spaceranger_to_zarr/main.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
process SPACERANGER_TO_ZARR {
tag "$meta.id"
label 'process_low'

container 'docker.io/nfdata/spatialdata:v0.7.2'

input:
tuple val(meta), path(spaceranger_output_dir)
val filtered_counts_file

output:
tuple val(meta), path("*.zarr"), emit: zarr
path "versions.yml" , emit: versions

when:
task.ext.when == null || task.ext.when

script:
def prefix = task.ext.prefix ?: "${meta.id}"
"""
#!/usr/bin/env python3

import os

os.environ["NUMBA_CACHE_DIR"] = os.environ.get("TMPDIR", "/tmp")
os.environ["MPLCONFIGDIR"] = os.environ.get("TMPDIR", "/tmp")
os.environ["XDG_CONFIG_HOME"] = os.environ.get("TMPDIR", "/tmp")

import sys
import importlib
import pkg_resources
import yaml
import spatialdata_io

# ----------------------------------
# Load dataset using spatialdata_io
# ----------------------------------

# Here, the bin size is set to 16, but we should allow the option to also read 002 and 008
data = spatialdata_io.visium_hd(
"$spaceranger_output_dir",
filtered_counts_file="${filtered_counts_file}",
dataset_id="${prefix}"
)

# ----------------------------------
# Save full dataset as Zarr
# ----------------------------------
data.write(f"${prefix}.zarr", overwrite=True)

# ----------------------------------
# Print versions of relevant libraries
# ----------------------------------

versions = {}
versions["${task.process}"] = {}
for lib in ['spatialdata_io', 'spatialdata', 'numpy', 'pandas', 'scipy']:
try:
version = pkg_resources.get_distribution(lib).version
except Exception:
try:
module = importlib.import_module(lib)
version = getattr(module, '__version__', 'unknown')
except Exception:
version = None
if version is not None:
versions["${task.process}"][lib] = version
versions["${task.process}"]['python'] = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"

with open('versions.yml', 'w') as f:
yaml.dump(versions, f)
"""

stub:
"""
#!/usr/bin/env python3

import os
os.makedirs("${meta.id}.zarr", exist_ok=True)

# ----------------------------------
# Print versions of relevant libraries
# ----------------------------------

versions = {}
versions["${task.process}"] = {}
for lib in ['spatialdata_io', 'spatialdata', 'numpy', 'pandas', 'scipy']:
try:
version = pkg_resources.get_distribution(lib).version
except Exception:
try:
module = importlib.import_module(lib)
version = getattr(module, '__version__', 'unknown')
except Exception:
version = None
if version is not None:
versions["${task.process}"][lib] = version
versions["${task.process}"]['python'] = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"

with open('versions.yml', 'w') as f:
yaml.dump(versions, f)

"""


}
4 changes: 3 additions & 1 deletion modules/nf-core/spaceranger/count/main.nf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading