00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 """
00020 Utility functions to load secondary structure information from DSSP files
00021 and assign them to entities.
00022
00023 Authors: Pascal Benkert, Marco Biasini
00024 """
00025
00026 import os
00027 import tempfile,subprocess
00028
00029 from ost import io,mol
00030 from ost import settings
00031
00032
00033 def _SkipHeader(stream):
00034 line=stream.readline()
00035 while line:
00036 if line.strip().find('#')==0:
00037 return True
00038 line=stream.readline()
00039 return False
00040
00041 def _Cleanup(pdb_path, temp_path, entity_saved):
00042 if entity_saved and os.path.exists(pdb_path):
00043 os.remove(pdb_path)
00044 if os.path.exists(temp_path):
00045 os.remove(temp_path)
00046
00047 def _ExecuteDSSP(path, dssp_bin, temp_dir=None):
00048
00049
00050 temp_dssp_path=tempfile.mktemp(suffix=".out",prefix="dssp", dir=temp_dir)
00051 dssp_abs_path=settings.Locate(['dsspcmbi','dssp','mkdssp'], env_name='DSSP_EXECUTABLE',
00052 explicit_file_name=dssp_bin)
00053 if os.path.isdir(dssp_abs_path):
00054 raise RuntimeError('"%s" is a directory. Specify path to DSSP binary' % dssp_abs_path)
00055 if not os.access(dssp_abs_path, os.X_OK):
00056 raise RuntimeError('"%s" is not executable' % dssp_abs_path)
00057
00058 ps=subprocess.Popen([dssp_abs_path, path, temp_dssp_path],
00059 stderr=subprocess.PIPE)
00060 err_lines=ps.stderr.readlines()
00061 return temp_dssp_path
00062
00063
00064 def _CalcRelativeSA(residue_type, absolute_sa):
00065 solvent_max_list=[118,317,238,243,183,262,286,154,258,228,
00066 243,278,260,271,204,234,206,300,303,216]
00067 residue_indices = "ARNDCQEGHILKMFPSTWYV"
00068
00069
00070
00071 if residue_type.islower():
00072 residue_type='C'
00073 if residue_indices.find(residue_type)==-1:
00074 raise RuntimeError('residue %s is a non-standard residue' %(residue_type))
00075 else:
00076 rel=float(absolute_sa)/(solvent_max_list[residue_indices.find(residue_type)])
00077 return rel
00078
00079
00080 def AssignDSSP(ent, pdb_path="", extract_burial_status=False, tmp_dir=None,
00081 dssp_bin=None):
00082 """
00083 Assign secondary structure states to peptide residues in the structure. This
00084 function uses the DSSP command line program.
00085
00086 If you already have a DSSP output file and would like to assign the secondary
00087 structure states to an entity, use :func:`LoadDSSP`.
00088
00089 :param ent: The entity for which the secondary structure should be calculated
00090 :type ent: :class:`~ost.mol.EntityHandle` or :class:`~ost.mol.EntityView`
00091 :param extract_burial_status: If true, also extract burial status and store
00092 as float-property
00093 ``relative_solvent_accessibility`` at residue
00094 level
00095 :param tmp_dir: If set, overrides the default tmp directory of the
00096 operating system
00097 :param dssp_bin: The path to the DSSP executable
00098 :raises: :class:`~ost.settings.FileNotFound` if the dssp executable is not
00099 in the path.
00100 :raises: :class:`RuntimeError` when dssp is executed with errors
00101 """
00102 entity_saved = False
00103
00104
00105 pdb_path=tempfile.mktemp(suffix=".pdb",prefix="temp_entity",
00106 dir=tmp_dir)
00107 io.SavePDB(ent, pdb_path)
00108 entity_saved = True
00109
00110
00111
00112 temp_dssp_path=_ExecuteDSSP(pdb_path, dssp_bin)
00113 if not os.path.exists(temp_dssp_path):
00114 raise RuntimeError('DSSP output file does not exist.')
00115
00116 try:
00117 LoadDSSP(temp_dssp_path, ent, extract_burial_status,
00118 entity_saved)
00119 except Exception, e:
00120
00121 print "Exception in DSSP:", e
00122 _Cleanup(pdb_path, temp_dssp_path, entity_saved)
00123 raise RuntimeError(e)
00124
00125
00126
00127 _Cleanup(pdb_path, temp_dssp_path, entity_saved)
00128
00129 return ent
00130
00131
00132
00133 def LoadDSSP(file_name, model, extract_burial_status=False,
00134 entity_saved=False, calculate_relative_sa=True):
00135 """
00136 Loads DSSP output and assigns secondary structure states to the peptidic
00137 residues.
00138
00139 If you would like to run dssp *and* assign the secondary structure,
00140 use :func:`AssignDSSP` instead.
00141
00142 :param file_name: The filename of the DSSP output file
00143 :param model: The entity to which the secondary structure states should be
00144 assigned
00145 :param extract_burial_status: If true also calculates burial status of
00146 residues and assigns it to the burial_status string property.
00147 :param calculate_relative_sa: If true also relative solvent accessibility and
00148 and assigns it to the relative_solvent_accessibility float property of
00149 the residue.
00150 :param entity_save: Whether the entity was saved.
00151 """
00152 if not model.IsValid():
00153 raise ValueError('model entity is not valid')
00154 if model.atom_count==0:
00155 raise ValueError('model entity does not contain any atoms')
00156 stream=open(file_name)
00157 if not _SkipHeader(stream):
00158 stream.close()
00159 raise RuntimeError('Ill-formatted DSSP file')
00160
00161 for line in stream:
00162 num=line[6:10].strip()
00163 ins_code=line[10].strip()
00164 chain_name=line[11]
00165 solvent_accessibility=float(line[34:39].strip())
00166
00167 amino_acid=line[13]
00168
00169
00170
00171 if isinstance(model,mol.ChainView):
00172 chain=model
00173 else:
00174 chain=model.FindChain(chain_name)
00175
00176 if not chain.IsValid():
00177 continue
00178 if num=='':
00179 continue
00180 residue=None
00181 try:
00182 if ins_code == "":
00183 residue=chain.FindResidue(mol.ResNum(int(num)))
00184 else:
00185 residue=chain.FindResidue(mol.ResNum(int(num),ins_code))
00186
00187
00188 if extract_burial_status:
00189
00190 residue.SetStringProp("burial_status", 'X')
00191
00192
00193 if residue.name=="MSE" and amino_acid=='X':
00194 amino_acid='M'
00195
00196 residue.SetFloatProp("solvent_accessibility",
00197 solvent_accessibility)
00198 if calculate_relative_sa:
00199 relative_sa=_CalcRelativeSA(amino_acid,solvent_accessibility)
00200 residue.SetFloatProp("relative_solvent_accessibility",
00201 relative_sa)
00202 if relative_sa < 0.25:
00203 residue.SetStringProp("burial_status", 'b')
00204 else:
00205 residue.SetStringProp("burial_status", 'e')
00206 except Exception, e:
00207 print "ERROR:",e
00208 continue
00209
00210 rtype=line[16:17]
00211 rt=mol.SecStructure.COIL
00212 if rtype=='H':
00213 rt=mol.SecStructure.ALPHA_HELIX
00214 elif rtype=='E':
00215 rt=mol.SecStructure.EXTENDED
00216 elif rtype=='B':
00217 rt=mol.SecStructure.BETA_BRIDGE
00218 elif rtype=='S':
00219 rt=mol.SecStructure.BEND
00220 elif rtype=='T':
00221 rt=mol.SecStructure.TURN
00222 elif rtype=='I':
00223 rt=mol.SecStructure.PI_HELIX
00224 elif rtype=='G':
00225 rt=mol.SecStructure.THREE_TEN_HELIX
00226
00227 if not residue.IsValid():
00228
00229
00230
00231 stream.close()
00232 raise RuntimeError('Ill-formatted DSSP file: invalid residue')
00233 residue.SetSecStructure(mol.SecStructure(rt))
00234 stream.close()