20 Utility functions to load secondary structure information from DSSP files
21 and assign them to entities.
23 Authors: Pascal Benkert, Marco Biasini
27 import tempfile,subprocess
29 from ost
import io,mol
30 from ost
import settings
33 def _SkipHeader(stream):
34 line=stream.readline()
36 if line.strip().find(
'#')==0:
38 line=stream.readline()
41 def _Cleanup(pdb_path, temp_path, entity_saved):
42 if entity_saved
and os.path.exists(pdb_path):
44 if os.path.exists(temp_path):
47 def _ExecuteDSSP(path, dssp_bin, temp_dir=None):
50 temp_dssp_path=tempfile.mktemp(suffix=
".out",prefix=
"dssp", dir=temp_dir)
51 dssp_abs_path=settings.Locate([
'dsspcmbi',
'dssp',
'mkdssp'], env_name=
'DSSP_EXECUTABLE',
52 explicit_file_name=dssp_bin)
53 if os.path.isdir(dssp_abs_path):
54 raise RuntimeError(
'"%s" is a directory. Specify path to DSSP binary' % dssp_abs_path)
55 if not os.access(dssp_abs_path, os.X_OK):
56 raise RuntimeError(
'"%s" is not executable' % dssp_abs_path)
58 ps=subprocess.Popen([dssp_abs_path, path, temp_dssp_path],
59 stderr=subprocess.PIPE)
60 err_lines=ps.stderr.readlines()
64 def _CalcRelativeSA(residue_type, absolute_sa):
65 solvent_max_list=[118,317,238,243,183,262,286,154,258,228,
66 243,278,260,271,204,234,206,300,303,216]
67 residue_indices =
"ARNDCQEGHILKMFPSTWYV"
71 if residue_type.islower():
73 if residue_indices.find(residue_type)==-1:
74 raise RuntimeError(
'residue %s is a non-standard residue' %(residue_type))
76 rel=float(absolute_sa)/(solvent_max_list[residue_indices.find(residue_type)])
80 def AssignDSSP(ent, pdb_path="", extract_burial_status=False, tmp_dir=None,
83 Assign secondary structure states to peptide residues in the structure. This
84 function uses the DSSP command line program.
86 If you already have a DSSP output file and would like to assign the secondary
87 structure states to an entity, use :func:`LoadDSSP`.
89 :param ent: The entity for which the secondary structure should be calculated
90 :type ent: :class:`~ost.mol.EntityHandle` or :class:`~ost.mol.EntityView`
91 :param extract_burial_status: If true, also extract burial status and store
93 ``relative_solvent_accessibility`` at residue
95 :param tmp_dir: If set, overrides the default tmp directory of the
97 :param dssp_bin: The path to the DSSP executable
98 :raises: :class:`~ost.settings.FileNotFound` if the dssp executable is not
100 :raises: :class:`RuntimeError` when dssp is executed with errors
105 pdb_path=tempfile.mktemp(suffix=
".pdb",prefix=
"temp_entity",
107 io.SavePDB(ent, pdb_path)
112 temp_dssp_path=_ExecuteDSSP(pdb_path, dssp_bin)
113 if not os.path.exists(temp_dssp_path):
114 raise RuntimeError(
'DSSP output file does not exist.')
117 LoadDSSP(temp_dssp_path, ent, extract_burial_status,
121 print "Exception in DSSP:", e
122 _Cleanup(pdb_path, temp_dssp_path, entity_saved)
123 raise RuntimeError(e)
127 _Cleanup(pdb_path, temp_dssp_path, entity_saved)
133 def LoadDSSP(file_name, model, extract_burial_status=False,
134 entity_saved=
False, calculate_relative_sa=
True):
136 Loads DSSP output and assigns secondary structure states to the peptidic
139 If you would like to run dssp *and* assign the secondary structure,
140 use :func:`AssignDSSP` instead.
142 :param file_name: The filename of the DSSP output file
143 :param model: The entity to which the secondary structure states should be
145 :param extract_burial_status: If true also calculates burial status of
146 residues and assigns it to the burial_status string property.
147 :param calculate_relative_sa: If true also relative solvent accessibility and
148 and assigns it to the relative_solvent_accessibility float property of
150 :param entity_save: Whether the entity was saved.
152 if not model.IsValid():
153 raise ValueError(
'model entity is not valid')
154 if model.atom_count==0:
155 raise ValueError(
'model entity does not contain any atoms')
156 stream=open(file_name)
157 if not _SkipHeader(stream):
159 raise RuntimeError(
'Ill-formatted DSSP file')
162 num=line[6:10].strip()
163 ins_code=line[10].strip()
165 solvent_accessibility=float(line[34:39].strip())
174 chain=model.FindChain(chain_name)
176 if not chain.IsValid():
183 residue=chain.FindResidue(
mol.ResNum(int(num)))
185 residue=chain.FindResidue(
mol.ResNum(int(num),ins_code))
188 if extract_burial_status:
190 residue.SetStringProp(
"burial_status",
'X')
193 if residue.name==
"MSE" and amino_acid==
'X':
196 residue.SetFloatProp(
"solvent_accessibility",
197 solvent_accessibility)
198 if calculate_relative_sa:
199 relative_sa=_CalcRelativeSA(amino_acid,solvent_accessibility)
200 residue.SetFloatProp(
"relative_solvent_accessibility",
202 if relative_sa < 0.25:
203 residue.SetStringProp(
"burial_status",
'b')
205 residue.SetStringProp(
"burial_status",
'e')
211 rt=mol.SecStructure.COIL
213 rt=mol.SecStructure.ALPHA_HELIX
215 rt=mol.SecStructure.EXTENDED
217 rt=mol.SecStructure.BETA_BRIDGE
219 rt=mol.SecStructure.BEND
221 rt=mol.SecStructure.TURN
223 rt=mol.SecStructure.PI_HELIX
225 rt=mol.SecStructure.THREE_TEN_HELIX
227 if not residue.IsValid():
232 raise RuntimeError(
'Ill-formatted DSSP file: invalid residue')