Sottoprocesso non riesce a catturare lo standard output
-
27-09-2019 - |
Domanda
Sto cercando di generare albero con file di input fasta e allineamento con 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()
Ho sempre incontro con questi problemi
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
Soluzione
Biopython 1.54 è stato rilasciato oggi con una versione stabile del modulo Bio.Phylo. Ho aggiornato la documentazione con un esempio gasdotto per gli alberi di generazione. Per semplicità, l'esempio utilizza ClustalW a sequenze di allineamento e generare un albero, invece di muscolo e Phylip, ma la maggior parte del codice è ancora lo stesso o simile.
http://biopython.org/wiki/Phylo#Example_pipeline
Se hai già generato un albero con Phylip (utilizzando l'allineamento .phy come input), è ancora possibile seguire gli esempi Phylo in generale. Phylip crea un file Newick con un nome come "outttree" o "foo.tree".
(sentitevi liberi di fondersi questo con la risposta di Brad;. Non riesco a scrivere un commento in quel filo ancora)
Altri suggerimenti
Un paio di cose stanno dando problemi qui:
-
Hai bisogno di una child.wait () dopo la chiamata sottoprocesso in modo che il codice verrà attendere che il programma esterno è fatto in esecuzione.
-
muscolare in realtà non scrivere sullo standard output, anche se la documentazione di aiuto dice lo fa, per lo meno con v3.6 che ho qui. Credo che l'ultima è v3.8 quindi questo potrebbe essere risolto.
Biopython è che indica che lo stdout si sta passando è vuota, che è l'errore che state vedendo. Provare a eseguire direttamente la riga di comando:
muscle -in opuntia.fasta
e vedere se si vede l'uscita FASTA. Ecco una versione che risolve il problema di attesa e gli usi un file di output intermedio:
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)
Dalla documentazione del subproccess biblioteca :
Attenzione
Usa comunicare () piuttosto che .stdin.write, .stdout.read o .stderr.read al fine di evitare situazioni di stallo a causa di qualsiasi degli altri buffer OS tubi riempiendo e bloccando il bambino processo.
in modo forse si potrebbe provare qualcosa di simile:
mydata = child.communicate()[0]
Si dispone di un backslash non protetto nel nome del file di output, che non è mai buona.
Usa 'r' per ottenere le stringhe prime, vale a dire r'c:\Python26\opuntia.phy'
.