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

Develop #2

Merged
merged 136 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
136 commits
Select commit Hold shift + click to select a range
2890d00
minor fix
BioinfoTongLI Nov 8, 2024
6167e30
Merge branch 'master' into develop
BioinfoTongLI Nov 8, 2024
d7b97aa
yet another bad simple quote
BioinfoTongLI Nov 8, 2024
f812f71
use workdir for model caching
BioinfoTongLI Nov 8, 2024
e953425
minor fix
BioinfoTongLI Nov 8, 2024
ccec84e
bump version; use tiffilfe for chunk access
BioinfoTongLI Nov 8, 2024
51493b5
default to /models for external data
BioinfoTongLI Nov 8, 2024
aa06ba0
init spatialdata parallel query
BioinfoTongLI Nov 14, 2024
8b0da56
minor debug
BioinfoTongLI Nov 14, 2024
4733f86
give correct output names to cropping step
BioinfoTongLI Nov 14, 2024
c0440d2
use path for folders
BioinfoTongLI Nov 14, 2024
5928d8d
handle specific case when partition is 1
BioinfoTongLI Nov 14, 2024
a0c03ac
init commit
BioinfoTongLI Nov 20, 2024
dd33e4c
rename properly
BioinfoTongLI Nov 20, 2024
2e1d23d
working version
BioinfoTongLI Nov 20, 2024
e5cf055
add metadata description for the task
BioinfoTongLI Nov 20, 2024
ebc7755
init commit for fractal cellpose
BioinfoTongLI Nov 21, 2024
8a28283
bump version to 0.0.2
BioinfoTongLI Nov 28, 2024
c54c6d2
state python path explicitely
BioinfoTongLI Nov 28, 2024
ea39c83
bump version to 0.5.1 and include model into /models/
BioinfoTongLI Nov 29, 2024
ff7d729
requires double quote
BioinfoTongLI Nov 29, 2024
37cd0b0
hard copy the model into the dir; discard user options
BioinfoTongLI Nov 29, 2024
3a71677
refactored; nf-test passed
BioinfoTongLI Dec 5, 2024
4dad5b5
added tests; save pretrained models into docker; user resources folder
BioinfoTongLI Dec 5, 2024
c174512
delete tiled_stardist
BioinfoTongLI Dec 5, 2024
f1e2272
minor refact for nf-core
BioinfoTongLI Dec 5, 2024
214c092
update meta yam for generatetiles
BioinfoTongLI Feb 2, 2025
6de1648
updated meta yaml for fractal cellpose
BioinfoTongLI Feb 2, 2025
1be4db9
add mergeoutline module binary and nextflow.config
BioinfoTongLI Feb 2, 2025
8591409
update cellpose test file
BioinfoTongLI Feb 2, 2025
d070dfd
update test files to zarr
BioinfoTongLI Feb 2, 2025
6263dc3
add zarr for mergeoutlines
BioinfoTongLI Feb 2, 2025
dd7a3f8
update tiled segmentation subworkflow
BioinfoTongLI Feb 2, 2025
80b6240
add mergeoutlines module
BioinfoTongLI Feb 2, 2025
cca2bf7
added test for stardist
BioinfoTongLI Feb 3, 2025
3c27dea
add stardist helper script
BioinfoTongLI Feb 3, 2025
1622ed7
update
BioinfoTongLI Feb 3, 2025
7f2755f
ignore for now
BioinfoTongLI Feb 3, 2025
2b3c7fc
use the same output channel name between cellpose and stardist
BioinfoTongLI Feb 3, 2025
cc4b26e
update channel value order
BioinfoTongLI Feb 3, 2025
36da187
update test
BioinfoTongLI Feb 3, 2025
591f172
add testing specific config file
BioinfoTongLI Feb 3, 2025
0587794
update test config. Somehow it hangs forever.
BioinfoTongLI Feb 3, 2025
6714573
added stardist option for the subworkflow
BioinfoTongLI Feb 3, 2025
824bf32
update mergeoutlines along with tests
BioinfoTongLI Feb 3, 2025
3d1cdf3
nf-test hangs
BioinfoTongLI Feb 3, 2025
779331b
use the nf-version of MERGE_OUTLINES
BioinfoTongLI Feb 3, 2025
813193d
remove local test files
BioinfoTongLI Feb 3, 2025
a8ec6a9
do not pass cell diameter to the output channels
BioinfoTongLI Feb 3, 2025
774b7a3
minor bug fixing
BioinfoTongLI Feb 3, 2025
2148abe
update stardist test snap
BioinfoTongLI Feb 3, 2025
291d154
init push for instanseg with tests
BioinfoTongLI Feb 6, 2025
b04e7d6
meta.yaml for describing the module IO and empty conda env
BioinfoTongLI Feb 6, 2025
5ea91da
add default testdata_base_path
BioinfoTongLI Feb 6, 2025
e4e2765
added multiple instance test, but hands forever. Added instanseg
BioinfoTongLI Feb 6, 2025
f930573
update minor issue with wkt
BioinfoTongLI Feb 6, 2025
331a080
update cellpose tests and added stub section
BioinfoTongLI Feb 6, 2025
2458057
added stub adn updated unittests.
BioinfoTongLI Feb 6, 2025
ce72cc7
update gitignore
BioinfoTongLI Feb 6, 2025
f6c60fa
add test unittest for spotiflow module
BioinfoTongLI Feb 6, 2025
e9d1f21
added exectable scripts to the module
BioinfoTongLI Feb 6, 2025
78fc5a5
bump container version to 0.5.2
BioinfoTongLI Feb 6, 2025
f582efd
Merge branch 'cellgeni:develop' into develop
BioinfoTongLI Feb 7, 2025
8285b83
removed irrelevant scripts and slightly updated the script
BioinfoTongLI Feb 7, 2025
db1c37b
update test snap accordingly
BioinfoTongLI Feb 7, 2025
f161d25
better variable handling in the process
BioinfoTongLI Feb 7, 2025
9997ed2
minor cleanup and update tests
BioinfoTongLI Feb 7, 2025
7bca20f
slight simplification
BioinfoTongLI Feb 7, 2025
b11ad60
added the module to merge peaks in csv files and output a wkt multipo…
BioinfoTongLI Feb 7, 2025
38765ad
add concatenate peaks
BioinfoTongLI Feb 7, 2025
efbfb40
switch to module based solutions
BioinfoTongLI Feb 7, 2025
c2f4a80
added tests for mergeoutlines
BioinfoTongLI Feb 7, 2025
5611be8
added deepcell module
BioinfoTongLI Feb 7, 2025
3415050
added deepcell and tests into subworkflow. But the test run hangs
BioinfoTongLI Feb 7, 2025
2ac840e
add GPU labels for segmentation tools
BioinfoTongLI Feb 10, 2025
e765ea0
fix typo
BioinfoTongLI Feb 10, 2025
68bf0cb
handle empty detection
BioinfoTongLI Feb 10, 2025
389c373
make the output unique
BioinfoTongLI Feb 10, 2025
42995c9
update deepcell test snap
BioinfoTongLI Feb 11, 2025
b588f12
update instanseg test snap
BioinfoTongLI Feb 11, 2025
fd9b295
update stardist test snap
BioinfoTongLI Feb 11, 2025
82babde
use default to tiffile's lazy chunk loading; add more tracable output…
BioinfoTongLI Feb 11, 2025
a29e2b2
use lazy tile loading for deepcell
BioinfoTongLI Feb 11, 2025
5e4a23a
trying to fix the issue when the largest polygon is of area 0(?)
BioinfoTongLI Feb 11, 2025
43977c4
update postcode to latest; tests don't work yet
BioinfoTongLI Feb 11, 2025
655d54c
add the merfish solution back
BioinfoTongLI Feb 12, 2025
ac0c5cc
reject invalid polygons before merging.
BioinfoTongLI Feb 14, 2025
37fe963
fix stupid typo cropping images
BioinfoTongLI Feb 14, 2025
cf9acaa
fix that stupid error again...
BioinfoTongLI Feb 14, 2025
f24a94c
once again
BioinfoTongLI Feb 14, 2025
56cc9fa
avoid returning none
BioinfoTongLI Feb 16, 2025
d537101
grouple Tuple using meta channel only
BioinfoTongLI Feb 16, 2025
878d03b
apply baseline translation for each tile.
BioinfoTongLI Feb 18, 2025
e164567
externalised get_tile func and bumped cellpose_seg version
BioinfoTongLI Feb 27, 2025
7d65e75
do not enforce gpu tag. Otherwise cannot switch to cpu queues.
BioinfoTongLI Feb 27, 2025
ea16336
update the get tile lib to handle microaligner edge case
BioinfoTongLI Feb 27, 2025
dc4cf77
externalised the whole image parsing
BioinfoTongLI Feb 27, 2025
b057442
use image cropper to get the tile
BioinfoTongLI Feb 27, 2025
2b9b97d
bump spotfilow wrapper version and update test.
BioinfoTongLI Feb 27, 2025
98083d5
update test snap
BioinfoTongLI Feb 27, 2025
2e87179
remove ch_ind in meta to faciliate downstream grouping
BioinfoTongLI Feb 27, 2025
fd1c15c
groupby meta without ch_ind
BioinfoTongLI Feb 27, 2025
49fb71b
update test snap; explicite write xmin/max and ymin/max in the output…
BioinfoTongLI Mar 3, 2025
a58c34d
do not remove ch_ind in peak-calling step
BioinfoTongLI Mar 3, 2025
93e7f82
add back the line for incorporating ch_ind into meta
BioinfoTongLI Mar 4, 2025
157967f
use a dedicated channel for channel index
BioinfoTongLI Mar 4, 2025
9b3ebce
update cropper to pass through the channel index
BioinfoTongLI Mar 4, 2025
e41f0d8
update spotiflow and the container
BioinfoTongLI Mar 4, 2025
ca029aa
do not use local img-cropper. use the imagetileprocessor to fetch tiles
BioinfoTongLI Mar 14, 2025
2be815f
use imagetileprocessor; bump test snap
BioinfoTongLI Mar 14, 2025
c8535dc
update test snap
BioinfoTongLI Mar 14, 2025
ba15989
switch to imagetileprocessor
BioinfoTongLI Mar 14, 2025
514d8b0
update deepcell container version
BioinfoTongLI Mar 14, 2025
4c3b881
use imagetileprocessor with instanseg
BioinfoTongLI Mar 14, 2025
dd8bf53
update instanseg container; remove gpu label
BioinfoTongLI Mar 14, 2025
5cd50e8
use imagetileprocessor with stardist helper
BioinfoTongLI Mar 14, 2025
acb6d51
better naming conversion to keep origianl tool version
BioinfoTongLI Mar 15, 2025
68300d4
update merge peaks
BioinfoTongLI Mar 15, 2025
a2a35af
switch to imagetileprocessor
BioinfoTongLI Mar 15, 2025
5f5a2c7
bump container version
BioinfoTongLI Mar 15, 2025
d0f2372
use exectuable in imagetileprocessor for mergeoutlines; cleanup; upda…
BioinfoTongLI Mar 15, 2025
ff9d1d9
add copy right
BioinfoTongLI Mar 15, 2025
e0042a7
major update of PoSTcode
BioinfoTongLI Mar 15, 2025
bfb8c4a
properly map barcode for both merfish-like and iss-like methods
BioinfoTongLI Mar 15, 2025
2cea5bd
handle minor exception
BioinfoTongLI Mar 15, 2025
86fb3ef
default to geojson for merged segmentation
BioinfoTongLI Mar 16, 2025
da6205d
minor fix for microaligner output
BioinfoTongLI Mar 16, 2025
2176596
better way of passing ext.args to test cases
BioinfoTongLI Mar 16, 2025
b49455c
use imagetileprocessor to do the merging
BioinfoTongLI Mar 18, 2025
866ca82
switch to imagetileprocessor and bump software version
BioinfoTongLI Mar 18, 2025
1b84367
update test snap file
BioinfoTongLI Mar 18, 2025
e8b4172
remove the local script
BioinfoTongLI Mar 18, 2025
cd4b39b
remove hard gpu label, since it will bug when gpu is absent
BioinfoTongLI Mar 18, 2025
ac4cefc
make sure images are of class channel inside the subworkflow
BioinfoTongLI Mar 18, 2025
a648be3
save multipolygon as the other methods
BioinfoTongLI Mar 18, 2025
978dfc3
used workflow snapshot instead of process; removed stub
BioinfoTongLI Mar 18, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ tests/data/
work/
.github/CODEOWNERS-tmp
*.un~
*.nf-test*
45 changes: 25 additions & 20 deletions modules/sanger/bioinfotongli/cellpose/main.nf
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
container_version = "0.1.0"
params.debug = false
params.cellpose_model_dir = "./"

