Skip to content
Snippets Groups Projects
Commit 370813d1 authored by Jean-Karim Heriche's avatar Jean-Karim Heriche
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
FROM r-base:4.4.2
RUN apt update && apt install -y libssl-dev liblzma-dev libbz2-dev libicu-dev libtiff-dev libfftw3-dev libcurl4-openssl-dev libxml2-dev libssh2-1-dev libgit2-dev libfontconfig1-dev libfreetype-dev libharfbuzz-dev libfribidi-dev default-jre default-jdk
RUN R -e "install.packages('BiocManager', repos=c('https://cloud.r-project.org/', 'https://ftp.gwdg.de/pub/misc/cran/')); BiocManager::install('EBImage');"
# Create user
RUN useradd -m image_analyst -d /home/image_analyst
# Run as user ide to avoid running as root
USER image_analyst
#RUN mkdir -p /home/image_analyst/R/libs && echo 'R_LIBS=/home/image_analyst/R/libs\n' > /home/image_analyst/.Renviron
COPY image_analysis.R /home/image_analyst/.
CMD ["/home/image_analyst/image_analysis.R"]
#!/usr/bin/env Rscript
library(EBImage)
args <- commandArgs(trailingOnly = TRUE)
img.dir <- ""
output.dir <- ""
if(length(args) < 1) {
stop("No input directory provided.")
} else {
img.dir <- args[1]
if(length(args) == 2) {
output.dir <- args[2]
}
}
image.list <- list.files(img.dir, pattern = "*.tif", full.names = TRUE)
for(img.file in image.list) {
img <- readImage(img.file)
# Invert
img <- max(img) - img
# Remove well boundaries
# Threshold
threshold <- otsu(img)
mask <- img > threshold
mask <- dilate(mask, makeBrush(33, shape = 'box'))
# Segmentation
obj.labels <- bwlabel(mask)
obj.sizes <- table(obj.labels)[-1]
idx.to.remove <- which(obj.sizes < 30000)
well <- rmObjects(obj.labels, idx.to.remove)
well[well>0] <- 1
mask <- (img > threshold) - well
mask[mask<=0] <- 0
# Segment the larvae
mask <- erode(mask, makeBrush(3, shape = 'line'))
obj.labels<- watershed(distmap(mask))
obj.sizes <- table(obj.labels)[-1]
idx.to.remove <- which(obj.sizes <= 30)
obj.labels <- rmObjects(obj.labels, idx.to.remove)
# print(table(obj.labels))
obj.colors <- colorLabels(obj.labels)
writeImage(obj.colors, file = file.path(output.dir,
paste0(tools::file_path_sans_ext(basename(img.file)), "-segmented.png")))
features <- computeFeatures.moment(x = obj.labels, ref = img)
write.csv(features, file.path(output.dir,
paste0(tools::file_path_sans_ext(basename(img.file)), ".csv")))
}
// executor {
// name = 'slurm'
// queueSize = 2
// }
docker {
enabled = true
registry = ""
runOptions = '-u $(id -u):$(id -g)'
}
aws {
accessKey = 'nxf_anon'
secretKey = 'a4ay0TwCg7'
client {
endpoint = "https://s3.embl.de"
s3PathStyleAccess = true
}
}
#!/usr/bin/env nextflow
nextflow.enable.dsl=2
/*
This workflow processes a directory of movies in avi container
format and converts them to multi-page tiff files.
The --dt argument controls the number of movie frames to include in the tiff
file and takes as parameter an integer n which indicates that every nth frame
will be selected.
Usage:
nextflow run preprocess.nf --inputdir </path/to/input_dir> \
--outputdir </path/to/output_dir> \
--dt <n>
*/
// Set default value
params.dt = "15" // use every nth frame
/* Get all .avi files recursively in all inputdir subdirectories.
We skip small avi files as they are most likely artefacts (e.g.
false start of recording).
Note 1: baseName strips the file name extension after the last dot.
Note 2: ffmpeg isn't guaranteed to return a non-zero exit code on error.
The use of the -xerror option makes the behaviour more consistent with
expectation but still doesn't cover all cases.
*/
inputFile = Channel
.fromPath( "${params.inputdir}/**.avi" )
.filter { it.size() > 1000000000 } // skip small files
.map { file -> def dir = file.getParent().getName()
return tuple(file.baseName, dir, file) }
process AVI_TO_TIFF {
shell '/bin/bash'
memory { 8.GB * task.attempt }
time { 5.minutes * task.attempt }
errorStrategy { (task.exitStatus in 137..140 || task.exitStatus == 143) ? 'retry' : 'finish' }
maxRetries 3
debug true
input:
tuple val(fileName), val(dir), path(aviPath)
output:
tuple path("${fileName}"), path("${fileName}/${fileName}-frame*.tif"), emit: images
script:
"""
echo "Starting conversion of ${aviPath}..."
[ -d ${fileName} ] || mkdir ${fileName}
ffmpeg -xerror -i ${aviPath} -vf "format=gray,select=not(mod(n\\,${params.dt}))" -vsync vfr -pix_fmt gray -compression_algo lzw "${fileName}/${fileName}-frame%05d.tif"
echo "Conversion is done!"
"""
}
process SEGMENTATION_AND_FEATURE_EXTRACTION {
shell '/bin/bash'
container "analyse_images"
publishDir "${params.outputdir}", mode: 'copy'
memory { 8.GB * task.attempt }
time { 5.minutes * task.attempt }
errorStrategy { (task.exitStatus in 137..140 || task.exitStatus == 143) ? 'retry' : 'finish' }
maxRetries 3
debug true
input:
tuple path(imageDir), path(images)
output:
tuple path("${imageDir}/*.png"), path("${imageDir}/*.csv")
script:
"""
echo "Starting analysis of images from ${imageDir}..."
image_analysis.R ${imageDir} ${imageDir}
echo "Done."
"""
}
workflow {
AVI_TO_TIFF(inputFile)
SEGMENTATION_AND_FEATURE_EXTRACTION(AVI_TO_TIFF.out.images)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment