Source code for promod3.modelling._molprobity

'''Binding to external MolProbity tool to get scores.'''

import ost
from ost import settings
import subprocess, tempfile, os

[docs]def RunMolProbity(target_pdb, molprobity_bin=None): '''Run ``MolProbity`` from ``Phenix`` on a given PDB file. MolProbity score computation: (formula from molprobity source code) .. code-block:: python clashscore = result["Clashscore"] rota_out = result["Rotamer outliers"] rama_iffy = 100. - result["Ramachandran favored"] mpscore = (( 0.426 * math.log(1 + clashscore) ) + ( 0.33 * math.log(1 + max(0, rota_out - 1)) ) + ( 0.25 * math.log(1 + max(0, rama_iffy - 2)) )) + 0.5 :param target_pdb: Path to PDB file on which to do analysis. :type target_pdb: :class:`str` :param molprobity_bin: Path to ``phenix.molprobity`` executable. If None, it searches for it in the ``PATH`` or (if set) in the env. variable ``MOLPROBITY_EXECUTABLE``. The function was tested with ``Phenix 1.9-1692`` and with ``MolProbity 4.2`` which also includes it. :type molprobity_bin: :class:`str` :return: Dictionary with scores produced by MolProbity. Entries: - "Ramachandran outliers" (percentage [0,100] as :class:`float`) - "Ramachandran favored" (percentage [0,100] as :class:`float`) - "Rotamer outliers" (percentage [0,100] as :class:`float`) - "C-beta deviations" (:class:`int`) - "Clashscore" (:class:`float`) - "MolProbity score" (:class:`float`) - "RMS(bonds)" (:class:`float`) - "RMS(angles)" (:class:`float`) :rtype: :class:`dict` :raises: :class:`~ost.settings.FileNotFound` if the "phenix.molprobity" executable is not found. ''' # HELPER def GetStringValue(my_line): """Parse line formatted as ' bla = X ...' and return 'X' as string.""" return my_line.split('=')[1].strip().split(' ')[0] # locate molprobity molprobity_exec = settings.Locate("phenix.molprobity", explicit_file_name=molprobity_bin, env_name='MOLPROBITY_EXECUTABLE') # run molprobity avoiding any file output cmd = [molprobity_exec, target_pdb, "output.quiet=True", \ "output.coot=False", "output.probe_dots=False"] job = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) sout, _ = job.communicate() # parse result = dict() first_found = False lines = sout.splitlines() for line in lines: my_line = line.strip().lower() if my_line.startswith("ramachandran outliers"): first_found = True result["Ramachandran outliers"] = float(GetStringValue(line)) elif first_found and my_line.startswith("favored"): result["Ramachandran favored"] = float(GetStringValue(line)) elif first_found and my_line.startswith("rotamer outliers"): result["Rotamer outliers"] = float(GetStringValue(line)) elif first_found and my_line.startswith("clashscore"): result["Clashscore"] = float(GetStringValue(line)) elif first_found and my_line.startswith("c-beta deviations"): result["C-beta deviations"] = int(GetStringValue(line)) elif first_found and my_line.startswith("molprobity score"): result["MolProbity score"] = float(GetStringValue(line)) elif first_found and my_line.startswith("rms(bonds)"): result["RMS(bonds)"] = float(GetStringValue(line)) elif first_found and my_line.startswith("rms(angles)"): result["RMS(angles)"] = float(GetStringValue(line)) return result
[docs]def RunMolProbityEntity(ost_ent, molprobity_bin=None): '''Run molprobity from phenix on given OST entity. See :func:`RunMolProbity` for details. :param ost_ent: OST entity on which to do analysis. :type ost_ent: :class:`Entity <ost.mol.EntityHandle>` ''' # store as PDB in a tmp. file _, tmpfile = tempfile.mkstemp(suffix='.pdb') ost.PushVerbosityLevel(0) ost.io.SavePDB(ost_ent, tmpfile) ost.PopVerbosityLevel() # get result result = RunMolProbity(tmpfile, molprobity_bin) # clean up os.remove(tmpfile) return result
[docs]def ReportMolProbityScores(scores): '''Print MolProbity score and its components to LogInfo. :param scores: MolProbity scores as generated by :func:`RunMolProbity`. :type scores: :class:`dict` ''' ost.LogInfo("MolProbity score: " + str(scores["MolProbity score"])) ost.LogInfo("- Clashscore : " + str(scores["Clashscore"])) ost.LogInfo("- Rotamer outliers : " + str(scores["Rotamer outliers"]) + " %") ost.LogInfo("- Ramachandran favored: " + str(scores["Ramachandran favored"]) + " %")
__all__ = ('RunMolProbity', 'RunMolProbityEntity', 'ReportMolProbityScores')