process BIOINFOTONGLI_CELLPOSE {
tag "${meta.id}"
debug params.debug
cache true

label "gpu"
label "medium_mem"

container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
"quay.io/bioinfotongli/tiled_cellpose:${container_version}":
"quay.io/bioinfotongli/tiled_cellpose:${container_version}"}"
"quay.io/cellgeni/tiled_cellpose:0.1.3":
"quay.io/cellgeni/tiled_cellpose:0.1.3"}"
containerOptions = {
workflow.containerEngine == "singularity" ? "--cleanenv --nv -B ${params.cellpose_model_dir}:/tmp/cellpose_models -B ${params.NUMBA_CACHE_DIR}:/tmp/numba_cache":
( workflow.containerEngine == "docker" ? "--gpus all -v ${params.cellpose_model_dir}:/tmp/cellpose_models": null )
workflow.containerEngine == "singularity" ? "--cleanenv --nv":
( workflow.containerEngine == "docker" ? "--gpus all": null )
}

publishDir params.out_dir + "/naive_cellpose_segmentation"
Expand All @@ -24,30 +17,42 @@ process BIOINFOTONGLI_CELLPOSE {
tuple val(meta), val(x_min), val(y_min), val(x_max), val(y_max), path(image), val(cell_diameter)

output:
tuple val(meta), val(cell_diameter), path("${stem}/${stem}_cp_outlines.txt"), emit: outlines, optional: true
tuple val(meta), val(cell_diameter), path("${stem}/${stem}_cp_outlines.wkt"), emit: wkts
tuple val(meta), val(cell_diameter), path("${stem}/${stem}*png"), emit: cp_plots, optional: true
tuple val(meta), path("${prefix}/${prefix}_cp_outlines.txt"), emit: outlines, optional: true
tuple val(meta), path("${prefix}/${prefix}_cp_outlines.wkt"), emit: wkts
tuple val(meta), path("${prefix}/${prefix}*png"), emit: cp_plots, optional: true
path "versions.yml" , emit: versions

script:
stem = "${meta.id}-${x_min}_${y_min}_${x_max}_${y_max}-diam_${cell_diameter}"
prefix = "${meta.id}-${x_min}_${y_min}_${x_max}_${y_max}-diam_${cell_diameter}"
def args = task.ext.args ?: ''
"""
export CELLPOSE_LOCAL_MODELS_PATH=/tmp/cellpose_models
export NUMBA_CACHE_DIR=/tmp/numba_cache
/opt/conda/bin/python /scripts/cellpose_seg.py run \
cellpose_seg.py run \
--image ${image} \
--x_min ${x_min} \
--y_min ${y_min} \
--x_max ${x_max} \
--y_max ${y_max} \
--cell_diameter ${cell_diameter} \
--out_dir "${stem}" \
--out_dir "${prefix}" \
${args}

cat <<-END_VERSIONS > versions.yml
"${task.process}":
: \$(echo \$(/scripts/cellpose_seg.py version 2>&1) | sed 's/^.*cellpose_seg.py //; s/Using.*\$//' ))
: \$(echo \$(cellpose_seg.py version))
END_VERSIONS
"""


stub:
def args = task.ext.args ?: ''
prefix = task.ext.prefix ?: "${meta.id}-${x_min}_${y_min}_${x_max}_${y_max}-diam_${cell_diameter}"
"""
mkdir "${prefix}"
touch "${prefix}/${prefix}_cp_outlines.wkt"

cat <<-END_VERSIONS > versions.yml
"${task.process}":
bioinfotongli: \$(cellpose_seg.py version)
END_VERSIONS
"""
}
47 changes: 37 additions & 10 deletions modules/sanger/bioinfotongli/cellpose/meta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,65 @@ tools:
documentation: "https://cellpose.readthedocs.io/en/latest/"
tool_dev_url: "https://github.com/MouseLand/cellpose"
doi: "https://doi.org/10.1038/s41592-020-01018-x"
licence: ""
licence: ["BSD-3-Clause license"]

