如何在nextflow中调用bash脚本并管理多个输入



我正试图将bash脚本集成到我的nextflow管道中。bash脚本从两个目录读取bed文件,并对它们执行相交操作。在运行管道之前,我的目录结构如下:

results
├── extract_gimme
│   ├── gimme_scan_Ss1
│   ├── gimme_scan_Ss2
│   ├── gimme_scan_Ss3
│   ├── gimme_scan_Ss4
│   └── gimme_scan_Ss5
├── gimme_scan
├── motifs_nr_coord
我的bash脚本如下:
# get list of extract_gimme/ & write to txt
ls $1 > dir_list.txt
echo "intersect starts here!"
echo "------------------------"
echo " "
#now run loop for each dir inside dir_list.txt
while read DIR;
do
# declare the two directories for intersect
bed_dir="$1$DIR"
ls $bed_dir > bed_files.txt
coord_dir="results/motifs_nr_coord"
#create directory to save outputs for each DIR
DIR_A="results/motifs_loc"
DIR_B=$(echo $DIR| cut -d'_' -f 3) #this will  get Ss[12345]
motif_dir="$DIR_A"/"$DIR_B"
mkdir -p $motif_dir # to output results
# process each sub dir using loop & run intersect
while read BED;
do
bedtools intersect -a $bed_dir"/"$BED -b $coord_dir"/"$BED -wa | sort | uniq > $motif_dir"/"$BED"_intersected.bed"
done < bed_files.txt
rm bed_files.txt
echo "sample processing for $DIR_B done!!"
echo " "
echo "**********************"
done  < dir_list.txt
rm dir_list.txt

下面是我非常干燥的nextflow管道:

#!/usr/bin/env nextflow
nextflow.enable.dsl=2

params.gimme_scan_dir = "results/extract_gimme"

process INTERSECT {
publishDir "results", mode: 'copy', overwrite: false

input:
path scan_dir

output:
path '*'

script:
"""
$baseDir/intersect_scan_coord.sh $scan_dir
"""
}

workflow {
scan_dir = Channel.fromPath(params.gimme_scan_dir, type: 'dir')
INTERSECT(scan_dir)

}
我使用这个命令在我的终端上运行bash:

。myscript.sh结果/extract_gimme

脚本在终端上运行良好,并输出来自extract_gimme中的每个子目录(即Ss1, Ss2…)的bed文件相交与motifs_nr_coord。

但是当我在nextflow管道中使用相同的脚本时,它不会输出相交的文件,而是创建空的但期望的目录。

nextflow运行测试。nf结果/extract_gimme

下面是运行nextflow管道后的目录结构。

results
├── extract_gimme
│   ├── gimme_scan_Ss1
│   ├── gimme_scan_Ss2
│   ├── gimme_scan_Ss3
│   ├── gimme_scan_Ss4
│   └── gimme_scan_Ss5
├── gimme_scan
├── motifs_nr_coord
└── results
└── motifs_loc
├── Ss1
├── Ss2
├── Ss3
├── Ss4
└── Ss5

我假设需要包括床文件到输入通道,但不知道如何,因为它涉及到目录和子目录。

我可以使用一些关于如何在我的nextflow管道中实现bash脚本的指针。

谢谢你的帮助。

我认为一个更简单的解决方案是传入gimme_scan BED文件坐标BED文件,并为每个文件创建一个通道。注意,我们可以使用fromFilePairs工厂方法尝试从父目录提取样本/扫描ID。我刚刚在这里使用了shell块来嵌入脚本,但您可以将其替换为运行shell脚本的脚本块,就像您最初使用的那样:

params.gimme_scan_bed_files = './results/extract_gimme/*/*.bed'
params.coord_bed_files = './results/motifs_nr_coord/*.bed'
params.outdir = './outdir'
process INTERSECT {
tag { scan_id }
publishDir "${params.outdir}/intersect", mode: 'copy'
input:
tuple val(scan_id), path('bed_dir/*')
path 'coord_dir/*'
output:
tuple val(scan_id), path("${scan_id}/*")
shell:
'''
mkdir "!{scan_id}"
for bed in bed_dir/*; do
bedtools intersect \
-a "${bed}" \
-b "coord_dir/$(basename "${bed}")" \
-wa |
sort \
-u \
> "!{scan_id}/$(basename "${bed}" '.bed')_intersected.bed"
done
'''
}
workflow {
Channel
.fromFilePairs( params.gimme_scan_bed_files, size: -1) {
it.parent.name.substring(it.parent.name.lastIndexOf('_') + 1)
}
.set { gimme_scan_bed_files }
Channel
.fromPath( params.coord_bed_files )
.collect()
.set { coord_bed_files }
INTERSECT( gimme_scan_bed_files, coord_bed_files )
INTERSECT.out.view()
}