Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add palom as local module #50

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
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
12 changes: 12 additions & 0 deletions conf/modules.config
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,20 @@ process {
]
}

withName: ALIGNMULTIPLECYCLES {
ext.args = { params.palom_align_channel ? "--channel ${params.palom_align_channel}" : ''}
// TODO px_size specification?
ext.when = {params.registration_method.split(',').contains('palom')}
publishDir = [
path: { "${params.outdir}/registration/palom" },
mode: params.publish_dir_mode,
]
}


withName: ASHLAR {
containerOptions = '--user root'
ext.when = {params.registration_method.split(',').contains('ashlar')}
publishDir = [
path: { "${params.outdir}/registration/ashlar" },
mode: params.publish_dir_mode,
Expand Down
11 changes: 11 additions & 0 deletions modules/local/palom/alignmultiplecycles/environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: "palom_multicycle"
channels:
- conda-forge
- bioconda
- defaults
dependencies:
- "openslide=4.0.0"
- "scikit-image=0.19.3"
- pip
- pip:
- "palom==2024.4.1"
43 changes: 43 additions & 0 deletions modules/local/palom/alignmultiplecycles/main.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
process ALIGNMULTIPLECYCLES {
tag "$meta.id"
label 'process_single'
container "docker.io/voigtgesa/palom:v2024.4.1_cli2"

input:
tuple val(meta), path(images, stageAs: 'image*/*')

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

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

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

"""
python /palom/align_multiple_cycles.py \\
--img_list $images \\
--out_name ${prefix}.ome.tif \\
--out_dir . \\
$args

cat <<-END_VERSIONS > versions.yml
"${task.process}":
palom: \$(palom-svs --version | sed 's/palom v//')
END_VERSIONS
"""

stub:
def prefix = task.ext.prefix ?: "${meta.id}"
"""
touch ${prefix}.ome.tif

cat <<-END_VERSIONS > versions.yml
"${task.process}":
palom: \$(palom-svs --version | sed 's/palom v//')
END_VERSIONS
"""
}
47 changes: 47 additions & 0 deletions modules/local/palom/alignmultiplecycles/meta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: "palom_multiplecycles"
description: Alignment for Multiple Layers of Mosaics
keywords:
- image_processing
- registration
- alignment
tools:
- "palom":
description: "Piecewise Alignment for Layers of Mosaics. Palom started as a tool for registering whole-slide images of the same FFPE section with different IHC stainings"
homepage: "https://github.com/labsyspharm/palom"
documentation: "https://github.com/labsyspharm/palom/blob/main/README.md"
tool_dev_url: "https://github.com/labsyspharm/palom"
doi: ""
licence: "" ## TODO Wait for licence specification (opened issue)

input:
- meta:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1', single_end:false ]`
- images:
type: path
description: List of paths to OME-TIF files, ordered by consecutive imaging cycles
pattern: "*.{ome.tiff,ome.tif,tif,tiff}"

output:
- meta:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1']`
- versions:
type: file
description: File containing software versions
pattern: "versions.yml"
- tif:
type: file
description: Registered image
pattern: "*.ome.tif"

authors:
- "@kbestak"
- "@gesavoigt"
maintainers:
- "@kbestak"
- "@gesavoigt"
2 changes: 2 additions & 0 deletions nextflow.config
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ params {
marker_sheet = null
segmentation = 'mesmer'
cellpose_model = []
registration_method = 'ashlar'
palom_align_channel = 0

// Illumination correction
illumination = null
Expand Down
17 changes: 15 additions & 2 deletions nextflow_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,24 @@
"segmentation": {
"type": "string",
"pattern": "^((cellpose|mesmer)?,?)*(?<!,)$",
"description": "comma separated list of segmentation modules to run. options are ['mesmer','cellpose']"
"description": "comma separated list of segmentation modules to run. options are ['mesmer','cellpose']",
"default": "mesmer"
},
"cellpose_model": {
"type": "string",
"description": "optional model file for cellpose segmentation"
"description": "optional model file for cellpose segmentation",
"default": "[]"
},
"registration_method": {
"type": "string",
"default": "ashlar",
"pattern": "^((ashlar|palom)?,?)*(?<!,)$",
"description": "Registration method to be used (ashlar or palom)"
},
"palom_align_channel": {
"type": "integer",
"default": 0,
"description": "Channel to use for image registration"
}
}
},
Expand Down
26 changes: 25 additions & 1 deletion workflows/mcmicro.nf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pi
include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_mcmicro_pipeline'
include { MULTIQC } from '../modules/nf-core/multiqc/main'
include { BASICPY } from '../modules/nf-core/basicpy/main'
include { ALIGNMULTIPLECYCLES } from '../modules/local/palom/alignmultiplecycles/main'
include { ASHLAR } from '../modules/nf-core/ashlar/main'
include { BACKSUB } from '../modules/nf-core/backsub/main'
include { CELLPOSE } from '../modules/nf-core/cellpose/main'
Expand Down Expand Up @@ -56,6 +57,24 @@ workflow MCMICRO {
.dump(tag: 'ch_samplesheet (after BASICPY)')
}

// Image registration
ch_registration = Channel.empty()

ch_samplesheet
.map{ meta, image_tiles, dfp, ffp ->
[[id: meta.id], [meta.cycle_number, image_tiles]]
}
// FIXME: pass groupTuple size: from samplesheet cycle count
.groupTuple(sort: { a, b -> a[0] <=> b[0] })
.map{ meta, cycles -> [meta, *cycles.collect{ it[1..-1] }.transpose()]}
.dump(tag: 'PALOM in')
| ALIGNMULTIPLECYCLES
if (params.registration_method.split(',').contains('palom')) {
ch_versions = ch_versions.mix(ALIGNMULTIPLECYCLES.out.versions)
ch_registration = ch_registration.mix(ALIGNMULTIPLECYCLES.out.tif)
}


ch_samplesheet
.map{ meta, image_tiles, dfp, ffp ->
[[id: meta.id], [meta.cycle_number, image_tiles, dfp, ffp]]
Expand All @@ -72,6 +91,10 @@ workflow MCMICRO {
}
| ASHLAR
ch_versions = ch_versions.mix(ASHLAR.out.versions)
if (params.registration_method.split(',').contains('ashlar')) {
ch_versions = ch_versions.mix(ASHLAR.out.versions)
ch_registration = ch_registration.mix(ASHLAR.out.tif)
}

// // Run Background Correction
// BACKSUB(ASHLAR.out.tif, ch_markers)
Expand All @@ -83,7 +106,8 @@ workflow MCMICRO {
ch_versions = ch_versions.mix(BACKSUB.out.versions)
} else {
*/
ch_segmentation_input = ASHLAR.out.tif
ch_registration.view()
ch_segmentation_input = ch_registration
/*
}
*/
Expand Down