input:
# Only when we have meta
- meta:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'test', use_gpu:true, channels:[1,2] ]`
e.g. `[ id:'test' ]`

- x_min:
type: integer
description: x_min of the region of interest

- x_max:
type: integer
description: x_max of the region of interest

- y_min:
type: integer
description: y_min of the region of interest

- y_max:
type: integer
description: y_max of the region of interest

- imgs:
type: file
description: raw images for segmentation
pattern: "*.{tif,ome.tif,ome.tiff,png}"
pattern: "*.{tif,ome.tif,ome.tiff}"

- cell_diameter:
type: integer
description: expected cell diameter in pixels

output:
#Only when we have meta
- meta:
type: map
description: |
description:
Groovy Map containing sample information
e.g. `[ id:'test', use_gpu:true, channels:[0,1] ]`
e.g. `[ id:'test' ]`

- versions:
type: file
description: File containing software versions
pattern: "versions.yml"

- segmentation:
- "${stem}/${stem}_cp_outlines.txt":
type: file
description: folder contains segmentation information
pattern: "*"
description:
pattern: "*.txt"

- "${stem}/${stem}_cp_outlines.wkt":
type: file
description:
pattern: "*.wkt"

- "${stem}/${stem}*png":
type: file
description:
pattern: "*.png"
authors:
- "@BioinfoTongLI"
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Wellcome Sanger Institute

"""
This script will slice the image in XY dimension and save the slices coordinates in json files
"""
import fire
import os
from cellpose import core, io, models
import numpy as np
from shapely import Polygon, wkt, MultiPolygon
from glob import glob
from imagetileprocessor import slice_and_crop_image

import logging

logging.basicConfig(level=logging.INFO)

VERSION="0.1.3"


def main(
image:str,
x_min:int, x_max:int, y_min:int, y_max:int,
out_dir:str,
cell_diameter:int=30,
cellpose_model:str="cyto3",
zs:list=[0],
channels:list=[0, 0],
resolution_level:int=0,
**cp_params
):

crop = slice_and_crop_image(
image, x_min, x_max, y_min, y_max, zs, np.array(channels), resolution_level
)
# if z is missing, add it
if len(crop.shape) == 3:
crop = np.expand_dims(crop, axis=0)

logging.info(f"Loading Cellpose model: {cellpose_model} (GPU: {core.use_gpu()})")
model = models.Cellpose(gpu=core.use_gpu(), model_type=cellpose_model)
# model = denoise.CellposeDenoiseModel(
# gpu=core.use_gpu(),
# model_type=cellpose_model,
# restore_type="denoise_cyto3",
# chan2_restore=False
# )

masks, flows, _, _ = model.eval(
crop,
channels=channels,
diameter=cell_diameter,
channel_axis=1,
z_axis=0,
**cp_params,
)
os.mkdir(out_dir)
io.save_masks(
np.squeeze(crop),
masks,
flows,
file_names=out_dir,
save_txt=True,
png=True,
tif=False,
save_flows=False,
save_outlines=True,
savedir=out_dir,
)
# convert cellpose outlines to WTK
logging.info(f"Converting outlines to WKT format")
# prefix_list = out_dir.split(".")
# if len(prefix_list) > 1:
# prefix = ".".join(prefix_list[:-1])
# else:
# prefix = prefix_list[0]
# outlines_file = os.path.join(out_dir, f"{prefix}_cp_outlines.txt")
outline_file = glob(f"{out_dir}/*_cp_outlines.txt")

if len(outline_file) > 0:
# if os.path.exists(outlines_file):
wkts = []
with open(outline_file[0], "rt") as f:
for line in f.readlines():
# split by comma and make integer
try:
outline = list(map(int, line.strip().split(",")))
except:
continue
outline = np.array(list(zip(outline[::2], outline[1::2])))
# transport tile coordinats to original image coordinates
outline[:, 0] += x_min
outline[:, 1] += y_min
poly = Polygon(outline).buffer(0)
if isinstance(poly, MultiPolygon):
poly = poly.geoms[0]
wkts.append(poly)

wkt_filename = os.path.join(out_dir, f"{out_dir}_cp_outlines.wkt")
with open(wkt_filename, "wt") as f:
f.write(wkt.dumps(MultiPolygon(wkts)))
else:
logging.info("No outlines file found")
with open(os.path.join(out_dir, f"{out_dir}_cp_outlines.wkt"), "wt") as f:
f.write("")


if __name__ == "__main__":
options = {
"run": main,
"version": VERSION,
}
fire.Fire(options)
109 changes: 109 additions & 0 deletions modules/sanger/bioinfotongli/cellpose/tests/main.nf.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
nextflow_process {

name "Test Process BIOINFOTONGLI_CELLPOSE"
script "../main.nf"
config "./nextflow.config"
process "BIOINFOTONGLI_CELLPOSE"

tag "modules"
tag "modules_sanger"
tag "bioinfotongli"
tag "bioinfotongli/cellpose"

test("mouse_heart - tiff - 500") {

when {
process {
"""
input[0] = [
[ id:'test'],
0, 0, 500, 500,
file(params.modules_testdata_base_path + 'imaging/tiff/mindagap.mouse_heart.wga.tiff', checkIfExists: true),
20,
]
"""
}
}

then {
assertAll(
{ assert process.success },
{ assert snapshot(process.out).match() }
)
}
}

test("mouse_heart - tiff - 200") {

when {
process {
"""
input[0] = [
[ id:'test'],
0, 0, 200, 200,
file(params.modules_testdata_base_path + 'imaging/tiff/mindagap.mouse_heart.wga.tiff', checkIfExists: true),
20,
]
"""
}
}

then {
assertAll(
{ assert process.success },
{ assert snapshot(process.out).match() }
)
}
}


test("mouse_heart - tiff - 200 - large cell diameter") {

when {
process {
"""
input[0] = [
[ id:'test'],
0, 0, 200, 200,
file(params.modules_testdata_base_path + 'imaging/tiff/mindagap.mouse_heart.wga.tiff', checkIfExists: true),
50,
]
"""
}
}

then {
assertAll(
{ assert process.success },
{ assert snapshot(process.out).match() }
)
}
}

test("mouse_heart - tiff - stub") {

options "-stub"

when {
process {
"""
input[0] = [
[ id:'test',],
0, 0, 100, 100,
file(params.modules_testdata_base_path + 'imaging/tiff/mindagap.mouse_heart.wga.tiff', checkIfExists: true),
20,
]
"""
}
}

then {
assertAll(
{ assert process.success },
{ assert snapshot(process.out).match() }
)
}

}

}
Loading