20 Wrappers for the tmalign and tmscore utilities.
24 tmscore: Yang Zhang and Jeffrey Skolnick, Proteins 2004 57: 702-710
25 tmalign: Y. Zhang and J. Skolnick, Nucl. Acids Res. 2005 33, 2302-9
28 Authors: Pascal Benkert, Marco Biasini
31 import subprocess, os, tempfile, platform
33 from ost
import settings, io, geom, seq
35 def _SetupFiles(models):
37 tmp_dir_name=tempfile.mkdtemp()
39 for index, model
in enumerate(models):
40 for chain
in model.chains:
41 if len(chain.name) > 1:
44 for res
in chain.residues:
48 io.SavePDB(model, os.path.join(tmp_dir_name,
'model%02d.pdb' % (index+1)), dialect=dia)
51 def _CleanupFiles(dir_name):
53 shutil.rmtree(dir_name)
55 def _ParseTmAlign(lines,lines_matrix):
56 info_line=lines[12].split(
',')
57 aln_length=int(info_line[0].split(
'=')[1].strip())
58 rmsd=float(info_line[1].split(
'=')[1].strip())
59 tm_score=float(lines[14].split(
'=')[1].split(
'(')[0].strip())
60 tf1=[float(i.strip())
for i
in lines_matrix[2].split()]
61 tf2=[float(i.strip())
for i
in lines_matrix[3].split()]
62 tf3=[float(i.strip())
for i
in lines_matrix[4].split()]
63 rot=
geom.Mat3(tf1[2], tf1[3], tf1[4], tf2[2], tf2[3],
64 tf2[4], tf3[2], tf3[3], tf3[4])
66 tf.PasteTranslation(
geom.Vec3(tf1[1], tf2[1], tf3[1]))
67 seq1 = seq.CreateSequence(
"1",lines[18].strip())
68 seq2 = seq.CreateSequence(
"2",lines[20].strip())
69 alignment = seq.CreateAlignment()
70 alignment.AddSequence(seq2)
71 alignment.AddSequence(seq1)
74 def _RunTmAlign(tmalign, tmp_dir):
75 model1_filename=os.path.join(tmp_dir,
'model01.pdb')
76 model2_filename=os.path.join(tmp_dir,
'model02.pdb')
77 if platform.system() ==
"Windows":
78 tmalign_path=settings.Locate(
'tmalign.exe', explicit_file_name=tmalign)
79 command=
"\"%s\" %s %s -m %s" %(os.path.normpath(tmalign_path), model1_filename, model2_filename, os.path.join(tmp_dir,
'matrix.txt'))
81 tmalign_path=settings.Locate(
'tmalign', explicit_file_name=tmalign)
82 command=
"\"%s\" \"%s\" \"%s\" -m \"%s\"" %(tmalign_path, model1_filename, model2_filename, os.path.join(tmp_dir,
'matrix.txt'))
83 ps=subprocess.Popen(command, shell=
True, stdout=subprocess.PIPE)
85 lines=ps.stdout.readlines()
87 _CleanupFiles(tmp_dir)
88 raise RuntimeError(
"tmalign superposition failed")
89 matrix_file=open(os.path.join(tmp_dir,
'matrix.txt'))
90 lines_matrix=matrix_file.readlines()
92 return _ParseTmAlign(lines,lines_matrix)
95 def __init__(self, rmsd, aligned_length, tm_score, transform, alignment):
102 def _ParseMmAlign(lines):
103 info_line=lines[10].split(
',')
104 aln_length=float(info_line[0].split(
'=')[1].strip())
105 rmsd=float(info_line[1].split(
'=')[1].strip())
106 tm_score=float(info_line[2].split(
'=')[1].strip())
107 tf1=[float(i.strip())
for i
in lines[14].split()]
108 tf2=[float(i.strip())
for i
in lines[15].split()]
109 tf3=[float(i.strip())
for i
in lines[16].split()]
110 rot=
geom.Mat3(tf1[2], tf1[3], tf1[4], tf2[2], tf2[3],
111 tf2[4], tf3[2], tf3[3], tf3[4])
113 tf.PasteTranslation(
geom.Vec3(tf1[1], tf2[1], tf3[1]))
114 seq1 = seq.CreateSequence(
"1",lines[19].strip())
115 seq2 = seq.CreateSequence(
"2",lines[21].strip())
116 alignment = seq.CreateAlignment()
117 alignment.AddSequence(seq2)
118 alignment.AddSequence(seq1)
120 return MMAlignResult(rmsd, tm_score, aln_length, tf, seq2, alignment)
122 def _RunMmAlign(mmalign, tmp_dir):
123 model1_filename=os.path.join(tmp_dir,
'model01.pdb')
124 model2_filename=os.path.join(tmp_dir,
'model02.pdb')
125 if platform.system() ==
"Windows":
126 mmalign_path=settings.Locate(
'mmalign.exe', explicit_file_name=mmalign)
127 command=
"\"%s\" %s %s" %(os.path.normpath(mmalign_path), model1_filename, model2_filename)
129 mmalign_path=settings.Locate(
'MMalign', explicit_file_name=mmalign)
130 command=
"\"%s\" \"%s\" \"%s\"" %(mmalign_path, model1_filename, model2_filename)
131 ps=subprocess.Popen(command, shell=
True, stdout=subprocess.PIPE)
133 lines=ps.stdout.readlines()
135 _CleanupFiles(tmp_dir)
136 raise RuntimeError(
"mmalign superposition failed")
137 return _ParseMmAlign(lines)
141 Holds the result of running TMscore
143 .. attribute:: rmsd_common
145 The RMSD of the common Calpha atoms of both structures
147 .. attribute:: rmsd_below_five
149 The RMSD of all Calpha atoms that can be superposed below five Angstroem
151 .. attribute:: tm_score
153 The TM-score of the structural superposition
155 .. attribute:: transform
157 The transform that superposes the model onto the reference structure.
159 :type: :class:`~ost.geom.Mat4`
161 .. attribute:: gdt_ha
163 The GDT_HA of the model to the reference structure.
165 .. attribute:: gdt_ts
167 The GDT_TS of the model to the reference structure.
170 def __init__(self, rmsd_common, tm_score, max_sub,
171 gdt_ts, gdt_ha, rmsd_below_five, transform):
180 def _ParseTmScore(lines):
181 tf1=[float(i.strip())
for i
in lines[23].split()]
182 tf2=[float(i.strip())
for i
in lines[24].split()]
183 tf3=[float(i.strip())
for i
in lines[25].split()]
184 rot=
geom.Mat3(tf1[2], tf1[3], tf1[4], tf2[2], tf2[3],
185 tf2[4], tf3[2], tf3[3], tf3[4])
187 tf.PasteTranslation(
geom.Vec3(tf1[1], tf2[1], tf3[1]))
189 float(lines[16].split()[2].strip()),
190 float(lines[17].split()[1].strip()),
191 float(lines[18].split()[1].strip()),
192 float(lines[19].split()[1].strip()),
193 float(lines[27].split()[-1].strip()),
197 def _RunTmScore(tmscore, tmp_dir):
198 model1_filename=os.path.join(tmp_dir,
'model01.pdb')
199 model2_filename=os.path.join(tmp_dir,
'model02.pdb')
200 if platform.system() ==
"Windows":
201 tmscore_path=settings.Locate(
'tmscore.exe', explicit_file_name=tmscore)
202 command=
"\"%s\" %s %s" %(os.path.normpath(tmscore_path), model1_filename,
205 tmscore_path=settings.Locate(
'tmscore', explicit_file_name=tmscore)
206 command=
"\"%s\" \"%s\" \"%s\"" % (tmscore_path, model1_filename,
208 ps=subprocess.Popen(command, shell=
True, stdout=subprocess.PIPE)
210 lines=ps.stdout.readlines()
212 _CleanupFiles(tmp_dir)
213 raise RuntimeError(
"tmscore superposition failed")
214 return _ParseTmScore(lines)
219 Performs a sequence independent superposition of model1 onto model2, the
223 :param model1: The model structure. If the superposition is successful, will
224 be superposed onto the reference structure
225 :type model1: :class:`~ost.mol.EntityView` or :class:`~ost.mol.EntityHandle`
226 :param model2: The reference structure
227 :type model2: :class:`~ost.mol.EntityView` or :class:`~ost.mol.EntityHandle`
228 :param tmalign: If not None, the path to the tmalign executable.
229 :returns: The result of the tmscore superposition
230 :rtype: :class:`ost.bindings.TMAlignResult`
232 :raises: :class:`~ost.settings.FileNotFound` if tmalign could not be located.
233 :raises: :class:`RuntimeError` if the superposition failed
235 tmp_dir_name=_SetupFiles((model1, model2))
236 result=_RunTmAlign(tmalign, tmp_dir_name)
237 model1.handle.EditXCS().ApplyTransform(result.transform)
238 _CleanupFiles(tmp_dir_name)
243 Run tmalign on two protein structures
245 tmp_dir_name=_SetupFiles((model1, model2))
246 result=_RunMmAlign(mmalign, tmp_dir_name)
247 model1.handle.EditXCS().ApplyTransform(result.transform)
248 _CleanupFiles(tmp_dir_name)
253 Performs a sequence dependent superposition of model1 onto model2,
256 :param model1: The model structure. If the superposition is successful, will
257 be superposed onto the reference structure
258 :type model1: :class:`~ost.mol.EntityView` or :class:`~ost.mol.EntityHandle`
259 :param model2: The reference structure
260 :type model2: :class:`~ost.mol.EntityView` or :class:`~ost.mol.EntityHandle`
261 :param tmscore: If not None, the path to the tmscore executable.
262 :returns: The result of the tmscore superposition
263 :rtype: :class:`TMScoreResult`
265 :raises: :class:`~ost.settings.FileNotFound` if tmalign could not be located.
266 :raises: :class:`RuntimeError` if the superposition failed
268 tmp_dir_name=_SetupFiles((model1, model2))
269 result=_RunTmScore(tmscore, tmp_dir_name)
270 model1.handle.EditXCS().ApplyTransform(result.transform)
271 _CleanupFiles(tmp_dir_name)
Three dimensional vector class, using Real precision.