diff --git a/modules/bindings/pymod/CMakeLists.txt b/modules/bindings/pymod/CMakeLists.txt index e2207bcda2d35a6a0216e177d7ad878da65ffb73..ba312b609546b16b403236eb47396d33eac71b5f 100644 --- a/modules/bindings/pymod/CMakeLists.txt +++ b/modules/bindings/pymod/CMakeLists.txt @@ -13,5 +13,6 @@ blast.py cadscore.py kclust.py ialign.py +align_3dcomb.py ) pymod(NAME bindings PY ${OST_BINDINGS}) diff --git a/modules/bindings/pymod/__init__.py b/modules/bindings/pymod/__init__.py index 671ae530fb59273ce2c3105ddc95bdd9567ccecd..ab3668069f13b1b3e66dbae71c895dbb4a7128fc 100644 --- a/modules/bindings/pymod/__init__.py +++ b/modules/bindings/pymod/__init__.py @@ -7,3 +7,4 @@ from ost.bindings import naccess from ost.bindings import hbplus from ost.bindings import clustalw from ost.bindings import cadscore +from ost.bindings import align_3dcomb diff --git a/modules/bindings/pymod/align_3dcomb.py b/modules/bindings/pymod/align_3dcomb.py new file mode 100644 index 0000000000000000000000000000000000000000..ca709fc15fcadfe8dbb0765466cf874e3b35c231 --- /dev/null +++ b/modules/bindings/pymod/align_3dcomb.py @@ -0,0 +1,129 @@ +""" +3DCOMB module + +Author: Niklaus Johner + +This module is for structural alignment from OpenStructure using the external program 3DCOMB. + +How To Use This Module: + 1. Import it (e.g. as "from ost.bindings import align_3dcomb") + 2. Use it (e.g. as "alignment,transformation_list = align_3dcomb.AlignStructures(view_list)") + +Requirement: + - 3DCOMB installed +""" + +from ost.bindings import utils +import subprocess,os +from ost import settings +from ost import io +import ost +import ost.geom + +def _GetExecutable(comb_exe, comb_env): + """ + Function to check if 3DCOMB executable is present + + :param comb_exe: Explicit path to 3DCOMB executable + :param msms_env: Environment variable pointing to 3DCOMB executable + :returns: Path to the executable + :raises: :class:`~ost.FileNotFound` if executable is not found + """ + return settings.Locate(['3DCOMB_linux','3DCOMB_win.exe'], explicit_file_name=comb_exe, + env_name=comb_env) + +def _SetupFiles(structure_list): + """ + Setup files for MSMS calculation in temporary directory + + :param structure_list: A list of EntityView that will be aligned.\ + each EntityView should contain a single chain and each residue needs to have a CA atom. + :returns: calss:settings.TempDir + :raises: class:`RuntimeError` if on of the Views is not valid + """ + + #write out temporary pdb files + if not all([ev.IsValid() for ev in structure_list]): + raise RuntimeError, "Invalid EntityView in structure_list" + tpd=utils.TempDirWithFiles(structure_list) + + #Write out the file containing the list of all structures + outfile=open(os.path.join(tpd.dirname,'list'),'w') + outfile.write('\n'.join(tpd.files)) + outfile.close() + return tpd + + +def _Run3DCOMB(command,tpd): + """ + Run the 3DCOMB alignment command + + This functions starts the external 3DCOMB executable and returns the stdout of + 3DCOMB. + + :param command: Command to execute + :returns: stdout of 3DCOMB + :raises: :class:`CalledProcessError` for non-zero return value + """ + outname=os.path.join(tpd.dirname,'align.out') + outfile=open(outname,'w') + returncode=subprocess.call(command, shell=True, stdout=outfile) + outfile.close() + #check for successful completion of 3DCOMB + if returncode!=0: + print "WARNING: 3DCOMB error\n" + raise subprocess.CalledProcessError + return returncode + +def _ParseOutput(tpd): + #Read Alignment + ali=io.LoadAlignment(os.path.join(tpd.dirname,'list.ali'),'fasta') + for i in range(ali.GetCount()): + ali.SetSequenceName(i,'struc{0}'.format(i)) + #Read Transformations + f=open(os.path.join(tpd.dirname,'list.rmt'),'r') + Tl=[] + for l in f: + if l.startswith('>'): + fl=ost.FloatList() + for i in range(3): + l=f.next() + sl=l.split(',') + fl.extend([float(el) for el in sl[0].split()+[sl[1]]]) + fl.extend([0,0,0,1]) + T=ost.geom.Transform() + M=ost.geom.Mat4(*fl) + T.SetMatrix(M) + Tl.append(T) + #Read standard output + outfile=open(os.path.join(tpd.dirname,'align.out'),'r') + results={} + for line in outfile: + if line.startswith('Objective function value is'):results['objective_function']=float(line.split()[-1]) + if line.startswith('CORE_LEN'): + l=line.split(',') + for el in l: + s=el.split('=') + results[s[0]]=float(s[1]) + return ali,Tl,results + + +def AlignStructures(structure_list,apply_transform=False,name_list=None,comb_exe=None,comb_env=None): + comb_executable=_GetExecutable(comb_exe, comb_env) + tpd=_SetupFiles(structure_list) + command=' '.join([comb_executable,os.path.join(tpd.dirname,'list')]) + returncode=_Run3DCOMB(command,tpd) + try:ali,Tl,results=_ParseOutput(tpd) + except: + print 'could not parse output' + raise RuntimeError + if apply_transform: + for T,ev in zip(Tl,structure_list): + ev.handle.FixTransform() + ev.handle.SetTransform(T) + tpd.Cleanup() + return ali,Tl,results + + + +