O subprocesso falha em capturar a saída padrão
-
27-09-2019 - |
Pergunta
Estou tentando gerar árvore com entrada de arquivo fasta e alinhamento com 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()
Eu sempre encontro com esses problemas
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
Solução
O BiopyThon 1.54 foi lançado hoje com uma versão estável do módulo Bio.phylo. Atualizei a documentação com um exemplo de pipeline para gerar árvores. Por simplicidade, o exemplo usa o Clustalw para alinhar sequências e gerar uma árvore, em vez de músculo e filipro, mas a maior parte do código ainda é a mesma ou semelhante.
http://biopython.org/wiki/phylo#example_pipeline
Se você já gerou uma árvore com filipra (usando o alinhamento .phy como entrada), ainda pode seguir os exemplos de fylo em geral. Phylip cria um arquivo novo com um nome como "Outttree" ou "foo.tree".
(Sinta -se à vontade para mesclar isso com a resposta de Brad; não posso escrever um comentário nesse tópico ainda.)
Outras dicas
Algumas coisas estão dando problemas aqui:
Você precisa de um filho.wait () após a chamada do subprocesso para que seu código aguarde até que o programa externo seja feito em execução.
Na verdade, o músculo não escreve para o stdout, mesmo que a documentação de ajuda diga, pelo menos com a v3.6 que eu tenho aqui. Eu acredito que o mais recente é v3.8, então isso pode ser corrigido.
O Biopython está lhe dizendo que o stdout que você está passando está vazio, que é o erro que você está vendo. Tente executar a linha de comando diretamente:
muscle -in opuntia.fasta
E veja se você vê a saída do FASTA. Aqui está uma versão que corrige o problema de espera e usa um arquivo de saída intermediário:
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)
Da documentação do Biblioteca de subprocas:
Aviso
Use Communicate () em vez de .stdin.write, .stdout.read ou .stderr.read para evitar impasses devido a qualquer outro tampão de tubo do sistema operacional enchendo e bloqueando o processo filho.
Então, talvez você possa tentar algo como:
mydata = child.communicate()[0]
Você tem uma barra de barriga desprotegida no seu nome de arquivo de saída, que nunca é bom.
Use 'r' para obter cordas cruas, ou seja, r'c:\Python26\opuntia.phy'
.