Подпроцесс не может поймать стандартный вывод - PullRequest
1 голос
/ 18 мая 2010

Я пытаюсь создать дерево с вводом файла fastta и выравниванием с помощью MuscleCommandline

import sys,os, subprocess
from Bio import AlignIO
from Bio.Align.Applications import MuscleCommandline
cline = MuscleCommandline(input="c:\Python26\opuntia.fasta")
child= subprocess.Popen(str(cline),
                         stdout = subprocess.PIPE,
                         stderr=subprocess.PIPE,
                        shell=(sys.platform!="win32"))
align=AlignIO.read(child.stdout,"fasta")
outfile=open('c:\Python26\opuntia.phy','w')
AlignIO.write([align],outfile,'phylip')
outfile.close()

Я всегда сталкиваюсь с этими проблемами

Traceback (most recent call last):
  File "<string>", line 244, in run_nodebug
  File "C:\Python26\muscleIO.py", line 11, in <module>
    align=AlignIO.read(child.stdout,"fasta")
  File "C:\Python26\Lib\site-packages\Bio\AlignIO\__init__.py", line 423, in read
    raise ValueError("No records found in handle")
ValueError: No records found in handle

Ответы [ 4 ]

4 голосов
/ 18 мая 2010

Здесь есть несколько проблем:

  1. Вам нужен child.wait () после вызова подпроцесса, чтобы ваш код ожидал завершения работы внешней программы.

  2. Muscle на самом деле не пишет в stdout, хотя справочная документация говорит, что это так, по крайней мере с v3.6, что у меня здесь. Я считаю, что последняя версия v3.8, так что это может быть исправлено.

Biopython сообщает вам, что стандартный проход, который вы передаете, пуст, что является ошибкой, которую вы видите. Попробуйте запустить командную строку напрямую:

<code>muscle -in opuntia.fasta

и посмотрите, видите ли вы вывод FASTA. Вот версия, которая устраняет проблему ожидания и использует промежуточный выходной файл:

<code>
import sys,os, subprocess
from Bio import AlignIO
from Bio.Align.Applications import MuscleCommandline
out_file = "opuntia.aln"
cline = MuscleCommandline(input="opuntia.fasta", out=out_file)
child= subprocess.Popen(str(cline),
                         stdout = subprocess.PIPE,
                         stderr=subprocess.PIPE,
                        shell=(sys.platform!="win32"))
child.wait()
with open(out_file) as align_handle:
    align=AlignIO.read(align_handle,"fasta")
outfile=open('opuntia.phy','w')
AlignIO.write([align],outfile,'phylip')
outfile.close()
os.remove(out_file)
2 голосов
/ 18 мая 2010

Из документации библиотеки подпроцесса :

Внимание

Используйте связь () вместо .stdin.write, .stdout.read или .stderr.read, чтобы избежать тупиков из-за любой из других конвейерных буферов ОС наполнение и блокировка ребенка процесс.

так что, возможно, вы могли бы попробовать что-то вроде:

mydata = child.communicate()[0]
1 голос
/ 18 мая 2010

У вас есть незащищенная обратная косая черта в выходном имени файла, что никогда не подходит.

Используйте 'r' для получения необработанных строк, т.е. r'c:\Python26\opuntia.phy'.

0 голосов
/ 21 мая 2010

Biopython 1.54 был выпущен сегодня со стабильной версией модуля Bio.Phylo. Я обновил документацию с примером конвейера для генерации деревьев. Для простоты в примере используется ClustalW для выравнивания последовательностей и создания дерева вместо Muscle и Phylip, но большая часть кода остается такой же или похожей.

http://biopython.org/wiki/Phylo#Example_pipeline

Если вы уже сгенерировали дерево с помощью Phylip (используя выравнивание .phy в качестве входных данных), вы все равно можете следовать примерам Phylo в целом. Филип создает файл Newick с таким именем, как «outttree» или «foo.tree».

(Не стесняйтесь объединить это с ответом Брэда; я пока не могу написать комментарий в этой теме.)

...