From 8297d991fae8d67e4e37f0397ade6645dde4cfc4 Mon Sep 17 00:00:00 2001 From: marco <marco@5a81b35b-ba03-0410-adc8-b2c5c5119f08> Date: Tue, 6 Apr 2010 14:25:45 +0000 Subject: [PATCH] move DSSP bindings from internal to main repo git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@1930 5a81b35b-ba03-0410-adc8-b2c5c5119f08 --- modules/bindings/pymod/CMakeLists.txt | 2 +- modules/bindings/pymod/dssp.py | 182 ++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 modules/bindings/pymod/dssp.py diff --git a/modules/bindings/pymod/CMakeLists.txt b/modules/bindings/pymod/CMakeLists.txt index 5dd7a1cc9..c17cb439f 100644 --- a/modules/bindings/pymod/CMakeLists.txt +++ b/modules/bindings/pymod/CMakeLists.txt @@ -1 +1 @@ -pymod(NAME bindings PY __init__.py lga.py hbplus.py msms.py tmtools.py) +pymod(NAME bindings PY __init__.py lga.py hbplus.py msms.py tmtools.py dssp.py) diff --git a/modules/bindings/pymod/dssp.py b/modules/bindings/pymod/dssp.py new file mode 100644 index 000000000..6594d639b --- /dev/null +++ b/modules/bindings/pymod/dssp.py @@ -0,0 +1,182 @@ +#------------------------------------------------------------------------------ +# This file is part of the OpenStructure project <www.openstructure.org> +# +# Copyright (C) 2008-2009 by the OpenStructure authors +# +# This library is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3.0 of the License, or (at your option) +# any later version. +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#------------------------------------------------------------------------------ +""" +Utility functions to load secondary structure information from DSSP files +and assign them to entities. + +Authors: Pascal Benkert, Marco Biasini +""" + +import os +import tempfile + +from ost import io,mol +from ost import settings + + +def _SkipHeader(stream): + line=stream.readline() + while line: + if line.strip().find('#')==0: + return True + line=stream.readline() + return False + + +def _ExecuteDSSP(path, temp_dir=None): + # use of mktemp is a safty problem (use mkstemp and provide file handle to + # subsequent process + temp_dssp_path=tempfile.mktemp(suffix=".out",prefix="dssp", dir=temp_dir) + dssp_abs_path=settings.Locate('dssp', env_name='DSSP_EXECUTABLE') + status = os.system(dssp_abs_path+" "+path+" 2>/dev/null 1> "+temp_dssp_path) + return temp_dssp_path + + +def _CalcRelativeSA(residue_type, absolute_sa): + solvent_max_list=[118,317,238,243,183,262,286,154,258,228, + 243,278,260,271,204,234,206,300,303,216] #TODO: source? + residue_indices = "ARNDCQEGHILKMFPSTWYV" + if residue_type.islower()==True: + residue_type='C' + if residue_indices.find(residue_type)==-1: + raise RuntimeError('residue %s is a non-standard residue' %(residue_type)) + else: + rel=float(absolute_sa)/(solvent_max_list[residue_indices.find(residue_type)]) + return rel + + +def AssignDSSP(ent, pdb_path="", extract_burial_status_flag=0, tmp_dir=None): + entity_saved_flag = 0 + if pdb_path=="": + # use of mktemp is a safty problem (use mkstemp and provide file handle to + # subsequent process + pdb_path=tempfile.mktemp(suffix=".pdb",prefix="temp_entity", + dir=tmp_dir) + io.SaveEntity(ent, pdb_path) + entity_saved_flag = 1 + + #TODO: exception handling (currently errors occuring here + # are handled in the parser LoadDSSP) + temp_dssp_path=_ExecuteDSSP(pdb_path) + + # assign DSSP to entity + try: + LoadDSSP(temp_dssp_path, ent, extract_burial_status_flag, + entity_saved_flag) + except Exception, e: + # clean up + print "Exception in DSSP:", e + if entity_saved_flag == 1: + os.remove(pdb_path) + os.remove(temp_dssp_path) + raise RuntimeError(e) + + # clean up + #print pdb_path, temp_dssp_path + if entity_saved_flag == 1: + os.remove(pdb_path) + os.remove(temp_dssp_path) + + return ent + + + +def LoadDSSP(file_name, model, extract_burial_status_flag=0, + entity_saved_flag=0, calculate_relative_sa=True): + if model.IsValid() == 0: + print "DSSP: model is not valid" + stream=open(file_name) + if not _SkipHeader(stream): + stream.close() + raise RuntimeError('Ill-formatted DSSP file') + + for line in stream: + num=line[6:10].strip() + ins_code=line[10].strip() + chain_name=line[11] + solvent_accessibility=float(line[34:39].strip()) + #solvent_accessibility=line[34:39].strip() + amino_acid=line[13] + #print line + + + if isinstance(model,mol.ChainView): + chain=model + else: + chain=model.FindChain(chain_name) + + if not chain.IsValid(): + continue + if num=='': + continue + residue=None + try: + if ins_code == "": + residue=chain.FindResidue(mol.ResNum(int(num))) + else: + residue=chain.FindResidue(mol.ResNum(int(num),ins_code)) + + # set property "burial status: + if extract_burial_status_flag == 1: + #set default (dummy) burial status for incomplete residues: + residue.SetGenericStringProperty("burial_status", 'X') + + #handle seleno-methionine appearing as amino acid 'X' in DSSP: + if residue.name=="MSE" and amino_acid=='X': + amino_acid='M' + + residue.SetGenericFloatProperty("solvent_accessibility", + solvent_accessibility) + if calculate_relative_sa: + relative_sa=_CalcRelativeSA(amino_acid,solvent_accessibility) + residue.SetGenericFloatProperty("relative_solvent_accessibility", + relative_sa) + if relative_sa < 0.25: + residue.SetGenericStringProperty("burial_status", 'b') + else: + residue.SetGenericStringProperty("burial_status", 'e') + except Exception, e: + print "ERROR:",e + continue + + rtype=line[16:17] + rt=mol.SecStructure.COIL + if rtype=='H': + rt=mol.SecStructure.ALPHA_HELIX + elif rtype=='E': + rt=mol.SecStructure.EXTENDED + elif rtype=='B': + rt=mol.SecStructure.BETA_BRIDGE + elif rtype=='S': + rt=mol.SecStructure.BEND + elif rtype=='T': + rt=mol.SecStructure.TURN + elif rtype=='I': + rt=mol.SecStructure.PI_HELIX + elif rtype=='G': + rt=mol.SecStructure.THREE_TEN_HELIX + # for corrupted DSSP files. Catch in calling routine: + if residue.IsValid() == 0: + #Todo: if residues with occupancy 0 have been removed before + #using a selection statement, they are missed here + #IMPORTANT: asign DSSP before any selections + stream.close() + raise RuntimeError('Ill-formatted DSSP file: invalid residue') + residue.SetSecStructure(mol.SecStructure(rt)) + stream.close() -- GitLab