Ejemplo n.º 1
0
def _InitSpaceNav(app):
    try:
        spnav = gui.SpnavInput.GetQThread()
        if spnav:
            spnav.start()
            parent = app.gl_win.qobject
            SpacenavControl(spnav, parent)
            ost.LogInfo("SpaceNav: device found and connected")
        else:
            ost.LogInfo(
                "SpaceNav: no device found, or could not connect to device socket"
            )
    except:
        ost.LogInfo("SpaceNav: caught exception during initialization: %s" %
                    (traceback.format_exc()))
Ejemplo n.º 2
0
def AddFromFiles(force_field, frcmod_filename, mpdb_filename):
    """Add data from a frcmod and an mpdb file to a force field.

  This will add a new :class:`~ost.mol.mm.BuildingBlock` to `force_field` for
  the residue defined in those files (residue name is extracted from the mpdb
  file which can only contain a single residue). Charges for each atom are
  extracted from the mpdb file. According to the frcmod file, an
  :class:`~ost.mol.mm.Interaction` is added for each bond, angle, dihedral and
  improper. Atom types with masses and non-bonded interactions are added to
  `force_field` as needed.

  :param force_field: A force field object to which the new parameters are
                      added.
  :type force_field:  :class:`~ost.mol.mm.Forcefield`
  :param frcmod_filename: Path to ``frcmod`` file as generated by ``parmchk2``.
  :type frcmod_filename:  :class:`str`
  :param mpdb_filename: Path to mpdb file as generated by ``antechamber``.
  :type mpdb_filename:  :class:`str`
  :return: The updated force field (same as `force_field`).
  :rtype:  :class:`~ost.mol.mm.Forcefield`
  """
    # check files
    if not os.path.exists(frcmod_filename):
        raise RuntimeError("Could not find frcmod file: " + frcmod_filename)
    if not os.path.exists(mpdb_filename):
        raise RuntimeError("Could not find mpdb file: " + mpdb_filename)
    # read in files
    try:
        eh, res_name = _ParseModifiedPDB(mpdb_filename)
    except Exception as ex:
        ost.LogError("Failed to parse mpdb file: " + mpdb_filename)
        raise ex
    try:
        ff_dict = _ParseAmberForceField(frcmod_filename)
    except Exception as ex:
        ost.LogError("Failed to parse frcmod file: " + frcmod_filename)
        raise ex
    ost.LogInfo("Adding force field for " + res_name)
    # add atoms to force field
    for aname, mass in ff_dict['MASS']:
        force_field.AddMass(aname, mass)
    # add LJs
    lj_sigma_scale = 2. / 10. / 2**(1. / 6.)  # Rvdw to sigma in nm
    lj_epsilon_scale = 4.184  # kcal to kJ
    for aname, Rvdw, epsilon in ff_dict['NONB']:
        # fix 0,0 (from OpenMM's processAmberForceField.py)
        if Rvdw == 0 or epsilon == 0:
            Rvdw, epsilon = 1, 0
        lj = mm.Interaction(mm.FuncType.LJ)
        lj.SetTypes([aname])
        lj.SetParam([Rvdw * lj_sigma_scale, epsilon * lj_epsilon_scale])
        force_field.AddLJ(lj)
    # add building block
    bb = _MakeComponentBuildingBlock(eh, ff_dict)
    force_field.AddBuildingBlock(res_name, bb)

    return force_field
