Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
6a6ba94
fix(modules): address awgymer review on PR #139 (strict nf-core compl…
an-altosian May 15, 2026
5678b70
fix: make version evals robust + drop unused imports
an-altosian May 15, 2026
2a15a80
fix(CI): drop restrict_concurrency + restore CI-derived snapshots + p…
an-altosian May 15, 2026
381fff1
fix(modules): revert proseg --output-spatialdata (real v3.1.0 flag)
an-altosian May 15, 2026
c8c7094
ci: retrigger — previous run hit 'no space left on device' on runner …
an-altosian May 15, 2026
c9e3311
ci: free disk space before nf-test (xeniumranger:4.0 pull was failing)
an-altosian May 15, 2026
b6b7122
ci: replace ineffective free-disk-space@v1 with docker prune + manual…
an-altosian May 15, 2026
48f450a
Revert CI workflow tweaks — root cause was wrong local nf-test invoca…
an-altosian May 15, 2026
ee80948
ci: bump nf-test max_shards 12→24 to break the cumulative-pull cliff
an-altosian May 15, 2026
59ab98e
ci: bump runner disk=large → xlarge for nf-test jobs
an-altosian May 15, 2026
118fb68
ci: relocate docker data-root to largest mount (if one exists) + measure
an-altosian May 15, 2026
62bcdeb
ci: swap runner image full→noble, dropping ~12GB of preinstalled tools
an-altosian May 15, 2026
2333c0f
Revert: restore disk=xlarge (image=noble label invalid, broke all 43 …
an-altosian May 15, 2026
32f479d
ci: use volume=80gb runs-on label (per @awgymer)
an-altosian May 18, 2026
3541886
ci: revert experimental CI tweaks; keep only volume=80gb
an-altosian May 18, 2026
3655ae5
fix: remove stale `errorStrategy = 'ignore'` from MULTIQC processes
an-altosian May 19, 2026
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 .github/workflows/nf-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 0 additions & 2 deletions bin/spatialdata_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import os
import shutil

import spatialdata


def parse_args():
"""Parse command-line arguments."""
Expand Down
1 change: 0 additions & 1 deletion bin/spatialdata_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import pandas as pd
import spatialdata as sd
import zarr

# Fix zarr v3 + anndata + numcodecs incompatibility:
# anndata's string writer passes numcodecs.VLenUTF8 to zarr.Group.create_array,
Expand Down
1 change: 0 additions & 1 deletion bin/spatialdata_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import sys

import pandas as pd
import spatialdata
from spatialdata_io import xenium

# Fix zarr v3 + anndata + numcodecs incompatibility:
Expand Down
41 changes: 29 additions & 12 deletions conf/modules.config
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ process {

// ---------------------------- multiqc ---------------------------------------------------

withName: 'MULTIQC|MULTIQC_PRE_XR_RUN|MULTIQC_POST_XR_RUN' {
errorStrategy = 'ignore'
}

withName: MULTIQC {
ext.args = { params.multiqc_title ? "--title \"${params.multiqc_title}\"" : '' }
publishDir = [
Expand Down Expand Up @@ -72,13 +68,23 @@ process {
path: "${params.outdir}/${params.mode}/xeniumranger/resegment",
mode: params.publish_dir_mode,
]
ext.args = {[
// Disable boundary/interior stain when the param is falsy; keep tool default when truthy.
!params.boundary_stain ? "--boundary-stain=disable" : "",
!params.interior_stain ? "--interior-stain=disable" : "",
params.expansion_distance != null ? "--expansion-distance=${params.expansion_distance}" : "",
params.dapi_filter != null ? "--dapi-filter=${params.dapi_filter}" : "",
].join(' ').trim()}
}

withName: XENIUMRANGER_IMPORT_SEGMENTATION {
publishDir = [
path: "${params.outdir}/${params.mode}/xeniumranger/import_segementation",
mode: params.publish_dir_mode,
]
ext.args = {[
params.expansion_distance != null ? "--expansion-distance=${params.expansion_distance}" : "",
].join(' ').trim()}
}

// ---------------------------- proseg ---------------------------------------------------
Expand All @@ -88,7 +94,9 @@ process {
path: "${params.outdir}/${params.mode}/proseg/preset",
mode: params.publish_dir_mode,
]
ext.format = { params.format ?: 'xenium' }
ext.args = {[
params.format != null ? "--${params.format}" : "",
].join(' ').trim()}
}

withName: PROSEG2BAYSOR {
Expand Down Expand Up @@ -173,19 +181,24 @@ process {
path: { "${params.outdir}/${params.mode}/segger/create_dataset" },
mode: params.publish_dir_mode,
]
ext.args = { "--tile-width ${params.tile_width} --tile-height ${params.tile_height}" }
ext.format = { params.format ?: 'xenium' }
ext.args = {[
params.format != null ? "--sample-type ${params.format}" : "",
params.tile_width != null ? "--tile-width ${params.tile_width}" : "",
params.tile_height != null ? "--tile-height ${params.tile_height}" : "",
].join(' ').trim()}
}

withName: SEGGER_TRAIN {
publishDir = [
path: { "${params.outdir}/${params.mode}/segger/train" },
mode: params.publish_dir_mode,
]
ext.devices = params.devices
ext.args = { "--batch_size ${params.batch_size_train} --max_epochs ${params.max_epochs} --num_workers ${params.segger_num_workers}" }
ext.args2 = { "--init_emb 8 --hidden_channels 32 --num_tx_tokens 10000 --out_channels 8 --heads 2 --num_mid_layers 2 --strategy auto --precision bf16-mixed" }
maxForks = params.restrict_concurrency ? 1 : 0
ext.args = {[
"--init_emb 8 --hidden_channels 32 --num_tx_tokens 10000 --out_channels 8 --heads 2 --num_mid_layers 2 --strategy auto --precision bf16-mixed",
params.batch_size_train != null ? "--batch_size ${params.batch_size_train}" : "",
params.max_epochs != null ? "--max_epochs ${params.max_epochs}" : "",
params.segger_num_workers != null ? "--num_workers ${params.segger_num_workers}" : "",
].join(' ').trim()}
}

withName: SEGGER_PREDICT {
Expand All @@ -195,7 +208,11 @@ process {
// Skip partitioned parquet dirs (Hive-style) that S3 copy can't handle
saveAs: { filename -> filename.contains('transcripts_df.parquet') ? null : filename },
]
ext.args = { "--batch-size ${params.batch_size_predict} --cc-analysis ${params.cc_analysis} --knn-method ${params.segger_knn_method}" }
ext.args = {[
params.batch_size_predict != null ? "--batch-size ${params.batch_size_predict}" : "",
params.cc_analysis != null ? "--cc-analysis ${params.cc_analysis}" : "",
params.segger_knn_method != null ? "--knn-method ${params.segger_knn_method}" : "",
].join(' ').trim()}
}

// ---------------------------- ficture ------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ workflow {
params.help,
params.help_full,
params.show_hidden,
params.format,
params.gene_panel,
params.gene_synonyms,
params.image_seg_methods,
Expand Down
6 changes: 2 additions & 4 deletions modules.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@
"xeniumranger/import-segmentation": {
"branch": "master",
"git_sha": "39365e944e936511e33b993cdd978e0f12adac9a",
"installed_by": ["modules"],
"patch": "modules/nf-core/xeniumranger/import-segmentation/xeniumranger-import-segmentation.diff"
"installed_by": ["modules"]
},
"xeniumranger/relabel": {
"branch": "master",
Expand All @@ -67,8 +66,7 @@
"xeniumranger/resegment": {
"branch": "master",
"git_sha": "39365e944e936511e33b993cdd978e0f12adac9a",
"installed_by": ["modules"],
"patch": "modules/nf-core/xeniumranger/resegment/xeniumranger-resegment.diff"
"installed_by": ["modules"]
}
}
},
Expand Down
11 changes: 2 additions & 9 deletions modules/local/proseg/preset/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,12 @@ process PROSEG {

def args = task.ext.args ?: ''
prefix = task.ext.prefix ?: "${meta.id}"
def format = task.ext.format ?: 'xenium'

// check for platform values
if (!(format in ['xenium', 'cosmx', 'merscope'])) {
error("${format} is an invalid platform type. Please specify xenium, cosmx, or merscope")
}

"""
mkdir -p ${prefix}

proseg \\
--${format} \\
${args} \\
${transcripts} \\
--nthreads ${task.cpus} \\
--output-expected-counts ${prefix}/expected-counts.csv.gz \\
Expand All @@ -45,8 +39,7 @@ process PROSEG {
--output-cell-polygons ${prefix}/cell-polygons.geojson.gz \\
--output-cell-polygon-layers ${prefix}/cell-polygons-layers.geojson.gz \\
--output-union-cell-polygons ${prefix}/union-cell-polygons.geojson.gz \\
--output-spatialdata ${prefix}/proseg-output.zarr \\
${args}
--output-spatialdata ${prefix}/proseg-output.zarr
"""

stub:
Expand Down
8 changes: 0 additions & 8 deletions modules/local/segger/create_dataset/main.nf
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
process SEGGER_CREATE_DATASET {
tag "${meta.id}"
label 'process_xl'
maxForks params.restrict_concurrency ? 1 : 0

container "quay.io/dongzehe/segger:1.0.14"

Expand All @@ -23,12 +22,6 @@ process SEGGER_CREATE_DATASET {

def args = task.ext.args ?: ''
prefix = task.ext.prefix ?: "${meta.id}"
def format = task.ext.format ?: 'xenium'

// check for platform values
if (!(format in ['xenium'])) {
error("${format} is an invalid platform type.")
}

"""
export NUMBA_CACHE_DIR=\$PWD/.numba_cache
Expand All @@ -37,7 +30,6 @@ process SEGGER_CREATE_DATASET {
segger_create_dataset.py \\
--bundle-dir ${base_dir} \\
--output-dir ${prefix} \\
--sample-type ${format} \\
--n-workers ${task.cpus} \\
${args}
"""
Expand Down
8 changes: 2 additions & 6 deletions modules/local/segger/train/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,11 @@ process SEGGER_TRAIN {
}

def args = task.ext.args ?: ''
def args2 = task.ext.args2 ?: ''
def script_path = "/workspace/segger_dev/src/segger/cli/train_model.py"
prefix = task.ext.prefix ?: "${meta.id}"
// Scale GPU count with retries: 4 → 8 (capped at params.devices)
def gpu_count = 2 * task.attempt
def cuda_visible = gpu_count == 1 ? "export CUDA_VISIBLE_DEVICES=0" : ""
def accelerator = task.accelerator ? 'gpu' : 'auto'
def num_devices = task.devices ?: 0

"""
# Set numba cache directory to avoid caching issues in container
Expand All @@ -38,7 +35,7 @@ process SEGGER_TRAIN {

# GPU detection logging
echo "=== GPU Detection (SEGGER_TRAIN) ==="
echo "Requested devices: ${gpu_count} (attempt ${task.attempt}, max ${num_devices})"
echo "Requested devices: ${gpu_count} (attempt ${task.attempt})"
echo "Accelerator: ${accelerator}"
nvidia-smi 2>/dev/null && echo "GPU available: yes" || echo "GPU available: no (nvidia-smi failed)"
python3 -c "import torch; print(f'PyTorch CUDA available: {torch.cuda.is_available()}'); print(f'CUDA device count: {torch.cuda.device_count()}')" 2>/dev/null || echo "PyTorch CUDA check failed"
Expand All @@ -51,8 +48,7 @@ process SEGGER_TRAIN {
--sample_tag ${prefix} \\
--devices ${gpu_count} \\
--accelerator ${accelerator} \\
${args} \\
${args2}
${args}
"""

stub:
Expand Down
2 changes: 1 addition & 1 deletion modules/local/spatialdata/merge/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ process SPATIALDATA_MERGE {

output:
tuple val(meta), path("spatialdata/${prefix}/${outputfolder}"), emit: merged_bundle
tuple val("${task.process}"), val('spatialdata'), eval('python3 -c "import spatialdata; print(spatialdata.__version__)"'), topic: versions, emit: versions_spatialdata
tuple val("${task.process}"), val('spatialdata'), eval("pip show spatialdata | sed -n 's/^Version: //p'"), topic: versions, emit: versions_spatialdata

when:
task.ext.when == null || task.ext.when
Expand Down
2 changes: 1 addition & 1 deletion modules/local/spatialdata/meta/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ process SPATIALDATA_META {

output:
tuple val(meta), path("spatialdata/${prefix}/${outputfolder}"), emit: metadata
tuple val("${task.process}"), val('spatialdata'), eval('python3 -c "import spatialdata; print(spatialdata.__version__)"'), topic: versions, emit: versions_spatialdata
tuple val("${task.process}"), val('spatialdata'), eval("pip show spatialdata | sed -n 's/^Version: //p'"), topic: versions, emit: versions_spatialdata

when:
task.ext.when == null || task.ext.when
Expand Down
2 changes: 1 addition & 1 deletion modules/local/spatialdata/write/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ process SPATIALDATA_WRITE {

output:
tuple val(meta), path("spatialdata/${prefix}/${outputfolder}"), emit: spatialdata
tuple val("${task.process}"), val('spatialdata'), eval('python3 -c "import spatialdata; print(spatialdata.__version__)"'), topic: versions, emit: versions_spatialdata
tuple val("${task.process}"), val('spatialdata'), eval("pip show spatialdata | sed -n 's/^Version: //p'"), topic: versions, emit: versions_spatialdata

when:
task.ext.when == null || task.ext.when
Expand Down
4 changes: 2 additions & 2 deletions modules/local/utility/downscale_morphology/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ process DOWNSCALE_MORPHOLOGY {
tuple val(meta), path("${prefix}/downscaled.tif"), emit: downscaled
tuple val(meta), path("${prefix}/scale_info.json"), emit: scale_info
tuple val("${task.process}"), val('python'), eval("python3 --version | sed 's/Python //'"), topic: versions, emit: versions_python
tuple val("${task.process}"), val('tifffile'), eval('python3 -c "import tifffile; print(tifffile.__version__)"'), topic: versions, emit: versions_tifffile
tuple val("${task.process}"), val('scikit-image'), eval('python3 -c "import skimage; print(skimage.__version__)"'), topic: versions, emit: versions_skimage
tuple val("${task.process}"), val('tifffile'), eval("pip show tifffile 2>/dev/null | sed -n 's/^Version: //p'"), topic: versions, emit: versions_tifffile
tuple val("${task.process}"), val('scikit-image'), eval("pip show scikit-image 2>/dev/null | sed -n 's/^Version: //p'"), topic: versions, emit: versions_skimage

when:
task.ext.when == null || task.ext.when
Expand Down
2 changes: 1 addition & 1 deletion modules/local/utility/parquet_to_csv/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ process PARQUET_TO_CSV {

output:
tuple val(meta), path("${prefix}/*.csv*"), emit: transcripts_csv
tuple val("${task.process}"), val('pyarrow'), eval('python3 -c "import pyarrow; print(pyarrow.__version__)"'), topic: versions, emit: versions_pyarrow
tuple val("${task.process}"), val('pyarrow'), eval("pip show pyarrow 2>/dev/null | sed -n 's/^Version: //p'"), topic: versions, emit: versions_pyarrow

when:
task.ext.when == null || task.ext.when
Expand Down
2 changes: 1 addition & 1 deletion modules/local/utility/resize_tif/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ process RESIZE_TIF {
output:
tuple val(meta), path("${meta.id}/resized_*.tif"), emit: resized_mask
tuple val("${task.process}"), val('python'), eval("python3 --version | sed 's/Python //'"), topic: versions, emit: versions_python
tuple val("${task.process}"), val('tifffile'), eval('python3 -c "import tifffile; print(tifffile.__version__)"'), topic: versions, emit: versions_tifffile
tuple val("${task.process}"), val('tifffile'), eval("pip show tifffile 2>/dev/null | sed -n 's/^Version: //p'"), topic: versions, emit: versions_tifffile

when:
task.ext.when == null || task.ext.when
Expand Down
2 changes: 1 addition & 1 deletion modules/local/utility/upscale_mask/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ process UPSCALE_MASK {
output:
tuple val(meta), path("${prefix}/upscaled_*.tif"), emit: upscaled_mask
tuple val("${task.process}"), val('python'), eval("python3 --version | sed 's/Python //'"), topic: versions, emit: versions_python
tuple val("${task.process}"), val('tifffile'), eval('python3 -c "import tifffile; print(tifffile.__version__)"'), topic: versions, emit: versions_tifffile
tuple val("${task.process}"), val('tifffile'), eval("pip show tifffile 2>/dev/null | sed -n 's/^Version: //p'"), topic: versions, emit: versions_tifffile

when:
task.ext.when == null || task.ext.when
Expand Down
2 changes: 1 addition & 1 deletion modules/local/xenium_patch/divide/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ process XENIUM_PATCH_DIVIDE {
tuple val(meta), path("patches/patch_grid.json") , emit: grid
tuple val(meta), path("patches/patch_*/transcripts.parquet") , emit: patch_transcripts
tuple val("${task.process}"), val('python'), eval("python3 --version | sed 's/Python //'"), topic: versions, emit: versions_python
tuple val("${task.process}"), val('pyarrow'), eval('python3 -c "import pyarrow; print(pyarrow.__version__)"'), topic: versions, emit: versions_pyarrow
tuple val("${task.process}"), val('pyarrow'), eval("pip show pyarrow 2>/dev/null | sed -n 's/^Version: //p'"), topic: versions, emit: versions_pyarrow

when:
task.ext.when == null || task.ext.when
Expand Down
2 changes: 1 addition & 1 deletion modules/local/xenium_patch/stitch/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ process XENIUM_PATCH_STITCH {
path("output/xr-cell-polygons.geojson"),
path("output/xr-transcript-metadata.csv") , emit: xr_polygons_transcript
tuple val("${task.process}"), val('python'), eval("python3 --version | sed 's/Python //'"), topic: versions, emit: versions_python
tuple val("${task.process}"), val('sopa'), eval('python3 -c "import sopa; print(sopa.__version__)"'), topic: versions, emit: versions_sopa
tuple val("${task.process}"), val('sopa'), eval("pip show sopa 2>/dev/null | sed -n 's/^Version: //p'"), topic: versions, emit: versions_sopa

when:
task.ext.when == null || task.ext.when
Expand Down
1 change: 0 additions & 1 deletion modules/nf-core/xeniumranger/import-segmentation/main.nf

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

This file was deleted.

9 changes: 0 additions & 9 deletions modules/nf-core/xeniumranger/resegment/main.nf

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

Loading
Loading