Skip to content
Snippets Groups Projects
Select Git revision
  • 8d1158e094213319bf04eaccaaab48b764a524e4
  • master default protected
  • develop protected
  • cmake_boost_refactor
  • ubuntu_ci
  • mmtf
  • non-orthogonal-maps
  • no_boost_filesystem
  • data_viewer
  • 2.11.1
  • 2.11.0
  • 2.10.0
  • 2.9.3
  • 2.9.2
  • 2.9.1
  • 2.9.0
  • 2.8.0
  • 2.7.0
  • 2.6.1
  • 2.6.0
  • 2.6.0-rc4
  • 2.6.0-rc3
  • 2.6.0-rc2
  • 2.6.0-rc
  • 2.5.0
  • 2.5.0-rc2
  • 2.5.0-rc
  • 2.4.0
  • 2.4.0-rc2
29 results

export_sequence_viewerV2.cc

Blame
  • dssp.py 8.61 KiB
    #------------------------------------------------------------------------------
    # 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,subprocess
    
    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 _Cleanup(pdb_path, temp_path, entity_saved):
      if entity_saved and os.path.exists(pdb_path):
        os.remove(pdb_path)
      if os.path.exists(temp_path):
        os.remove(temp_path)
    
    def _ExecuteDSSP(path, dssp_bin, 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(['dsspcmbi','dssp','mkdssp'], env_name='DSSP_EXECUTABLE', 
                                    explicit_file_name=dssp_bin)
      if os.path.isdir(dssp_abs_path):
        raise RuntimeError('"%s" is a directory. Specify path to DSSP binary' % dssp_abs_path)
      if not os.access(dssp_abs_path, os.X_OK):
        raise RuntimeError('"%s" is not executable' % dssp_abs_path)
    
      ps=subprocess.Popen([dssp_abs_path, path, temp_dssp_path], 
                          stderr=subprocess.PIPE)
      err_lines=ps.stderr.readlines()
      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"
      # cysteine bridges are marked with lower-case letters by DSSP. We don't 
      # really care which cysteines are forming covalent bonds, so let's set the 
      # one-letter-code to "C".
      if residue_type.islower():
        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=False, tmp_dir=None, 
                   dssp_bin=None):
      """
      Assign secondary structure states to peptide residues in the structure. This
      function uses the DSSP command line program.
    
      If you already have a DSSP output file and would like to assign the secondary 
      structure states to an entity, use :func:`LoadDSSP`.
      
      :param ent: The entity for which the secondary structure should be calculated
      :type ent: :class:`~ost.mol.EntityHandle` or :class:`~ost.mol.EntityView`
      :param extract_burial_status: If true, also extract burial status and store
                                    as float-property
                                    ``relative_solvent_accessibility`` at residue
                                    level
      :param tmp_dir: If set, overrides the default tmp directory of the
                      operating system
      :param dssp_bin: The path to the DSSP executable
      :raises: :class:`~ost.settings.FileNotFound` if the dssp executable is not 
          in the path.
      :raises: :class:`RuntimeError` when dssp is executed with errors
      """
      entity_saved = False
      # 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.SavePDB(ent, pdb_path)
      entity_saved = True
    
      #TODO: exception handling (currently errors occuring here
      # are handled in the parser LoadDSSP)
      temp_dssp_path=_ExecuteDSSP(pdb_path, dssp_bin)
      if not os.path.exists(temp_dssp_path):
        raise RuntimeError('DSSP output file does not exist.')
      # assign DSSP to entity
      try:
        LoadDSSP(temp_dssp_path, ent, extract_burial_status,
                 entity_saved)
      except Exception, e:
        # clean up
        print "Exception in DSSP:", e
        _Cleanup(pdb_path, temp_dssp_path, entity_saved)
        raise RuntimeError(e)
    
      # clean up
      #print pdb_path, temp_dssp_path
      _Cleanup(pdb_path, temp_dssp_path, entity_saved)
    
      return ent
    
    
    
    def LoadDSSP(file_name, model, extract_burial_status=False,
                 entity_saved=False, calculate_relative_sa=True):
        """
        Loads DSSP output and assigns secondary structure states to the peptidic
        residues.
    
        If you would like to run dssp *and* assign the secondary structure,
        use :func:`AssignDSSP` instead.
    
        :param file_name: The filename of the DSSP output file
        :param model: The entity to which the secondary structure states should be
                      assigned
        :param extract_burial_status: If true also calculates burial status of
            residues and assigns it to the burial_status string property.
        :param calculate_relative_sa: If true also relative solvent accessibility and
            and assigns it to the relative_solvent_accessibility float property of
            the residue.
        :param entity_save: Whether the entity was saved.
        """
        if not model.IsValid():
          raise ValueError('model entity is not valid')
        if model.atom_count==0:
          raise ValueError('model entity does not contain any atoms')
        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:
              #set default (dummy) burial status for incomplete residues:
              residue.SetStringProp("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.SetFloatProp("solvent_accessibility",
                                              solvent_accessibility)
              if calculate_relative_sa:
                relative_sa=_CalcRelativeSA(amino_acid,solvent_accessibility)
                residue.SetFloatProp("relative_solvent_accessibility",
                                                relative_sa)
                if relative_sa < 0.25:
                  residue.SetStringProp("burial_status", 'b')
                else:
                  residue.SetStringProp("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 not residue.IsValid():
            #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()