-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.nf
156 lines (111 loc) · 3.65 KB
/
main.nf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env nextflow
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rendeirolab/lazyslide-nextflow
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Github : https://github.com/rendeirolab/lazyslide-nextflow
----------------------------------------------------------------------------------------
*/
nextflow.enable.dsl = 2
params.input = "data/input.csv"
// Path to the input CSV
params.slide_col = "slide"
params.outdir = "results/"
// Directory for outputs
params.aggregated_output = "results/aggregated_features.zarr"
params.models = "vgg16,resnet50"
params.tilePx = 256
params.mpp = 'none'
params.model_list = params.models?.split(',') as List
workflow {
log.info(
"""
██ █████ ███████ ██ ██ ███████ ██ ██ ██████ ███████
██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██ ██
██ ███████ ███ ████ ███████ ██ ██ ██ ██ █████
██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██
███████ ██ ██ ███████ ██ ███████ ███████ ██ ██████ ███████
===================================================================
Workflow information:
Workflow: ${workflow.projectDir}
Input parameters:
Slide table: ${file(params.input)}
Tile size: ${params.tilePx}px
Tile mpp: ${params.mpp}
Feature extraction models: ${params.model_list}
The results will be available at: ${params.outdir}
"""
)
input = file(params.input)
updated_csv = Channel
.fromPath(input)
.splitCsv(header: true)
.map { row ->
{
def slide = row[params.slide_col]
def updatedSlide
if (file(slide).exists()) {
updatedSlide = slide
}
else {
updatedSlide = file(input).parent / slide
}
row[params.slide_col] = updatedSlide.toString()
return row
}
}
slide_list = updated_csv.map { row ->
row[params.slide_col]
}
processed = processWSI(slide_list)
processed = featureExtraction(processed, params.model_list)
aggregateResults(processed.collect(), input, params.model_list)
}
process processWSI {
tag { "${wsi_path}" }
label 'preprocess'
input:
val wsi_path
output:
val wsi_path, emit: wsis
script:
def mpp_part = "--mpp ${params.mpp}"
if (params.mpp == 'none') {
mpp_part = ""
}
"""
lazyslide preprocess ${wsi_path} --tile-px ${params.tilePx} ${mpp_part}
"""
}
process featureExtraction {
tag { "${model} ${wsi}" }
label 'feature_extraction'
input:
val wsi
each model
output:
val wsi, emit: wsis
script:
def n_workers = (task.cpus / 2).toInteger()
if (n_workers > 8) {
n_workers = 8
}
"""
lazyslide feature ${wsi} --model ${model} --num-workers ${n_workers}
"""
}
process aggregateResults {
tag { "${model}" }
label 'aggregation'
publishDir "${params.outdir}/agg", pattern: "*.zarr"
input:
val wsis
val csv_file
each model
output:
path "*.zarr"
script:
"""
lazyslide agg ${csv_file} --feature-key ${model} --wsi-col ${params.slide_col}
"""
}