In [1]:
from __future__ import print_function, division
from pprint import pprint
import os
In [2]:
import pbxplore as pbx
PBxplore allows two ways to write fasta files. The sequences can be written either all at once or one at a time. To write a batch of sequences at once, we need a list of sequences and a list of the corresponding sequence names. The writing function here is :func:pbxplore.io.write_fasta
.
In [10]:
names = []
pb_sequences = []
pdb_path = os.path.join(pbx.DEMO_DATA_PATH, '2LFU.pdb')
for chain_name, chain in pbx.chains_from_files([pdb_path]):
dihedrals = chain.get_phi_psi_angles()
pb_seq = pbx.assign(dihedrals)
names.append(chain_name)
pb_sequences.append(pb_seq)
pprint(names)
pprint(pb_sequences)
with open('output.fasta', 'w') as outfile:
pbx.io.write_fasta(outfile, pb_sequences, names)
In [11]:
!cat output.fasta
!rm output.fasta
Sequences can be written once at a time using the :func:pbxplore.io.write_fasta_entry
function.
In [12]:
pdb_path = os.path.join(pbx.DEMO_DATA_PATH, '2LFU.pdb')
with open('output.fasta', 'w') as outfile:
for chain_name, chain in pbx.chains_from_files([pdb_path]):
dihedrals = chain.get_phi_psi_angles()
pb_seq = pbx.assign(dihedrals)
pbx.io.write_fasta_entry(outfile, pb_seq, chain_name)
In [13]:
!cat output.fasta
!rm output.fasta
By default, the lines in fasta files are wrapped at 60 caracters as defined in :const:pbxplore.io.fasta.FASTA_WIDTH
. Both :func:pbxplore.io.write_fasta
and :func:pbxplore.io.write_fasta_entry
have a width
optionnal argument that allows to control the wrapping.
In [14]:
print(pb_sequences[0])
In [15]:
with open('output.fasta', 'w') as outfile:
for width in (60, 70, 80):
pbx.io.write_fasta_entry(outfile, pb_sequences[0],
'width={} blocks'.format(width),
width=width)
In [16]:
!cat output.fasta
!rm output.fasta
In [17]:
pdb_path = os.path.join(pbx.DEMO_DATA_PATH, '2LFU.pdb')
with open('output.phipsi', 'w') as outfile:
for chain_name, chain in pbx.chains_from_files([pdb_path]):
dihedral = chain.get_phi_psi_angles()
for res in sorted(dihedral):
phi = "{:8.2f}".format(dihedral[res]["phi"]) if dihedral[res]["phi"] else " None"
psi = "{:8.2f}".format(dihedral[res]["psi"]) if dihedral[res]["psi"] else " None"
print("{} {:6d} {} {} ".format(chain_name, res, phi, psi), file=outfile)
Note it's better to write the dihedral for each PDB/frame due to the high memory cost to store all of them in a list.
The output is formated with one line per residue. The first columns repeat the name given for the chain, then is the residue id followed by the phi and the psi angle. If an angle is not defined, 'None' is written instead.
In [19]:
!head output.phipsi
!tail output.phipsi
!rm output.phipsi
In [20]:
def pdb_to_fasta_pb(pdb_path, fasta_path):
"""
Write a fasta file with all the PB sequences from a PDB
"""
with open(fasta_path, 'w') as outfile:
for chain_name, chain in pbx.chains_from_files([pdb_path]):
dihedrals = chain.get_phi_psi_angles()
pb_seq = pbx.assign(dihedrals)
pbx.io.write_fasta_entry(outfile, pb_seq, chain_name)
# Write a fasta file
pdb_path = os.path.join(pbx.DEMO_DATA_PATH, '2LFU.pdb')
pdb_to_fasta_pb(pdb_path, 'output.fasta')
# Read a list of headers and a list of sequences from a fasta file
names, sequences = pbx.io.read_fasta('output.fasta')
print('names:')
pprint(names)
print('sequences:')
pprint(sequences)
!rm output.fasta
If the sequences we want to read are spread amongst several fasta files, then we can use the :func:pbxplore.io.read_several_fasta
function that takes a list of fasta file path as argument instead of a single path.
In [21]:
# Write several fasta files
pdb_to_fasta_pb(os.path.join(pbx.DEMO_DATA_PATH, '1BTA.pdb'), '1BTA.fasta')
pdb_to_fasta_pb(os.path.join(pbx.DEMO_DATA_PATH, '2LFU.pdb'), '2FLU.fasta')
# Read the fasta files
names, sequences = pbx.io.read_several_fasta(['1BTA.fasta', '2FLU.fasta'])
# Print the first entries
print('names:')
pprint(names[:5])
print('sequences:')
pprint(sequences[:5])
!rm 1BTA.fasta 2FLU.fasta