Ejemplo n.º 3
0
    def Search(self, a3m_file, database, options={}, prefix=''):
        """
        Searches for templates in the given database. Before running the search,
        the hhm file is copied. This makes it possible to launch several hhblits
        instances at once. Upon success, the filename of the result file is
        returned. This file may be parsed with :func:`ParseHHblitsOutput`.

        :param a3m_file: Path to input MSA as produced by :meth:`BuildQueryMSA`
        :type a3m_file: :class:`str`

        :param database: Search database, needs to be the common prefix of the
                         database files
        :type database: :class:`str`

        :param options: Dictionary of options to *hhblits*, one "-" is added in
                        front of every key. Boolean True values add flag without
                        value. Merged with default options {'cpu': 1, 'n': 1},
                        where 'n' defines the number of iterations.
        :type options: :class:`dict`

        :param prefix: Prefix to the result file
        :type prefix: :class:`str`

        :return: The path to the result file
        :rtype: :class:`str`
        """
        opts = {'cpu' : 1, # no. of cpus used
                'n'   : 1}   # no. of iterations
        opts.update(options)
        opt_cmd, opt_str = _ParseOptions(opts)
        base = os.path.basename(os.path.splitext(a3m_file)[0])
        hhr_file = '%s%s_%s.hhr' % (prefix, base, opt_str)
        hhr_file = os.path.join(self.working_dir, hhr_file)
        search_cmd = '%s %s -e 0.001 -Z 10000 -B 10000 -i %s -o %s -d %s' % (
            self.hhblits_bin,
            opt_cmd,
            os.path.abspath(a3m_file),
            os.path.abspath(hhr_file),
            os.path.join(os.path.abspath(os.path.split(database)[0]),
                         os.path.split(database)[1]))
        ost.LogInfo('searching %s' % database)
        ost.LogVerbose(search_cmd)
        job = subprocess.Popen(search_cmd, shell=True, cwd=self.working_dir,
                               stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        sout, serr = job.communicate()
        if job.returncode != 0:
            lines = sout.decode().splitlines()
            for line in lines:
                ost.LogError(line.strip())
            lines = serr.decode().splitlines()
            for line in lines:
                ost.LogError(line.strip())
            return None
        return hhr_file
Ejemplo n.º 4
0
def renumber_model(model, new_start):
    """ Renumber the model in place, using the new start number. """
    peptide_chains = [
        chain for chain in model.chains if chain.name not in set(["-", "_"])
    ]
    assert len(peptide_chains) == 1  #
    target_chain = peptide_chains[0]
    assert target_chain.IsValid()
    editor = model.EditICS()
    ost.LogInfo("Renumbering target from %s" % new_start)
    editor.RenumberChain(target_chain, new_start, True)
    editor.UpdateXCS()
Ejemplo n.º 5
0
def CreateDB(infasta, dbout, mkdb_cmd=None):
  """
  Create a blast DB from a fasta file

  :param infasta: the pdb fasta from which the database will be created
  :type infasta: :class:`string`

  :param dbout: output location for blastDB file
  :type dbout: :class:`string`


  """
  if mkdb_cmd==None:
    try:
      exe=settings.Locate('formatdb')
      args=[exe, '-i', infasta, '-n', dbout]
    except:
      try:
        exe=settings.Locate('makeblastdb')
        args=[exe, '-in', infasta, '-out', dbout, '-dbtype', 'prot']
      except:
        raise RuntimeError('could not find makeblastdb/formatdb executable')
  else:
    if os.path.basename(mkdb_cmd)=='makeblastdb':
      exe=settings.Locate('makeblastdb',explicit_file_name=mkdb_cmd)
      args=[exe, '-in', infasta, '-out', dbout, '-dbtype', 'prot']
    elif os.path.basename(mkdb_cmd)=='formatdb':
        exe=settings.Locate('formatdb',explicit_filename=mkdb_cmd)
        args=[exe, '-i', infasta, '-n', dbout]
    else:
      raise IOError('mkdb command must either be the path to formatdb or makeblastdb!')

  ost.LogInfo('creating blast DB (%s)' % ' '.join(args))
  blast_pipe=subprocess.Popen(args, stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE)
  blast_pipe.communicate()
Ejemplo n.º 6
0
def Blast(query, database, gap_open=11, gap_ext=1, matrix='BLOSUM62',
         blast_location=None, outfmt=0, filter_low_complexity=True):
  """
  Runs a protein vs. protein blast search. The results are returned
  according to the value of the ``outfmt`` parameter.

  :param query: the query sequence
  :type query: :class:`seq.ConstSequenceHandle`

  :param database: The filename of the sequence database. Make sure that
      formatdb has been run on the database and the <database>.pin file exists.
  :param matrix: The substitution matrix to be used. Must be one of 'BLOSUM45',
     'BLOSUM62', 'BLOSUM80', 'PAM30', 'PAM70'.
  :param gap_open: Gap opening penalty. Note that only a subset of gap opening
     penalties is supported for each substitutition matrix. Consult the blast
     docs for more information.
  :param gap_ext: Gap extension penalty. Only a subset of gap extension
     penalties are supported for each of the substitution matrices. Consult the
     blast docs for more information.
  :param outfmt: output format, where '0' corresponds to default output (parsed 
     blast output and 1 to raw string output).
  :param filter_low_complexity: Mask off segments of the query sequence that 
     have low compositional complexity, as determined by the SEG program of 
     Wootton & Federhen (Computers and Chemistry, 1993)
  :rtype: :class:`BlastHit` (with ``outfmt=0``) or :class:`str` 
     (with ``outfmt=1``)
  """
  subst_mats=('BLOSUM45', 'BLOSUM62', 'BLOSUM80', 'PAM30', 'PAM70',)
  if matrix not in subst_mats:
    raise ValueError('matrix must be one of %s' % ', '.join(subst_mats))
  if not os.path.exists('%s.pin' % database) and not os.path.exists('%s.pal' % database):
    raise IOError("Database %s does not exist" % database)
  if blast_location!=None and not os.path.exists(blast_location):
    ost.LogScript('Could not find %s' %blast_location)

  if blast_location==None:
    try:
      blast_exe=settings.Locate('blastall')
    except:
      try:
        blast_exe=settings.Locate('blastp')
      except:
        raise RuntimeError('could not find blast executable')
  else:
    blast_exe=settings.Locate(os.path.basename(blast_location),explicit_file_name=blast_location)

  if os.path.basename(blast_exe)=='blastall':
    args=[blast_exe, '-d', database, '-p', 'blastp',
          '-m', '7', '-M', matrix, '-G', str(gap_open), '-E', str(gap_ext)]
    if filter_low_complexity==False:
      args.append('-F')
      args.append('F')
          
  else:
    complexity_opt='-seg'
    if filter_low_complexity==True:
      complexity_arg='yes'
    else:
      complexity_arg='no'
    args=[blast_exe, '-db', database, '-matrix', matrix,
          '-gapopen', str(gap_open), '-gapextend', str(gap_ext), '-outfmt', '5', complexity_opt, complexity_arg ]

  ost.LogInfo('running BLAST (%s)' % ' '.join(args))
  blast_pipe=subprocess.Popen(args, stderr=subprocess.PIPE,
                              stdout=subprocess.PIPE, stdin=subprocess.PIPE)
  if isinstance(query, str):
    stdout, stderr=blast_pipe.communicate(query.encode())
  else:
    stdout, stderr=blast_pipe.communicate(io.SequenceToString(query, 'fasta').encode())

  if len(stderr)>0:
     pattern=re.compile(r'^\[.*\]\s+ERROR:\s+(.*)')
     lines=stderr.decode().split('\n')
     error_message=pattern.match(lines[0])
     if error_message:
       raise BlastError(error_message.group(1), '\n'.join(lines[1:]))
  if outfmt==0:
    return ParseBlastOutput(stdout.decode())
  else:
    return stdout.decode()
Ejemplo n.º 7
0
    def BuildQueryMSA(self, nrdb, options={}, a3m_file=None):
        """Builds the MSA for the query sequence.

        This function directly uses hhblits of hhtools. While in theory it would
        be possible to do this by PSI-blasting on our own, hhblits is supposed
        to be faster. Also it is supposed to prevent alignment corruption. The
        alignment corruption is caused by low-scoring terminal alignments that
        draw the sequences found by PSI-blast away from the optimum. By removing
        these low scoring ends, part of the alignment corruption can be
        suppressed.

        hhblits does **not** call PSIPRED on the MSA to predict the secondary
        structure of the query sequence. This is done by addss.pl of hhtools.
        The predicted secondary structure is stored together with the sequences
        identified by hhblits.

        The produced A3M file can be parsed by :func:`ParseA3M`. If the file was
        already produced, hhblits is not called again and the existing file path
        is returned.

        :param nrdb: Database to be align against; has to be an hhblits database
        :type nrdb: :class:`str`

        :param options: Dictionary of options to *hhblits*, one "-" is added in
                        front of every key. Boolean True values add flag without
                        value. Merged with default options {'cpu': 1, 'n': 1},
                        where 'n' defines the number of iterations.
        :type options: :class:`dict`

        :param a3m_file: a path of a3m_file to be used, optional
        :type a3m_file: :class:`str`

        :return: The path to the A3M file containing the MSA
        :rtype: :class:`str`
        """
        if a3m_file is None:
            a3m_file = '%s.a3m' % os.path.splitext(self.filename)[0]
        else:
            a3m_file = os.path.abspath(a3m_file)
        if os.path.exists(a3m_file):
            ost.LogInfo('Reusing already existing query alignment (%s)' % a3m_file)
            return a3m_file
        ost.LogInfo('Using hhblits from "%s"' % self.hhsuite_root)
        full_nrdb = os.path.join(os.path.abspath(os.path.split(nrdb)[0]),
                                 os.path.split(nrdb)[1])
        # create MSA
        opts = {'cpu' : 1, # no. of cpus used
                'n'   : 1}   # no. of iterations
        opts.update(options)
        opt_cmd, _ = _ParseOptions(opts)
        hhblits_cmd = '%s -e 0.001 -i %s -oa3m %s -d %s %s' % \
                      (self.hhblits_bin, self.filename, a3m_file, full_nrdb,
                       opt_cmd)
        job = subprocess.Popen(hhblits_cmd, shell=True, cwd=self.working_dir,
                               stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        sout, _ = job.communicate()
        lines = sout.decode().splitlines()
        for line in lines:
            ost.LogVerbose(line.strip())
        if not os.path.exists(a3m_file):
            ost.LogWarning('Building query profile failed, no output')
            return a3m_file
        # add secondary structure annotation
        addss_cmd = "%s %s" % (os.path.join(self.hhsuite_root,
                                            'lib/hh/scripts/addss.pl'),
                               a3m_file)
        env = dict(os.environ)
        env.update({'PERL5LIB' : os.path.join(self.hhsuite_root,
                                              'lib/hh/scripts'),
                    'HHLIB' : self.hhlib_dir,
                    'PATH' : '%s:%s' % (os.path.join(self.hhsuite_root, 'bin'),
                                        os.environ['PATH'])})
        job = subprocess.Popen(addss_cmd, shell=True, cwd=self.working_dir,
                               env=env, stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
        sout, serr = job.communicate()
        lines = sout.decode().splitlines()
        for line in lines:
            if 'error' in line.lower():
                ost.LogWarning('Predicting secondary structure for MSA '+
                               '(%s) failed, on command: %s' % (a3m_file, line))
                return a3m_file
        return a3m_file