6 This module is for calculating surface areas
7 from OpenStructure using the external program naccess
9 How To Use This Module:
10 1. Import it (e.g. as "from ost.bindings import naccess")
11 2. Use it (e.g. as "sasa = naccess.CalculateSurfaceArea(entity)")
23 from ost
import settings
31 def _GetExecutable(naccess_exe):
32 return settings.Locate(
'naccess', explicit_file_name=naccess_exe)
40 def _SetupFiles(entity, selection):
42 tmp_dir_name=tempfile.mkdtemp()
45 entity_view=entity.Select(selection)
46 if len(entity_view.atoms) > 50000:
47 raise RuntimeError,
"Too much atoms for NACCESS (> 50 000)"
48 if not entity_view.IsValid():
49 raise RuntimeError,
"Could not create view for selection (%s)"%(selection)
52 tmp_file_name=os.path.join(tmp_dir_name,
"entity.pdb")
53 tmp_file_base = os.path.join(tmp_dir_name,
"entity")
54 io.SavePDB(entity_view, tmp_file_name)
55 return (tmp_dir_name, tmp_file_name, tmp_file_base)
64 def _ParseAsaFile(entity, file, asa_atom):
67 asa_lines = asa_fh.readlines()
71 if l.startswith(
"ATOM"):
77 atom_name = atom_name.strip()
79 res_number = res_number.strip()
82 m=re.match(
r'(?P<num>-?\d+)(?P<ins>\w)?', res_number)
90 a = entity.FindAtom(chain_id, resNum, atom_name)
92 a.SetFloatProp(asa_atom, float(asa))
94 print chain_id, resNum, atom_name
104 def _ParseRsaFile(enti,file, asa_abs, asa_rel):
106 area_lines = area_fh.readlines()
109 area_lines = area_lines[4:]
113 if l.startswith(
"RES"):
114 p = re.compile(
r'\s+')
118 res_name = res_name.strip()
121 res_number= res_number.strip()
123 abs_all, rel_all =l[15:28].strip().split()
124 m=re.match(
r'(?P<num>-?\d+)(?P<ins>\w)?', res_number)
126 if di[
"ins"] ==
None:
129 resNum =
mol.ResNum(int(di[
"num"]), di[
"ins"])
131 res = enti.handle.FindResidue(chain_id, resNum)
134 if res_name == res.name:
135 res.SetFloatProp(asa_rel, float(rel_all) )
136 res.SetFloatProp(asa_abs, float(abs_all) )
138 raise RuntimeError,
"Residue Names are not the same for ResNumb: %s (%s vs %s)" % (res_number, res.name, res_name)
144 def __CleanupFiles(dir_name):
146 shutil.rmtree(dir_name)
155 def _RunNACCESS(command, temp_dir):
156 proc = subprocess.Popen(command, shell=
True, stdout=subprocess.PIPE, cwd = temp_dir)
157 stdout_value, stderr_value = proc.communicate()
160 if proc.returncode!=0:
161 print "WARNING: naccess error\n", stdout_value
162 raise subprocess.CalledProcessError(proc.returncode, command)
189 include_hydrogens=
False, include_hetatm =
False,
190 include_water =
False, selection=
"",
191 naccess_exe=
None, keep_files=
False , asa_abs=
"asaAbs", asa_rel=
"asaRel", asa_atom=
"asaAtom"):
195 naccess_executable=_GetExecutable(naccess_exe)
199 (naccess_data_dir, naccess_data_file,naccess_data_base )=_SetupFiles(entity, selection)
202 command=
"%s %s -p %f " % \
203 (naccess_executable, naccess_data_file, radius)
204 if include_hydrogens:
205 command =
"%s -w" % command
207 command =
"%s -y" % command
209 command =
"%s -h" % command
211 stdout_value=_RunNACCESS(command, naccess_data_dir)
213 new_asa= os.path.join(naccess_data_dir,
"%s.asa" % naccess_data_base)
214 _ParseAsaFile(entity, new_asa, asa_atom)
216 new_rsa = os.path.join(naccess_data_dir,
"%s.rsa" % naccess_data_base)
217 _ParseRsaFile(entity, new_rsa, asa_abs, asa_rel)
221 for a
in entity.atoms:
222 sasa += a.GetFloatProp(asa_atom, 0.0)
231 __CleanupFiles(naccess_data_dir)