Skip to content

Commit 6b97b38

Browse files
author
Alfie Brownless
committed
Added system exit for duplicate waters. Made pdb naming schemes more flexible.
1 parent 1340088 commit 6b97b38

2 files changed

Lines changed: 70 additions & 7 deletions

File tree

WatCon/generate_static_networks.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,8 @@ def extract_objects(pdb_file, network_type, custom_selection, active_region_refe
12071207
ats = [atom for atom in mol.atoms if 'O' in atom.name]
12081208

12091209
#Water molecules are objects which contain H1, H2, O atoms
1210+
if len([f for f in ats if f.name=='O']) > 1:
1211+
raise SystemExit(f'Detected multiple oxygen atoms per one water molecule, exiting. Check for duplicates in residue {mol.resid}!')
12101212
water_network.add_water(mol.resid, *ats, mol.resid)
12111213

12121214
if directed:
@@ -1372,11 +1374,13 @@ def process_pdb(pdb_file, coords=None, ref_coords=None, references=None):
13721374
#If an MSA has been performed
13731375
if msa_indexing == True:
13741376
#Assuming fasta file is named similarly to the pdb -- need sequence files for MSA alignment
1377+
fasta_individual = [f for f in os.listdir(fasta_directory) if (pdb_file.split('_')[0] in f and 'fa' in f)]
1378+
if len(fasta_individual) == 0:
1379+
fasta_individual = [f for f in os.listdir(fasta_directory) if (pdb_file.split('.')[0] in f and 'fa' in f)]
13751380
try:
1376-
fasta_individual = [f for f in os.listdir(fasta_directory) if (pdb_file.split('_')[0] in f and 'fa' in f)][0] #THIS IS NOT GENERALIZED
1381+
fasta_individual = fasta_individual[0]
13771382
except:
1378-
print(f'Warning: Could not find an equivalent fasta file for {pdb_file}. Check your naming schemes!')
1379-
raise ValueError
1383+
raise SystemExit(f'Warning: Could not find an equivalent fasta file for {pdb_file}, exiting. Check your naming schemes!')
13801384

13811385
#Generate MSA alignment if file does not exist and output MSA indices corresponding to partcicular sequence
13821386
msa_indices = sequence_processing.generate_msa_alignment(alignment_file, combined_fasta, os.path.join(fasta_directory, fasta_individual))
@@ -1526,10 +1530,13 @@ def process_pdb(pdb_file, coords=None, ref_coords=None, references=None):
15261530
if MSA_reference_pdb is not None:
15271531
u = mda.Universe(os.path.join(pdb_dir, MSA_reference_pdb))
15281532
reference_resids = u.residues.resids.tolist()
1533+
fasta_individual = [f for f in os.listdir(fasta_directory) if (MSA_reference_pdb.split('_')[0] in f and 'fa' in f)]
1534+
if len(fasta_individual) == 0:
1535+
fasta_individual = [f for f in os.listdir(fasta_directory) if (MSA_reference_pdb.split('.')[0] in f and 'fa' in f)]
15291536
try:
1530-
fasta_individual = [f for f in os.listdir(fasta_directory) if (MSA_reference_pdb.split('_')[0] in f and 'fa' in f)][0] #THIS IS NOT GENERALIZED
1537+
fasta_individual = fasta_individual[0]
15311538
except:
1532-
print(f'Could not find an equivalent fasta file for {MSA_reference_pdb}')
1539+
raise SystemExit(f'Warning: Could not find an equivalent fasta file for {MSA_reference_pdb}, exiting. Check your naming schemes!')
15331540

15341541
#Generate MSA alignment if file does not exist and output MSA indices corresponding to partcicular sequence
15351542
msa_indices_reference = sequence_processing.generate_msa_alignment(alignment_file, combined_fasta, os.path.join(fasta_directory, fasta_individual))

WatCon/sequence_processing.py

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,48 @@
1212
import os
1313

1414
from modeller import *
15+
def msa_with_modeller(alignment_file, combined_fasta):
16+
"""
17+
Perform Multiple Sequence Alignment (MSA) using Modeller.
18+
19+
Note
20+
----
21+
If the proteins are not closely related, it may be better to use a more sophisticated alignment method.
1522
23+
Parameters
24+
----------
25+
alignment_file : str
26+
Name of the file to write the alignment results to.
27+
combined_fasta : str
28+
Path to a FASTA file containing sequences of all proteins.
29+
30+
Returns
31+
-------
32+
None
33+
"""
34+
35+
log.verbose()
36+
37+
#Initialize environment
38+
env = environ()
39+
env.io.atom_files_directory='./'
40+
41+
#Perform alignment, using default modeller parameters
42+
aln = alignment(env, file=combined_fasta, alignment_format='FASTA')
43+
aln.salign(rr_file='$(LIB)/as1.sim.mat', # Substitution matrix used
44+
output='',
45+
max_gap_length=20,
46+
gap_function=False, # If False then align2d not done
47+
feature_weights=(1., 0., 0., 0., 0., 0.),
48+
gap_penalties_1d=(-100, 0),
49+
output_weights_file='saligni1d.mtx',
50+
similarity_flag=True) # Ensuring that the dynamic programming
51+
# matrix is not scaled to a
52+
# difference matrix
53+
54+
#Write final alignment
55+
aln.write(file=alignment_file, alignment_format='PIR')
56+
1657
def perform_structure_alignment(pdb_dir, same_chain='A',out_dir='aligned_pdbs', sort_pdbs=True):
1758
"""
1859
Perform a built-in structural alignment.
@@ -67,7 +108,20 @@ def perform_structure_alignment(pdb_dir, same_chain='A',out_dir='aligned_pdbs',
67108
chain = same_chain[i]
68109
pdb_file = os.path.join(pdb_dir, ref_pdb)
69110

70-
m = Model(env, file=pdb_file, model_segment=('FIRST:'+chain, 'LAST:'+chain))
111+
if isinstance(chain, str):
112+
try:
113+
m = Model(env, file=pdb_file, model_segment=('FIRST:'+chain, 'LAST:'+chain))
114+
except:
115+
#If chain of interest is not found, use chain 'X'
116+
m = Model(env, file=pdb_file, model_segment=('FIRST:'+'X', 'LAST:'+'X'))
117+
else:
118+
#If tuple, assume user wants Chain [0] - Chain [1]x
119+
try:
120+
m = Model(env, file=pdb_file, model_segment=('FIRST:'+chain[0], 'LAST:'+chain[1]))
121+
except:
122+
#If chain of interest is not found, use chain 'X'
123+
m = Model(env, file=pdb_file, model_segment=('FIRST:'+'X', 'LAST:'+'X'))
124+
71125
aln.append_model(m, atom_files=os.path.join(pdb_dir, ref_pdb), align_codes=ref_pdb)
72126

73127
aln.malign()
@@ -151,6 +205,7 @@ def apply_transformation(coordinates, rotation_matrix, translation_vector):
151205
transformed_coords = np.dot(coordinates, rotation_matrix.T) + translation_vector
152206
return transformed_coords
153207

208+
os.makedirs(out_dir, exist_ok=True)
154209
parser = PDBParser()
155210
pdbs = os.listdir(pdb_dir)
156211
pdbs.sort()
@@ -438,7 +493,8 @@ def pick_pair(u, options, num_options=1, dist_cutoff=20):
438493
"""
439494
pairs = []
440495
cur_option = 0
441-
while cur_option < no_options:
496+
dist = lambda x1, y1, z1, x2, y2, z2: np.sqrt((x1-x2)**2 + (y1-y2)**2 + (z1-z2)**2)
497+
while cur_option < num_options:
442498
for option1 in options:
443499
coords1 = u.select_atoms(f"resid {option1} and name CA").positions
444500
for option2 in options[::-1]:

0 commit comments

Comments
 (0)