OpenStructure
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
cadscore.py
Go to the documentation of this file.
1 #------------------------------------------------------------------------------
2 # This file is part of the OpenStructure project <www.openstructure.org>
3 #
4 # Copyright (C) 2008-2009 by the OpenStructure authors
5 #
6 # This library is free software; you can redistribute it and/or modify it under
7 # the terms of the GNU Lesser General Public License as published by the Free
8 # Software Foundation; either version 3.0 of the License, or (at your option)
9 # any later version.
10 # This library is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 # details.
14 #
15 # You should have received a copy of the GNU Lesser General Public License
16 # along with this library; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 #------------------------------------------------------------------------------
19 """
20 Wrapper for the CAD score.
21 
22 References:
23 
24 Olechnovic K, Kulberkyte E, Venclovas C., CAD-score: A new contact area
25 difference-based function for evaluation of protein structural models
26 Proteins. 2012 Aug 30. [Epub ahead of print]
27 
28 Authors: Valerio Mariani, Alessandro Barbato
29 """
30 
31 import subprocess, os, tempfile, platform
32 from ost import settings, io
33 
34 def _SetupFiles(model,reference):
35  # create temporary directory
36  tmp_dir_name=tempfile.mkdtemp()
37  dia = 'PDB'
38  for chain in model.chains:
39  if chain.name==" ":
40  raise RuntimeError("One of the chains in the model has no name. Cannot calculate CAD score")
41  if len(chain.name) > 1:
42  dia = 'CHARMM'
43  break;
44  for res in chain.residues:
45  if len(res.name) > 3:
46  dia = 'CHARMM'
47  break;
48  io.SavePDB(model, os.path.join(tmp_dir_name, 'model.pdb'), dialect=dia)
49  dia = 'PDB'
50  for chain in reference.chains:
51  if chain.name==" ":
52  raise RuntimeError("One of the chains in the reference has no name. Cannot calculate CAD score")
53  if len(chain.name) > 1:
54  dia = 'CHARMM'
55  break;
56  for res in chain.residues:
57  if len(res.name) > 3:
58  dia = 'CHARMM'
59  break;
60  io.SavePDB(reference, os.path.join(tmp_dir_name, 'reference.pdb'),dialect=dia)
61  return tmp_dir_name
62 
63 def _CleanupFiles(dir_name):
64  import shutil
65  shutil.rmtree(dir_name)
66 
67 
68 class CADResult:
69  """
70  Holds the result of running CAD
71 
72  .. attribute:: globalAA
73 
74  The global CAD's atom-atom (AA) score
75 
76  .. attribute:: localAA
77 
78  Dictionary containing local CAD's atom-atom (AA) scores.
79 
80  :type: dictionary (key: chain.resnum (e.g.: A.24), value: CAD local AA score (see CAD Documentation online)
81  """
82  def __init__(self, globalAA, localAA):
83  self.globalAA=globalAA
84  self.localAA=localAA
85 
86 def _ParseCADGlobal(lines):
87  interesting_lines=lines[1]
88  aa=float(interesting_lines.split()[10])
89  return aa
90 
91 def _ParseCADLocal(lines):
92  local_aa_dict={}
93  for lin in lines[11:]:
94  items=lin.split()
95  chain=items[0]
96  resnum=int(items[1])
97  key=chain+'.'+str(resnum)
98  aa=float(items[2])
99  local_aa_dict[key]=aa
100  return local_aa_dict
101 
102 def _RunCAD(max_iter, tmp_dir):
103  model_filename=os.path.join(tmp_dir, 'model.pdb')
104  reference_filename=os.path.join(tmp_dir, 'reference.pdb')
105  if platform.system() == "Windows":
106  raise RuntimeError('CAD score not available on Windows')
107  else:
108  cad_calc_path=settings.Locate('CADscore_calc.bash')
109  cad_read_g_path=settings.Locate('CADscore_read_global_scores.bash')
110  cad_read_l_path=settings.Locate('CADscore_read_local_scores.bash')
111  command1="\"%s\" -o %i -m \"%s\" -t \"%s\" -D \"%s\"" %(cad_calc_path, max_iter, model_filename, reference_filename, os.path.join(tmp_dir,"cadtemp"))
112  command2="\"%s\" -D \"%s\"" %(cad_read_g_path, os.path.join(tmp_dir,"cadtemp"))
113  command3="\"%s\" -m \"%s\" -t \"%s\" -D \"%s\" -c AA" %(cad_read_l_path, model_filename, reference_filename,os.path.join(tmp_dir,"cadtemp"))
114  ps1=subprocess.Popen(command1, shell=True, stdout=subprocess.PIPE)
115  ps1.wait()
116  ps2=subprocess.Popen(command2, shell=True, stdout=subprocess.PIPE)
117  ps2.wait()
118  lines=ps2.stdout.readlines()
119  try:
120  globalAA=_ParseCADGlobal(lines)
121  except:
122  raise RuntimeError("CAD calculation failed")
123  ps3=subprocess.Popen(command3, shell=True, stdout=subprocess.PIPE)
124  ps3.wait()
125  lines=ps3.stdout.readlines()
126  try:
127  localAA=_ParseCADLocal(lines)
128  except:
129  raise RuntimeError("CAD calculation failed")
130 
131  return CADResult(globalAA,localAA)
132 
133 
134 def CADScore(model, reference, max_iter=300):
135  """
136  Calculates global and local atom-atom (AA) CAD Scores
137 
138 
139  :param model: The model structure.
140  :type model: :class:`~ost.mol.EntityView` or :class:`~ost.mol.EntityHandle`
141  :param reference: The reference structure
142  :type model2: :class:`~ost.mol.EntityView` or :class:`~ost.mol.EntityHandle`
143  :param max_iter: Optional. The maximum number of iteration for the tessellation algorithm before giving up. By default 300
144  :returns: The result of the CAD score calculation
145  :rtype: :class:`CADResult`
146 
147  :raises: :class:`~ost.settings.FileNotFound` if any of the CAD score exacutables could not be located.
148  :raises: :class:`RuntimeError` if the calculation failed
149  """
150  tmp_dir_name=_SetupFiles(model, reference)
151  result=_RunCAD(max_iter, tmp_dir_name)
152  _CleanupFiles(tmp_dir_name)
153  return result
154