annotate ab_haddock_format.py @ 2:a8cda1a4b9ea draft

Uploaded v2
author p.lucas
date Thu, 06 May 2021 09:01:30 +0000
parents 6a4d5446c123
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
1 #!/usr/bin/env python
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
2 # -*- coding: utf-8 -*-
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
3 #
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
4 # Copyright 2020:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
5 # Francesco Ambrosetti
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
6 #
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
7
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
8 """
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
9 Formats the antibody to fit the HADDOCK requirements with the
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
10 specified chain id and returns the list of residues belonging
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
11 to the HV loops defined according to the HADDOCK friendly format.
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
12
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
13 *** The antibody has to be numbered according to the Chothia scheme ***
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
14
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
15 Usage:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
16 python haddock-format.py <chothia numbered antibody> <output .pdb file> <chain_id>
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
17
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
18 Example:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
19 python 4G6K_ch.pdb 4G6K-HADDOCK.pdb A
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
20
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
21 Author: {0}
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
22 Email: {1}
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
23 """
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
24
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
25 import argparse
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
26 import biopandas.pdb as bp
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
27 import copy as cp
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
28 import os
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
29 import sys
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
30
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
31 __author__ = "Francesco Ambrosetti"
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
32 __email__ = "ambrosetti.francesco@gmail.com"
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
33 USAGE = __doc__.format(__author__, __email__)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
34
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
35
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
36 def check_input():
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
37 """
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
38 Check and collect the script inputs
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
39 Returns:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
40 args.pdb (str): path to the pdb-file
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
41 args.chain (str): chain id to use for the HADDOCK-formatted structure
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
42 """
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
43
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
44 # Parse command line arguments
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
45 parser = argparse.ArgumentParser(
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
46 description=USAGE,
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
47 formatter_class=argparse.RawTextHelpFormatter)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
48 parser.add_argument('pdb', help='Path to the Chothia numbered antibody PDB structure', type=str)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
49 parser.add_argument('out', help='Path to the output PDB file', type=str)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
50 parser.add_argument('chain', help='Chain id to use for the HADDOCK-formatted PDB structure', type=str)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
51
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
52 args = parser.parse_args()
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
53
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
54 if not os.path.isfile(args.pdb):
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
55 emsg = 'ERROR!! File {0} not found or not readable\n'.format(args.pdb)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
56 sys.stderr.write(emsg)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
57 sys.exit(1)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
58
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
59 if not args.pdb.endswith(".pdb"):
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
60 emsg = 'ERROR!! File {0} not recognize as a PDB file\n'.format(args.pdb)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
61 sys.stderr.write(emsg)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
62 sys.exit(1)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
63
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
64 return args.pdb, args.out, args.chain
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
65
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
66
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
67 def unique(sequence):
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
68 seen = set()
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
69 return [x for x in sequence if not (x in seen or seen.add(x))]
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
70
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
71
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
72 class AbHaddockFormat:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
73 """Class to renumber a Chothia antibody to make it HADDOCK-ready"""
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
74
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
75 # Loops
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
76 # L chain loops
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
77 l1 = ['26_L', '27_L', '28_L', '29_L', '30_L', '30A_L', '30B_L', '30C_L', '30D_L', '30E_L', '30F_L', '31_L', '32_L']
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
78 l2 = ['50_L', '50A_L', '50B_L', '50C_L', '50D_L', '50E_L', '50F_L', '51_L', '52_L']
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
79 l3 = ['91_L', '92_L', '93_L', '94_L', '95_L', '95A_L', '95B_L', '95C_L', '95D_L', '95E_L', '95F_L', '96_L']
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
80 loops_l = l1 + l2 + l3
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
81
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
82 # H chain loops
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
83 h1 = ['26_H', '27_H', '28_H', '29_H', '30_H', '31_H', '31A_H', '31B_H', '31C_H', '31D_H', '31E_H', '31F_H', '32_H']
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
84 h2 = ['52A_H', '52B_H', '52C_H', '52D_H', '52E_H', '52F_H', '53_H', '54_H', '55_H']
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
85 h3 = ['96_H', '97_H', '98_H', '99_H', '100_H', '100A_H', '100B_H', '100C_H', '100D_H', '100E_H', '100F_H', '100G_H',
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
86 '100H_H', '100I_H', '100J_H', '100K_H', '101_H']
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
87 loops_h = h1 + h2 + h3
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
88
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
89 def __init__(self, pdbfile, chain):
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
90 """
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
91 Constructor for the AbHaddockFormat class
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
92 Args:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
93 pdbfile (str): path to the antibody .pdb file
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
94 chain (str): chain id to use for the HADDOCK-ready structure
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
95 """
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
96 self.file = pdbfile
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
97 self.pdb = bp.PandasPdb().read_pdb(self.file)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
98 self.chain = chain
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
99
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
100 def check_chain(self):
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
101 """
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
102 Check if the antibody contains the light and heavy chain
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
103 Returns:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
104 0
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
105 """
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
106 chain_ids = self.pdb.df['ATOM']['chain_id'].values
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
107
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
108 if 'H' not in chain_ids:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
109 emsg = 'ERROR!! File {0} does not contain the heavy chain\n'.format(self.file)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
110 sys.stderr.write(emsg)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
111 sys.exit(1)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
112
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
113 elif 'L' not in chain_ids:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
114 emsg = 'ERROR!! File {0} does not contain the light chain\n'.format(self.file)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
115 sys.stderr.write(emsg)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
116 sys.exit(1)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
117
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
118 return 0
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
119
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
120 def ab_format(self):
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
121 """
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
122 Renumbers the antibody and extract the HV residues
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
123
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
124 Returns:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
125 hv_list (list): list of the HV residue numbers
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
126 new_pdb (biopandas.pdb.pandas_pdb.PandasPdb): HADDOCK-ready pdb
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
127 """
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
128
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
129 # Check antibody chain ids
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
130 self.check_chain()
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
131
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
132 # Modify resno to include insertions and chain id
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
133 resno = self.pdb.df['ATOM']['residue_number'].values
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
134 ins = self.pdb.df['ATOM']['insertion'].values
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
135 chain = self.pdb.df['ATOM']['chain_id'].values
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
136 ch_resno = ['{0}{1}_{2}'.format(i, j, c) for i, j, c in zip(resno, ins, chain)]
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
137
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
138 # Create new resno
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
139 count = 0
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
140 prev_resid = None
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
141 new_resno = []
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
142
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
143 # Renumber
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
144 for r in ch_resno:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
145 if r != prev_resid:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
146 count += 1
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
147 new_resno.append(count)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
148 prev_resid = r
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
149 elif r == prev_resid:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
150 new_resno.append(count)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
151 prev_resid = r
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
152
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
153 # Update pdb
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
154 new_pdb = cp.deepcopy(self.pdb)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
155 new_pdb.df['ATOM']['chain_id'] = self.chain
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
156 new_pdb.df['ATOM']['residue_number'] = new_resno
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
157 new_pdb.df['ATOM']['insertion'] = '' # Remove insertions
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
158
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
159 # Create dictionary with old and new numbering
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
160 resno_dict = dict(zip(unique(ch_resno), unique(new_resno)))
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
161
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
162 # Collect HV residues with the new numbering
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
163 hv_list = []
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
164
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
165 # Heavy chain
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
166 for hv_heavy in self.loops_h:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
167 if hv_heavy in resno_dict.keys():
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
168 hv_list.append(resno_dict[hv_heavy])
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
169
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
170 # Light chain
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
171 for hv_light in self.loops_l:
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
172 if hv_light in resno_dict.keys():
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
173 hv_list.append(resno_dict[hv_light])
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
174
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
175 hv_list.sort()
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
176 return hv_list, new_pdb
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
177
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
178
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
179 if __name__ == '__main__':
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
180
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
181 # Get inputs
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
182 pdb_file, out_file, chain_id = check_input()
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
183
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
184 # Renumber pdb file and get HV residues
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
185 pdb_format = AbHaddockFormat(pdb_file, chain_id)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
186 hv_resno, pdb_ren = pdb_format.ab_format()
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
187
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
188 # Write pdb into a file
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
189 pdb_ren.to_pdb(path=out_file, records=['ATOM'], append_newline=True)
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
190
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
191 # Print HV residues
6a4d5446c123 Uploaded python script
p.lucas
parents:
diff changeset
192 print(','.join(map(str, hv_resno)))