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
8 changes: 8 additions & 0 deletions conf/modules.config
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,12 @@ process {
]
}

withName: MULTIQC {
ext.args = "--export"
publishDir = [
path: { "${params.outdir}/multiqc" },
mode: params.publish_dir_mode
]
}

}
69 changes: 69 additions & 0 deletions modules/local/multiqc.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
process MULTIQC {
label 'process_single'

conda "bioconda::multiqc=1.15"
container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
Copy link

@rxu17 rxu17 Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems fixed to a specific container version + id? Does it make sense to have it possible to pass a custom docker image so if it updates, can just pass that in over having to update this path, creating a PR and so forth? I was looking at here:

nf-dcqc/docs/usage.md

Lines 98 to 122 in baaf4c1

> We highly recommend the use of Docker or Singularity containers for full pipeline reproducibility, however when this is not possible, Conda is also supported.
The pipeline also dynamically loads configurations from [https://github.com/nf-core/configs](https://github.com/nf-core/configs) when it runs, making multiple config profiles for various institutional clusters available at run time. For more information and to see if your system is available in these configs please see the [nf-core/configs documentation](https://github.com/nf-core/configs#documentation).
Note that multiple profiles can be loaded, for example: `-profile test,docker` - the order of arguments is important!
They are loaded in sequence, so later profiles can overwrite earlier profiles.
If `-profile` is not specified, the pipeline will run locally and expect all software to be installed and available on the `PATH`. This is _not_ recommended, since it can lead to different results on different machines dependent on the computer enviroment.
- `test`
- A profile with a complete configuration for automated testing
- Includes links to test data so needs no other parameters
- `docker`
- A generic configuration profile to be used with [Docker](https://docker.com/)
- `singularity`
- A generic configuration profile to be used with [Singularity](https://sylabs.io/docs/)
- `podman`
- A generic configuration profile to be used with [Podman](https://podman.io/)
- `shifter`
- A generic configuration profile to be used with [Shifter](https://nersc.gitlab.io/development/shifter/how-to-use/)
- `charliecloud`
- A generic configuration profile to be used with [Charliecloud](https://hpc.github.io/charliecloud/)
- `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 or Charliecloud.

'https://depot.galaxyproject.org/singularity/multiqc:1.15--pyhdfd78af_0' :
'quay.io/biocontainers/multiqc:1.15--pyhdfd78af_0' }"

input:
path suites_json
path multiqc_config
path plugin_dir

output:
path "*multiqc_report.html", emit: report
path "*_data" , emit: data
path "*_plots" , optional:true, emit: plots
path "versions.yml" , emit: versions

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

script:
def args = task.ext.args ?: ''
"""
# Set up local Python environment
export PYTHONUSERBASE=\${PWD}/.local
export PATH=\${PYTHONUSERBASE}/bin:\${PATH}
# Install the custom MultiQC plugin first
cd ${plugin_dir}
pip install --user --no-deps .
cd -
Comment on lines +30 to +33

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is going to be ran often it would make a lot more sense for the container to be published to GHCR that can be ran without needing to run this setup script each and every time. That way it's already baked into a published image that is used instead of:

    container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
        'https://depot.galaxyproject.org/singularity/multiqc:1.15--pyhdfd78af_0' :
        'quay.io/biocontainers/multiqc:1.15--pyhdfd78af_0' }"

# Find the actual site-packages directory and set PYTHONPATH
SITE_PACKAGES=\$(find \${PYTHONUSERBASE}/lib -name site-packages -type d | head -n 1)
if [ -z "\${PYTHONPATH:-}" ]; then
export PYTHONPATH=\${SITE_PACKAGES}
else
export PYTHONPATH=\${SITE_PACKAGES}:\${PYTHONPATH}
fi
# suites.json is already staged by Nextflow, no need to copy
# Run MultiQC with the custom config
multiqc \\
--force \\
--config ${multiqc_config} \\
$args \\
.
cat <<-END_VERSIONS > versions.yml
"${task.process}":
multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" )
END_VERSIONS
"""

stub:
"""
touch multiqc_data
touch multiqc_plots
touch multiqc_report.html
cat <<-END_VERSIONS > versions.yml
"${task.process}":
multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" )
END_VERSIONS
"""
}
10 changes: 10 additions & 0 deletions multiqc/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Python build artifacts
build/
dist/
*.egg-info/
__pycache__/
*.py[cod]
*$py.class

# Setuptools
.eggs/
10 changes: 10 additions & 0 deletions multiqc/multiqc_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# MultiQC Configuration for DCQC Validation Plugin

# Force run the dcqc_validation module
run_modules:
- dcqc_validation

# Search pattern for dcqc_validation (plugin for DCQC validation)
sp:
dcqc_validation:
fn: "suites.json"
100 changes: 100 additions & 0 deletions multiqc/multiqc_dcqc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# MultiQC DCQC Validation Plugin

A MultiQC plugin for displaying validation results from DCQC suite testing.

## Features

- **Validation Summary**: Overview table showing overall status for each validated file
- **Test Details**: Detailed breakdown of individual test results by suite type
- **Failed Tests**: Comprehensive error messages and validation failures
- **General Stats**: Key metrics added to MultiQC general statistics table
- **Multi-Suite Support**: Handles all DCQC suite types (H5AD, and more)

## Installation

Install the plugin using pip from the project directory:

```bash
pip install .
```

Or install in development mode:

```bash
pip install -e .
```

## Usage

Run MultiQC in a directory containing `suites.json` file(s):

```bash
multiqc .
```

Or specify the results directory:

```bash
multiqc results/
```

## Data Format

The plugin expects a `suites.json` file with the following structure:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it expect all of the following fields you listed to be filled out or which ones are optional?


```json
[
{
"type": "H5ADSuite", // or other suite types
"target": {
"id": "sample_001",
"files": [
{
"name": "sample.h5ad", // or other file types
"url": "...",
"local_path": "..."
}
]
},
"suite_status": {
"status": "GREEN",
"required_tests": [...]
},
"tests": [
{
"type": "TestName",
"tier": 1,
"status": "passed",
"status_reason": "",
"is_external_test": false
}
]
}
]
```

The plugin supports all DCQC suite types and will display the suite type in the reports.

## Configuration

The plugin automatically searches for `suites.json` files. You can customize the search pattern in your MultiQC configuration file:

```yaml
sp:
dcqc_validation:
fn: 'suites.json'
```
## Output
The plugin generates three main sections in the MultiQC report:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a sample output screenshot you could add here?

1. **Validation Summary**: High-level overview with pass/fail status for each file and suite type
2. **Test Details**: Individual test results for each file, organized by suite type
3. **Failed Tests**: Detailed error messages for any failed validation tests
All sections display the suite type to help distinguish between different validation workflows (e.g., H5ADSuite, etc.).
## License
MIT
26 changes: 26 additions & 0 deletions multiqc/multiqc_dcqc/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""
MultiQC plugin for DCQC validation results.
"""

from multiqc.utils import config

# Make sure this plugin runs after any standard MultiQC modules
config.module_order.append(
{
"dcqc_validation": {
"module_tag": ["QC", "Validation"],
"name": "DCQC Validation",
"anchor": "dcqc-validation",
"target": "DCQC Validation",
"info": "displays validation results from DCQC suite testing",
}
}
)

# Configure search patterns for finding suites.json files
config.sp["dcqc_validation"] = {
"fn": "suites.json",
}

# Import the module
from multiqc_dcqc import dcqc_validation
Loading