1
$\begingroup$

I routinely use AlignIO in BioPython for manipulating alignments and in context here moving from fasta format to phylip format. Alot of phylogeny packages accept a relaxed (sequence ID) & sequential (sequence) phylip format. This format is user-friendly, helps double-check for alignment errors and can be the essential input format.

A typical bit of code is,

'''
Converts a fasta file to phylip format
'''
from Bio import AlignIO

Class Convert (inheritClass):
   
    def fa2phy (self):
        fileOut, fileIn = self._inOut() # builds the path name and deletes any pre-exising outfile
        align = AlignIO.read(fileIn, "fasta") # reads the alignment in fasta
        AlignIO.write(align, fileOut, "phylip-relaxed") # writes in phylip

The output of "phylip-relaxed" is interleaved format

4 120
virusA_detailed_description ACGTGACG .... ATCCCCAA
virusB_detailed_description ACGTGACG .... ATCGGGAA
virusC_detailed_description ACGTGACG .... ATCAAAAA
virusD_detailed_description ACGTGACG .... ATTTTTAA

ACGTGACG .... ATCCCCAA
ACGTGACG .... ATCGGGAA
ACGTGACG .... ATCAAAAA
ACGTGACG .... ATTTTTAA

Output sought is relaxed-sequential

4 120
virusA_detailed_description ACGTGACG .... ATCCCCAAACGTGACG .... ATCCCCAA
virusB_detailed_description ACGTGACG .... ATCGGGAAACGTGACG .... ATCGGGAA
virusC_detailed_description ACGTGACG .... ATCAAAAAACGTGACG .... ATCAAAAA
virusD_detailed_description ACGTGACG .... ATTTTTAAACGTGACG .... ATTTTTAA

There is an option to allow a sequential format (above). HOWEVER, a "phylip-sequential" option output is as follows (it truncates the sequence ID to 10 characters,

4 120
virusA_det ACGTGACG .... ATCCCCAAACGTGACG .... ATCCCCAA
virusB_det ACGTGACG .... ATCGGGAAACGTGACG .... ATCGGGAA
virusC_det ACGTGACG .... ATCAAAAAACGTGACG .... ATCAAAAA
virusD_det ACGTGACG .... ATTTTTAAACGTGACG .... ATTTTTAA

No matter how I look through AlignIO options the above is the nearest format. Could anyone point to a IO style solution? I could write it, but that defeats the object (i.e. purpose not an instance of a method).


Note the "...." in the outputs above are not a typical "sequence identity" symbols, it just means that total length of a line in an interleaved format is 60 nucleotides (it might be 80).

$\endgroup$
1
  • $\begingroup$ I think the solution is to output using SeqIO, i.e. one sequence a time $\endgroup$
    – M__
    Jun 30 '20 at 12:07
1
$\begingroup$

I have nutted out a solution for you.

If this is the content of input.fa:

>virusA_detailed_description
ACGTGACGATCCCCAAACGTGACGATCCCCAA
>virusB_detailed_description
ACGTGACGATCGGGAAACGTGACGATCGGGAA
>virusC_detailed_description
ACGTGACGATCAAAAAACGTGACGATCAAAAA
>virusD_detailed_description
ACGTGACGATTTTTAAACGTGACGATTTTTAA

And this is the script:

#!/usr/bin/env python3

'''
Converts a fasta file to phylip format
'''

from Bio import AlignIO
from Bio.AlignIO.PhylipIO import PhylipWriter
import sys

infile = sys.argv[1]
outfile = sys.argv[2]
idwidth = int(sys.argv[3])
with open(infile, 'r') as input_handle:
    align = AlignIO.read(input_handle, "fasta")
    with open(outfile, 'w') as output_handle:
        PhylipWriter(output_handle).write_alignment(align, id_width=idwidth)

Then, save this script as phylpwrtr.py and do:

chmod +x phylpwrtr.py
./phylpwrtr.py input.fa output_longids.phy 30 # 30 is the width of the header, adjust the value to adjust header length

The contents of output_longids.phy looks like:

 4 32
virusA_detailed_description    ACGTGACGAT CCCCAAACGT GACGATCCCC AA
virusB_detailed_description    ACGTGACGAT CGGGAAACGT GACGATCGGG AA
virusC_detailed_description    ACGTGACGAT CAAAAAACGT GACGATCAAA AA
virusD_detailed_description    ACGTGACGAT TTTTAAACGT GACGATTTTT AA
$\endgroup$
1
  • $\begingroup$ Wow! Thank you PhylipWriter is the solution ... huge thanks! :-) $\endgroup$
    – M__
    Jul 2 '20 at 11:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.