Связывание подпроцессов в Python - PullRequest
0 голосов
/ 30 января 2012

Привет, у меня был вопрос о связывании ввода и вывода с подпроцессами в python. Я пытаюсь упростить программу, пропуская вывод одного шага, передавая его другому подпроцессу, а не выводя его в файл. Затем откройте другой процесс для запуска этого файла.

например. Первый процесс использует SAMTOOLS для вывода определенной хромосомы из большого файла BAM. Так... bigfile.bam считывается и выводит chromosome22.bam

Следующий подпроцесс использует BEDTOOLS для преобразования этой хромосомы22.bam в хромосому22.bed Так... chromosome22.bam считывается и выводит chromosome22.bed

Я хочу передать стандартный вывод первого процесса во второй, чтобы промежуточный файл не требовался.

Пока у меня есть это ...

for x in 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,'X','Y':
   subprocess.call("%s view -bh %s %s > %s/%s/%s.bam" % (samtools,bam,x,bampath,out,x), shell=True)

Это создает файлы хромосом [1-22, X, Y] .bam. Но можно ли этого избежать и поместить в тот же цикл еще одну команду подпроцесса, чтобы преобразовать их в файлы постели?

Команда для преобразования кровати:

bedpath/bedtools bamtobed -i [bamfile] > [bedfile]

Ответы [ 3 ]

4 голосов
/ 30 января 2012

Пожалуйста, посмотрите на пример замена конвейера оболочки в документации.

1 голос
/ 30 января 2012

Нет необходимости использовать Python здесь. Гораздо проще в оболочке . Но, по сути, он работает так же, как и в python.

Если постельные принадлежности могут читать со стандартного ввода, вы можете, например, делаем

#!/bin/sh
for x in `seq 1 22` X Y; do
   $samtools view -bh $bam $x | $bedtools bamtobed > $bampath/$out/$x.bam
done

В зависимости от того, как bedtools был обработан, вам также может понадобиться использовать -i -, чтобы прочитать его из stdin.

Если вы придерживаетесь Python, я настоятельно рекомендую узнать, как это сделать

  1. не делая этого во всех оболочках,
  2. без выдачи команд оболочки, которые необходимо корректно экранировать, чтобы избежать ошибок

subprocess более безопасно для использования при использовании синтаксиса на основе массива и без оболочки . Сделайте это два вызова подпроцесса, по одному для каждой команды. Подробнее см. http://docs.python.org/library/subprocess.html#replacing-shell-pipeline.

cmd1 = [samtools, "view", "-bh", bam, x]
cmd2 = [bedtools, "bamtobed"]

c1 = subprocess.Popen(cmd1, stdout=subprocess.PIPE)
c2 = subprocess.Popen(cmd2, stdin=c1.stdout, stdout=open(outputfilename, "w"))
c1.stdout.close()
c2.communicate()
0 голосов
/ 30 января 2012

Да, вы можете использовать функциональность трубы. Посмотрите, можете ли вы читать из stdin процесс bamtobed ​​... если можете, попробуйте следующее. Таким образом, вы экономите время ввода-вывода на диск, предполагая, что нагрузка при обработке невелика.

МЕДЛЕННАЯ модификация:

proc1.stdout теперь является стандартным для второго процесса.

proc1 = subprocess.call("%s view -bh %s %s" % (samtools,bam,x,bampath,out,x), shell=True, stdout=subprocess.PIPE)

proc2 = subprocess.call("bedpath/bedtools bamtobed > %s" % (outFileName, ), shell=True, stdin=proc1.stdout)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...