00001 """ 00002 Interface to LGA 00003 00004 Author: Marco Biasini 00005 """ 00006 import tempfile 00007 import os 00008 from ost import io 00009 import subprocess 00010 from ost import geom 00011 from ost import settings 00012 00013 def _FindLGABinary(lga_bin): 00014 return settings.Locate('lga', explicit_file_name=lga_bin, 00015 env_name='LGA_BINARY') 00016 00017 def _PrepareInput(pdb1, pdb2, output_pdb): 00018 """ 00019 Deal with the brain-dead input requirements of LGA. 00020 """ 00021 mol1=os.path.basename(os.path.splitext(pdb1)[0]) 00022 mol2=os.path.basename(os.path.splitext(pdb2)[0]) 00023 os.system('echo MOLECULE %s > %s' % (mol1, output_pdb)) 00024 os.system('cat %s >> %s' % (pdb1, output_pdb)) 00025 os.system('echo "\n" >> %s' % (output_pdb)) 00026 os.system('echo MOLECULE %s >> %s' % (mol2, output_pdb)) 00027 os.system('cat %s >> %s' % (pdb2, output_pdb)) 00028 00029 class GDTResult: 00030 def __init__(self, rotation, shift, gdt_ts, gdt_ha): 00031 self.rotation=rotation 00032 self.shift=shift 00033 self.gdt_ts=gdt_ts 00034 self.gdt_ha=gdt_ha 00035 def GetTransform(self): 00036 transform=geom.Mat4() 00037 transform.PasteTranslation(self.shift) 00038 return transform*geom.Mat4(self.rotation) 00039 00040 def _ParseRotationAndShift(lines): 00041 t=[l.split() for l in lines] 00042 rot=geom.Mat3() 00043 shift=geom.Vec3() 00044 for i, x in enumerate(t): 00045 rot[(i, 0)]=+float(x[2]) 00046 rot[(i, 1)]=+float(x[6]) 00047 rot[(i, 2)]=+float(x[10]) 00048 shift[i]=float(x[14]) 00049 return rot, shift 00050 00051 def _ParseGDTSection(section, residue_count): 00052 cutoffs=[float(e) for e in section[0].split()[2:]] 00053 num_ca=[int(e) for e in section[1].split()[2:]] 00054 gdt_ts=[float(e) for e in section[2].split()[2:]] 00055 scores=dict(zip(cutoffs, gdt_ts)) 00056 numbers=dict(zip(cutoffs, num_ca)) 00057 factor=(1.0/(4*residue_count))*100 00058 ts_cutoffs=(1.0, 2.0, 4.0, 8.0) 00059 ha_cutoffs=(0.5, 1.0, 2.0, 4.0) 00060 gdt_ts=(sum([numbers[c] for c in ts_cutoffs]))*factor 00061 gdt_ha=(sum([numbers[c] for c in ha_cutoffs]))*factor 00062 return gdt_ts, gdt_ha 00063 00064 def _ParseLGAOutput(output, residue_count): 00065 result=GDTResult(geom.Mat3(), geom.Vec3(), 0.0, 0.0) 00066 found_gdt_section=False 00067 found_transform_section=False 00068 for index, line in enumerate(output): 00069 if line.startswith('GLOBAL_DISTANCE_TEST'): 00070 next_lines=output[index+1:index+5] 00071 result.gdt_ts, result.gdt_ha=_ParseGDTSection(next_lines, residue_count) 00072 found_gdt_section=True 00073 if line.startswith('Unitary ROTATION matrix'): 00074 next_lines=output[index+1:index+4] 00075 result.rotation, result.shift=_ParseRotationAndShift(next_lines) 00076 found_transform_section=True 00077 break 00078 assert found_transform_section and found_gdt_section 00079 return result 00080 00081 def GDT(pdb1, pdb2, chain1='', chain2='', reference_length=None, lga_bin=None): 00082 """ 00083 Calculate GDT value between pdb1 and pdb2. It is assumed that the 00084 corresponding residues in pdb1 and pdb2 have the same residue numbers. 00085 """ 00086 lga_bin=_FindLGABinary(lga_bin) 00087 temp_d=tempfile.mkdtemp(prefix='lga_gdt_ts_') 00088 for d in ('MOL2', 'TMP', 'RESULTS'): 00089 os.mkdir(os.path.join(temp_d, d)) 00090 00091 if not chain1: 00092 chain1=pdb1.chains[0].name 00093 if not chain2: 00094 chain2=pdb2.chains[0].name 00095 pdb_one_name=os.path.join(temp_d, 'MOL2', 'one.pdb') 00096 pdb_two_name=os.path.join(temp_d, 'MOL2', 'two.pdb') 00097 io.SaveEntity(pdb1, pdb_one_name) 00098 io.SaveEntity(pdb2, pdb_two_name) 00099 _PrepareInput(pdb_one_name, pdb_two_name, 00100 os.path.join(temp_d, 'MOL2', 'input.pdb')) 00101 output_file=os.path.join(temp_d, 'out.txt') 00102 ch1, ch2=('', '') 00103 if len(chain1.strip()): ch1=' -ch1:%s ' % chain1 00104 if len(chain2.strip()): ch2=' -ch2:%s ' % chain2 00105 00106 params=(temp_d, lga_bin, 'input.pdb', ch1, ch2) 00107 command='cd %s; %s %s %s%s-ie -3 -d:4 -sda' 00108 00109 expanded_cmd=command % params 00110 lga_proc=subprocess.Popen(expanded_cmd, shell=True, 00111 stdout=subprocess.PIPE) 00112 length=reference_length or max(pdb1.residue_count, pdb2.residue_count) 00113 result=_ParseLGAOutput(lga_proc.stdout.readlines(), reference_length) 00114 os.system('rm -r %s' % temp_d) 00115 return result