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()))
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
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
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()
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()
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()
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