# **************************************************************************
# *
# * Authors: Roberto Marabini (roberto@cnb.csic.es)
# * Marta Martinez (mmmtnez@cnb.csic.es)
# *
# * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
# *
# * This program is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 2 of the License, or
# * (at your option) any later version.
# *
# * This program 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 General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# * 02111-1307 USA
# *
# * All comments concerning this program package may be sent to the
# * e-mail address 'scipion@cnb.csic.es'
# *
# **************************************************************************
import collections
import json
from phenix import PHENIXVERSION
import matplotlib.pyplot as plt
from tkinter import *
from tkinter import messagebox
from pyworkflow.viewer import DESKTOP_TKINTER, WEB_DJANGO, ProtocolViewer
from pwem.viewers import TableView, Chimera
from pyworkflow.protocol.params import LabelParam, EnumParam
from phenix import Plugin
from pyworkflow.tests import *
from pwem.objects import String
from pwem import Domain
import os
from collections.abc import ValuesView
[docs]def errorWindow(tkParent, msg):
try:
# if tkRoot is null the error message may be behind
# other windows
messagebox.showerror("Error", # bar title
msg, # message
parent=tkParent)
except:
print(("Error:", msg))
[docs]class PhenixProtRefinementBaseViewer(ProtocolViewer):
""" base for molprovity and real space refine programs
"""
_environments = [DESKTOP_TKINTER, WEB_DJANGO]
COOT = 'coot'
ANALYSISTMPFILE = 'tmpAnalysisFile.txt'
RAMATMPFILE = 'Ramachandran_write_plot.py'
ROTATMPFILE = "Rotamer_write_plot.py"
MULTICPLOTTMPFILE = "Multi_criterion_plot.py"
def __init__(self, **kwargs):
ProtocolViewer.__init__(self, **kwargs)
if os.path.exists(self.protocol._getExtraPath(
self.protocol.MOLPROBITYOUTFILENAME)):
MOLPROBITYOUTFILENAME = self.protocol._getExtraPath(
self.protocol.MOLPROBITYOUTFILENAME)
self._parseFile(MOLPROBITYOUTFILENAME)
if Plugin.getPhenixVersion() == PHENIXVERSION or \
os.path.exists(self.protocol._getExtraPath(
self.protocol.MOLPROBITYPKLFILENAME)):
self.MOLPROBITYPKLFILENAME = self.protocol._getExtraPath(
self.protocol.MOLPROBITYPKLFILENAME)
self._writePickleData()
self.dictOverall = json.loads(self.dictOverall,
object_pairs_hook=collections.OrderedDict)
def _defineParams(self, form):
form.addSection(label="Volume and models")
form.addParam('displayMapModel', LabelParam,
label="Volume and models in ChimeraX",
help="Display of input volume(s) and atomic structure(s).")
if Plugin.getPhenixVersion() == PHENIXVERSION or \
os.path.exists(self.protocol._getExtraPath(
self.protocol.MOLPROBITYPKLFILENAME)):
form.addSection(label='MolProbity results')
group = form.addGroup('Summary MolProbity')
group.addParam('showMolProbityResults', LabelParam,
important=True,
label="MolProbity Basic Statistics",
help="Validation of protein geometry. Statistics "
"computed by the "
"PHENIX package using the same distributions as "
"the MolProbity web server."
"\n\nRamachandran outliers: Outlier "
"residues that show an unusual "
"combination of their phi and psi "
"torsion angles. Ramachandran outlier score is "
"computed as the percentage of Ramachandran "
"outliers regarding the total number of residues "
"in the entry showing outlier assessment."
"\n\nRamachandran "
"favored: Residues that show an normal "
"combination of their phi and psi "
"torsion angles. Ramachandran favored score is "
"computed as the percentage of Ramachandran "
"outliers regarding the total number of residues "
"in the entry showing outlier assessment. Between "
"the favored and outlier regions in the "
"Ramachandran plot, there is a small region of "
"allowed residues.\n\nRotamer outliers: Residues "
"that adopt unusual chi torsion angles "
"(non-rotameric), used to describe "
"the conformation of protein sidechains. The "
"score of rotamer outliers is computed as "
"the percentage of residues with non-rotameric "
"angles.\n\nC-beta outliers: Residues that show an "
"unusual deviation (higher than 0.25 A) of the "
"beta carbon from its ideal position. "
"This deviation of beta carbon "
"indicates incompatibilities between sidechain and "
"backbone.\n\nClashscore: Score associated to the "
"number of pairs of non-bonded atoms in the model "
"that are unusually close to each other. These "
"clashing atoms show unfavorable steric overlaps "
"of van der Waals shells. Steric clashes in "
"proteins are defined based on the Van der Waals "
"repulsion energy of the clashing atoms. "
"The clashscore is computed as the "
"number of serious clashes per 1000 atoms. "
"\n\nRMS (bonds): Root-mean-square deviation of "
"macromolecular bond lengths. "
"\n\nRMS (angles): Root-mean-square deviation of "
"macromolecular bond angles. "
"\n\nOverall score: Score that represents the "
"experimental resolution expected for a model of "
"this quality; ideally the score should be lower "
"than the actual resolution.\n")
group.addParam('showCootOutliers', LabelParam,
important=True,
label="Open in Coot",
help="Interactive visualization of outliers and clashes"
" with Coot:\n\nRamachandran outliers\n"
"Rotamer outliers\nC-beta outliers\n"
"Severe clashes ")
if self.dictOverall['_len_missing_atoms'] > 0:
group.addParam('showMissingAtoms', LabelParam,
label="Missing atoms",
help="For clarity, hydrogen atoms are not included")
group = form.addGroup('Basic Geometry: Bond Length Restraints')
group.addParam('showBLrestraints', LabelParam,
label="Deviations",
help="Check here the number of outlier pairs of atoms "
"according to the bond length restraints "
"between pairs of linked atoms.\nWarning!!!: "
"Refined structures should not have any outliers"
" except those are obvious in high "
"resolution electron density maps.\n")
self.outliers = self.dictBLRestraints['Number of outliers > 4sigma']
if self.outliers > 0:
group.addParam('showBLoutliers', LabelParam, important=True,
label="Outliers",
help="List of outlier pairs of atoms (sorted by deviation) "
"according to the bond length restraints.\n")
group = form.addGroup('Basic Geometry: Bond Angle Restraints')
group.addParam('showBArestraints', LabelParam,
label="Deviations",
help="Check here the number of outlier triplets of atoms "
"according "
"to the bond angle restraints.\n"
"Warning!!!: Refined structures should not "
"have any outliers except those are obvious in "
"high resolution electron density maps.")
self.outliers = self.dictBARestraints['Number of outliers > 4sigma']
if self.outliers > 0:
group.addParam('showBAoutliers', LabelParam, important=True,
label="Outliers",
help="List of outlier triplets of atoms (sorted by "
"deviation) according to the bond angle "
"restraints")
group = form.addGroup('Basic Geometry: Dihedral Angle Restraints')
group.addParam('showDArestraints', LabelParam,
label="Deviations",
help="Check here the number of outlier tetrads of atoms "
"according "
"to the side chain dihedral torsion (chi) angle "
"restraints.\n"
"Warning!!!: Refined structures should not "
"have any outliers except those are obvious in "
"high resolution electron density maps.")
self.outliers = self.dictDARestraints['Number of outliers > 4sigma']
if self.outliers > 0:
group.addParam('showDAoutliers', LabelParam, important=True,
label="Outliers",
help="List of outlier tetrads of atoms ("
"sorted by deviation) "
"according to the dihedral "
"angle restraints")
group = form.addGroup('Basic Geometry: Chirality Restraints')
group.addParam('showCHILrestraints', LabelParam,
label="Deviations",
help="Check here the number of outlier tetrads of atoms "
"according to the volume chirality "
"restraints.\n"
"Warning!!!: Refined structures should not "
"have any outliers except those are obvious "
"in high resolution electron density maps.")
self.outliers = self.dictChilRestraints['Number of outliers > 4sigma']
if self.outliers > 0:
group.addParam('showCHILoutliers', LabelParam, important=True,
label="Outliers",
help="List of outlier tetrads of atoms ("
"sorted by deviation) "
"according to the volume "
"chirality restraints")
group = form.addGroup('Basic Geometry: Planarity Restraints')
group.addParam('showPLANARrestraints', LabelParam,
label="Deviations",
help="Check here the number of outliers of planar "
"groups, such as aromatic rings,"
"according to the planar "
"restraints.\n"
"Warning!!!: Refined structures should not "
"have any outliers except those are obvious "
"in high resolution electron density maps.")
self.outliers = self.dictPlanarRestraints['Number of outliers > 4sigma']
if self.outliers > 0:
group.addParam('showPLANARoutliers', LabelParam, important=True,
label="Outliers",
help='List of planar group outliers '
'(sorted by deviation)')
if (self.dictOverall['_protein'] == True):
group = form.addGroup('Protein')
self.plotList = ['Ramachandran plot', 'Chi1-Chi2 plot']
group.addParam('plotType', EnumParam,
choices=self.plotList, default=0,
label="Select plot:",
help="Select a plot type. Ramachandran plot is "
"chosen by default. Chi1-Chi2 plot shows "
"rotameric angles\n")
group.addParam('showPlotType', LabelParam, important=True,
label="View plot",
help="")
if (self.dictOverall['_percent_rama_outliers'] > 0.):
group.addParam('showRamaOutliersTable', LabelParam,
important=True,
label="Ramachandran outliers:",
help="Ramachandran outliers are those aminoacids"
" with non-favourable dihedral angles. "
"Most of the time, Ramachandran outliers are "
"a consequence of mistakes during the data "
"processing.")
else:
group.addParam('showMesgNoRamaOutliers', LabelParam,
label="No Ramachandran outliers detected")
if (self.dictOverall['_percent_rota_outliers'] > 0.):
group.addParam('showRotaOutliersTable', LabelParam,
important=True,
label="Rotamer outliers: ",
help="Although a residue may lie in the "
"favored regions of the Chi1-Chi2 plot, "
"outliers are flagged based on the "
"distribution of all non-branched Chi "
"angles in a residue.\nZero outliers is "
"not the goal. Rotamer outliers can be "
"justified by sufficiently strong " \
"electron density, van der Waals "
"packing, and/or hydrogen bonds.\n")
else:
group.addParam('showMesgNoRotaOutliers', LabelParam,
label="No Rotamer outliers detected")
if (self.dictOverall['_n_cbeta_outliers'] > 0):
group.addParam('showCbetaOutliersTable', LabelParam,
important=True,
label="C-beta outliers:",
help="C-beta position outliers (position "
"deviates from ideal by more than "
"0.25A).\n\nIdeal CB position is "
"determined from the average of the "
"ideal C-N-CA-CB and N-C-CA-CB dihedrals."
" This measure is more sensitive than"
" individual measures to both sidechain "
"and mainchain misfittings.\n")
else:
group.addParam('showMesgNoCbetaOutliers', LabelParam,
label="No C-beta position outliers detected",
help="C-beta position outliers (position "
"deviates from ideal by more than "
"0.25A).\n\nIdeal CB position is "
"determined from the average of the "
"ideal C-N-CA-CB and N-C-CA-CB dihedrals."
" This measure is more sensitive than"
" individual measures to both sidechain "
"and mainchain misfittings.\n")
if (self.dictOverall['_n_nqh_flips_outliers'] > 0):
group.addParam('showBackAsnGlnHisSidechains', LabelParam,
important=True,
label="Recommended Asn/Gln/His sidechain "
"flips:",
help="Asn, Gln, and His sidechains are "
"asymmetric and may require flipping to "
"form favorable van der Waals contacts "
"and hydrogen bonding.\n\nREDUCE "
"(phenix.reduce) has been run on your "
"file to add hydrogens necessary for "
"identifying clashes and has also "
"identified the following residues "
"as needing to be flipped. Note that "
"phenix.refine will often perform these "
"flips by default.\n")
else:
group.addParam('showMesgNoSidechainFlips', LabelParam,
label="No sidechain flips required",
help="Asn, Gln, and His sidechains are "
"asymmetric and may require flipping to "
"form favorable van der Waals contacts "
"and hydrogen bonding.\n\nREDUCE "
"(phenix.reduce) has been run on your "
"file to add hydrogens necessary for "
"identifying clashes and has also "
"identified the following residues "
"as needing to be flipped. Note that "
"phenix.refine will often perform these "
"flips by default.\n")
if (self.dictOverall['_n_omega_outliers'] > 0):
group.addParam('showCisAndTwistedPeptides', LabelParam,
important=True,
label="Cis and Twisted peptides:",
help="Cis conformations are observed in "
"about 5% of Prolines.\n\nCis "
"conformations are observed in about "
"0.03% of general residues.\n\nTwisted "
"peptides are almost certainly "
"modeling errors.\n")
else:
group.addParam('showMesgNoNonTransPeptides', LabelParam,
label="No non-trans peptides detected",
help="Cis conformations are observed in "
"about 5% of Prolines.\n\nCis "
"conformations are observed in about "
"0.03% of general residues.\n\nTwisted "
"peptides are almost certainly "
"modeling errors.\n")
if (self.dictOverall['_clashes'] == True):
group = form.addGroup('Clashes')
if (self.dictOverall['_n_clashes_outliers'] > 0):
group.addParam('showClashes', LabelParam, important=True,
label="All atom-contact analysis",
help="This list summarizes all severe clashes "
"(more than 0.4 Angstrom non-H-bond "
"overlap) found by PROBE; you can view "
"these graphically in Coot. If no "
"hydrogens were present, REDUCE was "
"used to add them prior to running "
"PROBE.")
else:
group.addParam('showMesgNoClashes', LabelParam,
label="No bad contacts (> 0.4A overlap) found.",
help="This list summarizes all severe clashes "
"(more than 0.4 Angstrom non-H-bond "
"overlap) found by PROBE; you can view "
"these graphically in Coot. If no "
"hydrogens were present, REDUCE was "
"used to add them prior to running "
"PROBE.")
if (self.dictOverall['_rna_group'] == True):
group = form.addGroup('RNA restraint outliers')
# TODO: Describe functions for RNA (Validation.Molprobity.py)
if (self.dictOverall['_n_bonds_rna_outliers'] > 0):
group.addParam('_showRNABonds', LabelParam,
important=True,
label="RNA nucleotides with excessive bond"
" lengths:",
help="")
else:
group.addParam('showMesgNoBonds', LabelParam,
label="All bonds within expected limits",
help="")
if (self.dictOverall['_n_angles_rna_outliers'] > 0):
group.addParam('_showRNAAngles', LabelParam,
important=True,
label="RNA nucleotides with improper dihedral "
"angles:",
help="")
else:
group.addParam('showMesgNoAngles', LabelParam,
label="All dihedral angles within expected "
"limits",
help="")
if (self.dictOverall['_n_puckers_rna_outliers'] > 0):
group.addParam('_showRNASugarPuckers', LabelParam,
important=True,
label="RNA nucleotides with improper sugar "
"puckers:",
help="")
else:
group.addParam('showMesgNoPuckers', LabelParam,
label="All sugar puckers in appropriate "
"conformations",
help="")
if (self.dictOverall['_n_suites_rna_outliers'] > 0):
group.addParam('_showRNASuites', LabelParam,
important=True,
label="RNA nucleotides with bad backbone "
"angles:",
help="")
else:
group.addParam('showMesgNosuites', LabelParam,
label="Backbone angles within expected ranges",
help="")
if (self.dictOverall['_overall_rsc'] == True):
form.addSection(label='Real-space correlation')
group = form.addGroup('Real-space correlation to electron density')
group.addParam('showMultiCriterionPlot', LabelParam,
important=True,
label="View Multi-criterion plot",
help="This plot shows simultaneously "
"Real-space correlation coefficients "
"and B-factor values for each residue.\n")
group.addParam('showOverallRSCResults', LabelParam,
important=True,
label="Correlation Coefficients",
help="Real-space correlation\n\nFor a detailed "
"definition of Mask CC, Volume CC and Peak "
"CC, see Afonine, P. V., Klaholz, B. K., "
"Moriarty, N. W., Poon, B. K., Sobolev, "
"O. V., Terwilliger, T. C., Adams, P. D. "
"& Urzhumtsev, A. (2018). bioRxiv. "
"https://doi.org/10.1101/249607.\n\n"
"Mask CC: Model-to-map correlation "
"coefficient calculated in the map region "
"around the model, using map values inside "
"a mask calculated around the macromolecule"
".\n\nVolume CC and Peak CC compare only "
"map regions with the highest density values "
"and regions below a certain contouring "
"threshold level are ignored.\nVolume CC: "
"The map region considered is defined by "
"the N highest points inside the molecular "
"mask.\nPeak CC: In this case, calculations "
"consider the union of regions defined by "
"the N highest peaks in the model-calculated "
"map and the N highest peaks in the "
"experimental map.\n")
self.residueTypeList = ['Protein', 'Other', 'Water',
'Everything']
group.addParam('residueType', EnumParam,
choices=self.residueTypeList, default=0,
label="Residue Type:",
help="Select a residue Type. Protein is chosen by "
"default.\n")
self.ccBelowList = ['0.1', '0.2', '0.3', '0.4', '0.5', '0.6',
'0.7', '0.8', '0.9', '1.0']
group.addParam('ccIndex', EnumParam,
choices=self.ccBelowList, default=7,
label="Show CC below:",
help="Select a decimal. CC 0.8 is chosen by "
"default.")
group.addParam('showCCTable', LabelParam,
label="Table of Real-space correlation "
"coefficients",
help="Residue: Protein chain, "
"aminoacid index, and aminoacid name.\n"
"B_iso: Isotropic B-factor value for "
"residue (Disorder measure that quantitates "
"the level of thermal motion).\nOccupancy: "
"Disorder measure to indicate alternate "
"location of multiple side chain atoms. "
"Occupancies normally add up to unity. If "
"no alternates have been observed, the "
"occupancy equals to 1.00.\n2Fo-Fc: Electron "
"density computed as 2Fo (Fo: structure "
"factors from the diffraction patterns; "
"experimental data) minus Fc (structure "
"factor amplitudes calculated from model "
"phases).\nFmodel: Model structure factors "
"including all scales.\nCC: Correlation "
"coefficent between the observed map and "
"model-derived map in the real space.\n")
group = form.addGroup('Fourier shell correlations')
_atomRadius = "%0.3f" % self.dictOverall['_atom_radius']
group.addParam('showAtomRadius', LabelParam,
important=True,
label="Atom Mask Radius (Angstroms): " +
str(_atomRadius),
help='Radius of the "Fourier Shell", a spherical '
'volume mask in Fourier space.\n')
group.addParam('displayFSCplot', LabelParam,
label="Fourier Shell Correlation plot",
help="FSC regarding spatial frequency "
"(1/Angstroms)")
form.addSection(label='Atomic properties')
group = form.addGroup('Occupancies')
self._computeOccBFactor(self.dictOverall['_occ_bf_outliers'])
if (len(self.occupancyList) == 0):
group.addParam('showMesgNoOccupancies', LabelParam,
important=True, label="All occupancies okay")
else:
group.addParam('showOccupancies', LabelParam,
important=True,
label="Table of occupancies",
help="The table shows occupancy values lower "
"than 1.0 for an atom when summed over "
"alternative conformations (Type = atom) "
"or for a residue when the occupancies for "
"the atoms in a residue are not the same ("
"Type = residue). Please check"
" that they are correct.\n")
group = form.addGroup('B-factor/ADPs')
if ((self.dictOverall['_n_aniso_h'] is not None) and
(self.dictOverall['_n_aniso_h'] > 0)):
group.addParam('showWarningAnisoH', LabelParam, important= True,
label="WARNING: %d hydrogens have anisotropic "
"B-factors." % self.dictOverall['_n_aniso_h'])
group.addParam('showIsotropicB', LabelParam,
important=True,
label="Isotropic B:",
help="The refinement against the map of B-factors or "
"Atomic Displacement Parameters (ADPs) is "
"performed at the last macro-cycle and using "
"reciprocal space.\n\nIsotropic B: Temperature "
"factor or displacement parameter constraining "
"the motion of the atoms so it is the same in "
"all three directions.\nMinimum, Maximum and Mean "
"are the statistic values of isotropic B-factor ")
if (len(self.suspiciousBFList) > 0):
group.addParam('showSuspiciousBfactors', LabelParam,
label="Suspicious B-factors",
help= "The table of Suspicious B-factors (ADP"
" outliers) details all isotropic ADPs "
"with values outside a range of plus "
"or minus 4 sigmas around the mean "
"value for the considered atomic "
"structure. Although these B-factors "
"are not neccessarily wrong, "
"it may be worth checking the atomic "
"positions, occupancies or element "
"types shown in this table.\n")
if self.dictOverall['_n_zero_b'] > 0:
group.addParam('showWarningSuspicious', LabelParam,
important=True,
label="WARNING: %d atom(s) have "
"B-factor(s) of zero, which indicates"
" that either the occupancy or the "
"element is incorrect."
% self.dictOverall['_n_zero_b'])
def _getVisualizeDict(self):
return{
'displayMapModel': self._displayMapModel,
'showMolProbityResults': self._visualizeMolProbityResults,
'showCootOutliers': self._showCootOutliers,
'showMissingAtoms': self._showMissingAtoms,
'showBLrestraints': self._showBLrestraints,
'showBLoutliers': self._showBLoutliers,
'showBArestraints': self._showBArestraints,
'showBAoutliers': self._showBAoutliers,
'showDArestraints': self._showDArestraints,
'showDAoutliers': self._showDAoutliers,
'showCHILrestraints': self._showCHILrestraints,
'showCHILoutliers': self._showCHILoutliers,
'showPLANARrestraints': self._showPLANARrestraints,
'showPLANARoutliers': self._showPLANARoutliers,
'showPlotType': self._showPlotType,
'showRamaOutliersTable': self._showRamaOutliersTable,
'showRotaOutliersTable': self._showRotaOutliersTable,
'showCbetaOutliersTable': self._showCbetaOutliersTable,
'showBackAsnGlnHisSidechains': self._showBackAsnGlnHisSidechains,
'showCisAndTwistedPeptides': self._showCisAndTwistedPeptides,
'showMultiCriterionPlot': self._showMultiCriterionPlot,
'showOverallRSCResults': self._showOverallRSCResults,
'showClashes': self._showClashes,
'showCCTable': self._showCCTable,
'displayFSCplot': self._displayFSCplot,
'showOccupancies' : self._showOccupancies,
'showIsotropicB': self._showIsotropicB,
'showSuspiciousBfactors': self. _showSuspiciousBfactors
}
def _displayMapModel(self, e=None):
bildFileName = self.protocol._getExtraPath("axis_output.bild")
try:
_inputVol = self.protocol.inputVolume.get()
except:
_inputVol = self.protocol.inputStructure.get().getVolume()
if _inputVol is not None:
dim = _inputVol.getDim()[0]
sampling = _inputVol.getSamplingRate()
else:
# To show pdbs only
dim = 150.
sampling = 1.
Chimera.createCoordinateAxisFile(dim,
bildFileName=bildFileName,
sampling=sampling)
counter = 1
fnCmd = self.protocol._getExtraPath("chimera_output.cxc")
f = open(fnCmd, 'w')
# change to workingDir
# If we do not use cd and the project name has an space
# the protocol fails even if we pass absolute paths
f.write('cd %s\n' % os.getcwd())
# reference axis model = 1
f.write("open %s\n" % bildFileName)
f.write("cofr 0,0,0\n") # set center of coordinates
# input 3D map
counter += 1 # 1
if self._getInputVolume() is not None:
fnVol = self._getInputVolume()
try:
VOLUMEFILENAME = self.protocol._getExtraPath(
self.protocol.MOLPROBITYFILE)
except:
if self.protocol.hasAttribute('REALSPACEFILE'):
VOLUMEFILENAME = self.protocol._getExtraPath(
self.protocol.REALSPACEFILE)
elif self.protocol.hasAttribute('VALIDATIONCRYOEMFILE'):
VOLUMEFILENAME = self.protocol._getExtraPath(
self.protocol.VALIDATIONCRYOEMFILE)
f.write("open %s\n" % VOLUMEFILENAME)
x, y, z = fnVol.getOrigin(force=True).getShifts()
sampling = fnVol.getSamplingRate()
f.write("volume #%d style surface voxelSize %f\nvolume #%d origin "
"%0.2f,%0.2f,%0.2f\n"
% (counter, sampling, counter, x, y, z))
if len(fnVol.getHalfMaps()) > 0:
for halfMap in fnVol.getHalfMaps().split(','):
counter += 1
if not halfMap.endswith(".mrc"):
f.write("open %s\n" % halfMap.split(".")[0] + ".mrc")
else:
f.write("open %s\n" % halfMap)
f.write("volume #%d style surface voxelSize %f\n" %
(counter, sampling))
f.write("volume #%d origin %0.2f,%0.2f,%0.2f\n" %
(counter, x, y, z))
# input PDB (usually from coot)
counter += 1 # 2
pdbFileName = self.protocol.inputStructure.get().getFileName()
f.write("open %s\n" % pdbFileName)
f.write("style stick\n")
# refined PDB
if self.protocol.hasAttribute('outputPdb') and \
(len(os.listdir(self.protocol._getExtraPath())) > 5):
counter += 1 # 3
pdbFileName = self.protocol.outputPdb.getFileName()
f.write("open %s\n" % pdbFileName)
f.close()
# run in the background
chimeraPlugin = Domain.importFromPlugin('chimera', 'Plugin', doRaise=True)
chimeraPlugin.runChimeraProgram(chimeraPlugin.getProgram(), fnCmd + "&",
cwd=os.getcwd())
return []
def _visualizeMolProbityResults(self, e=None):
headerList = ['statistic', 'value']
dictX = self.dictSummary
val = 0.4
mesg = "Model Final Statistics"
title = "MolProbity: Final Results Summary"
self._showResults(headerList, dictX, val, mesg, title)
def _showCootOutliers(self, e=None):
MOLPROBITYCOOTFILENAME = self.protocol._getExtraPath(
self.protocol.MOLPROBITYCOOTFILENAME)
args = ""
args += " --python " + MOLPROBITYCOOTFILENAME
# pdb file
if self.protocol.hasAttribute('outputPdb'):
pdb = self.protocol.outputPdb
else:
pdb = self.protocol.inputStructure.get()
CootRefine = Domain.importFromPlugin('ccp4.protocols', 'CootRefine', doRaise=True)
project = self.protocol.getProject()
args = {
'pdbFileToBeRefined': pdb,
'doInteractive': True,
'phythonscript': String(MOLPROBITYCOOTFILENAME),
'inputProtocol': self.protocol
}
# volume
vol = self._getInputVolume()
if vol is not None:
args['inputVolumes'] = [vol]
protCoot = project.newProtocol(CootRefine, **args)
protCoot.setObjLabel('coot refinement\noutliers\n')
project.launchProtocol(protCoot)
def _getInputVolume(self):
if self.protocol.inputVolume.get() is None:
fnVol = self.protocol.inputStructure.get().getVolume()
else:
fnVol = self.protocol.inputVolume.get()
return fnVol
def _showMissingAtoms(self, e=None):
headerList = ['Chain', 'Residue', 'AtLoc', 'Missing atoms']
dataList = []
chain = []
residue = []
atLoc = []
missingAtoms = []
for i in range(len(self.dictOverall['_missing_atoms'])):
chain.append(self.dictOverall['_missing_atoms'][i][0])
residue.append(self.dictOverall['_missing_atoms'][i][1])
atLoc.append(self.dictOverall['_missing_atoms'][i][2])
missingAtoms.append(self.dictOverall['_missing_atoms'][i][3])
for c, r, aL, mA in zip(chain, residue, atLoc, missingAtoms):
dataList.append((c, r, aL, mA))
mesg = "Missing atoms"
title = "Model missing atoms"
self._showOutliers(headerList, dataList, mesg, title)
def _showBLrestraints(self, e=None):
headerList = ['measure', 'value']
dictX = self.dictBLRestraints
val = 0.3
mesg = "Bond Length Restraints\n(Deviations from ideal values)"
title = "MolProbity: Basic Geometry"
self._showResults(headerList, dictX, val, mesg, title)
def _showBLoutliers(self, e=None):
headerList = ['Atom1', 'Atom2', 'Ideal value', 'Model value',
'Deviation (sigmas)']
dataList = self.blDataList
mesg = "List of outliers (sorted by deviation)"
title = "Bond Length Restraints"
self._showOutliers(headerList, dataList, mesg, title)
def _showBArestraints(self, e=None):
headerList = ['measure', 'value']
dictX = self.dictBARestraints
val = 0.3
mesg = "Bond Angle Restraints\n(Deviations from ideal values)"
title = "MolProbity: Basic Geometry"
self._showResults(headerList, dictX, val, mesg, title)
def _showBAoutliers(self, e=None):
headerList = ['Atoms', 'Ideal value', 'Model value', 'Deviation ('
'sigmas)']
dataList = self.baDataList
mesg = "List of outliers (sorted by deviation)"
title = "Bond Angle Restraints"
self._showOutliers(headerList, dataList, mesg, title)
def _showDArestraints(self, e=None):
headerList = ['measure', 'value']
dictX = self.dictDARestraints
val = 0.3
mesg = "Dihedral Angle Restraints\n(Deviations from ideal values)"
title = "MolProbity: Basic Geometry"
self._showResults(headerList, dictX, val, mesg, title)
def _showDAoutliers(self, e=None):
headerList = ['Atoms', 'Ideal value', 'Model value', 'Deviation ('
'sigmas)']
dataList = self.daDataList
mesg = "List of outliers (sorted by deviation)"
title = "Dihedral Angle Restraints"
self._showOutliers(headerList, dataList, mesg, title)
def _showCHILrestraints(self, e=None):
headerList = ['measure', 'value']
dictX = self.dictChilRestraints
val = 0.3
mesg = "Chirality Restraints\n(Deviations from ideal values)"
title = "MolProbity: Basic Geometry"
self._showResults(headerList, dictX, val, mesg, title)
def _showCHILoutliers(self, e=None):
headerList = ['Atoms', 'Ideal value', 'Model value', 'Deviation ('
'sigmas)']
dataList = self.chilDataList
mesg = "List of outliers (sorted by deviation)"
title = "Chirality Restraints"
self._showOutliers(headerList, dataList, mesg, title)
def _showPLANARrestraints(self, e=None):
headerList = ['measure', 'value']
dictX = self.dictPlanarRestraints
val = 0.3
mesg = "Planarity Restraints\n(Deviations from ideal values)"
title = "MolProbity: Basic Geometry"
self._showResults(headerList, dictX, val, mesg, title)
def _showPLANARoutliers(self, e=None):
headerList = ['Atoms', 'Max. delta', 'RMS (delta)', 'Deviation ('
'sigmas)']
dataList = self.planarDataList
mesg = "List of outliers (sorted by deviation)"
title = "Planarity Restraints"
self._showOutliers(headerList, dataList, mesg, title)
def _showPlotType(self, e=None):
plot_index = int(self.plotType)
self.listName = self.plotList[plot_index]
self._writeCommand(self.listName)
if self.listName == self.plotList[1]:
self.TMPFILENAME = self.protocol._getExtraPath(self.ROTATMPFILE)
else:
self.TMPFILENAME = self.protocol._getExtraPath(self.RAMATMPFILE)
with open(self.TMPFILENAME, "w") as f:
f.write(self.command)
# execute file with phenix.python
Plugin.runPhenixProgram("", self.TMPFILENAME)
def _showRamaOutliersTable(self, e=None):
headerList = self.dictOverall['_rama_headers']
dataList = self.dictOverall['_rama_outliers']
mesg = "Ramachandran outliers"
title = "Ramachandran analysis"
self._showOutliers(headerList, dataList, mesg, title)
def _showRotaOutliersTable(self, e=None):
headerList = self.dictOverall['_rota_headers']
dataList = self.dictOverall['_rota_outliers']
mesg = "Rotamer outliers"
title = "Rotamer analysis"
self._showOutliers(headerList, dataList, mesg, title)
def _showCbetaOutliersTable(self, e=None):
headerList = self.dictOverall['_cbeta_headers']
dataList = self.dictOverall['_cbeta_outliers']
mesg = "C-beta position outliers"
title = "C-beta deviation analysis"
self._showOutliers(headerList, dataList, mesg, title)
def _showBackAsnGlnHisSidechains(self, e=None):
headerList = self.dictOverall['_nqh_flips_headers']
dataList = self.dictOverall['_nqh_flips_outliers']
mesg = "Recommended sidechain flips"
title = "Backwards Asn/Gln/His sidechains"
self._showOutliers(headerList, dataList, mesg, title)
def _showCisAndTwistedPeptides(self, e=None):
headerList = self.dictOverall['_omega_headers']
dataList = self.dictOverall['_omega_outliers']
mesg = "Cis and Twisted peptides"
title = "Cis and Twisted peptides analyis"
self._showOutliers(headerList, dataList, mesg, title)
def _showClashes(self, e=None):
headerList = self.dictOverall['_clashes_headers']
dataList = self.dictOverall['_clashes_outliers']
mesg = "Bad contacts from PROBE: %d overlapping atom pairs" \
% len(dataList)
title = "All atom-contact analyis"
self._showOutliers(headerList, dataList, mesg, title)
def _showMultiCriterionPlot(self, e=None):
self.listName = "Multi-criterion plot"
self._writeCommand(self.listName)
self.TMPFILENAME = self.protocol._getExtraPath(self.MULTICPLOTTMPFILE)
with open(self.TMPFILENAME, "w") as f:
f.write(self.command)
# execute file with phenix.python
Plugin.runPhenixProgram("", self.TMPFILENAME)
def _showOverallRSCResults(self, e=None):
headerList = ['statistic', 'value']
dictX = self.dictOverall
val = 0.3
mesg = "Model Final Statistics"
title = "Real-space correlation: Final Results Summary"
self._showResults(headerList, dictX, val, mesg, title)
def _showCCTable(self, e=None):
self._computeCCTable()
headerList = self.dictOverall['_rs_headers']
dataList = self.RSCCList
mesg = "Real-space correlation"
title = "Correlation coefficients table"
self._showOutliers(headerList, dataList, mesg, title)
def _showOccupancies(self, e=None):
headerList = self.dictOverall['_occ_bf_headers']
dataList = self.occupancyList
mesg = "Occupancies"
title = "Occupancies"
self._showOutliers(headerList, dataList, mesg, title)
def _showIsotropicB(self, e=None):
headerList = ['statistic', 'value']
dictX = collections.OrderedDict()
dictX['Minimun'] = self.dictOverall['_b_min']
if self.dictOverall['_b_min_macromolecules'] is not None:
dictX['Min (macromolecules)'] = \
self.dictOverall['_b_min_macromolecules']
if self.dictOverall['_b_min_ligands'] is not None:
dictX['Min (ligands)'] = \
self.dictOverall['_b_min_ligands']
dictX['Maximun'] = self.dictOverall['_b_max']
if self.dictOverall['_b_max_macromolecules'] is not None:
dictX['Max (macromolecules)'] = \
self.dictOverall['_b_max_macromolecules']
if self.dictOverall['_b_max_ligands'] is not None:
dictX['Max (ligands)'] = \
self.dictOverall['_b_max_ligands']
dictX['Mean'] = self.dictOverall['_b_mean']
if self.dictOverall['_b_mean_macromolecules'] is not None:
dictX['Mean (macromolecules)'] = \
self.dictOverall['_b_mean_macromolecules']
if self.dictOverall['_b_mean_ligands'] is not None:
dictX['Mean (ligands)'] = \
self.dictOverall['_b_mean_ligands']
val = 0.2
mesg = "Isotropic B"
title = "B-factors/ADPs"
self._showResults(headerList, dictX, val, mesg, title)
def _showSuspiciousBfactors(self, e=None):
headerList = self.dictOverall['_occ_bf_headers']
dataList = self.suspiciousBFList
mesg = "Suspicious B-factors"
title = "B-factors/ADPs"
self._showOutliers(headerList, dataList, mesg, title)
def _showResults(self, headerList, dictX, val, mesg, title):
dataList = []
for k, v in list(dictX.items()):
if k[0] == "_":
continue
if isinstance(v, int):
dataList.append((k, v))
elif isinstance(v, float):
dataList.append((k, ("%" + str(val) + "f") % v))
if not dataList:
errorWindow(self.getTkRoot(), "No data available")
return
TableView(headerList=headerList,
dataList=dataList,
mesg=mesg,
title=title,
height=len(dataList), width=250, padding=40)
def _showOutliers(self, headerList, dataList, mesg, title):
if not dataList:
errorWindow(self.getTkRoot(), "No data available")
return
TableView(headerList=headerList,
dataList=dataList,
mesg=mesg,
title=title,
height=min(20,len(dataList)), width=250, padding=40)
def _displayFSCplot(self, e=None):
xList = self.dictOverall['_x_fsc']
yList = self.dictOverall['_y_fsc']
if not (xList or yList):
errorWindow(self.getTkRoot(), "No data available")
return
title = 'Fourier Shell Correlation (Map vs. Model)'
plt.plot(xList, yList)
plt.axis([0, 0.8, -0.2, 1])
plt.title(title)
plt.xlabel('1/resolution (1/Angstrom)')
plt.ylabel('FSC')
plt.show()
def _parseFile(self, fileName):
self.dictSummary = collections.OrderedDict()
self.dictBLRestraints = collections.OrderedDict()
self.blDataList = []
self.dictBARestraints = collections.OrderedDict()
self.baDataList = []
self.dictDARestraints = collections.OrderedDict()
self.daDataList = []
self.dictChilRestraints = collections.OrderedDict()
self.chilDataList = []
self.dictPlanarRestraints = collections.OrderedDict()
self.planarDataList = []
with open(fileName) as f:
line = f.readline()
while line:
words = line.strip().split()
if len(words) > 1:
if (words[0] == 'Ramachandran' and words[1] == 'outliers'):
self.dictSummary['Ramachandran outliers (%)'] = \
float(words[3])
elif (words[0] == 'favored' and words[1] == '='):
self.dictSummary['Ramachandran favored (%)'] = \
float(words[2])
elif (words[0] == 'Rotamer' and words[1] == 'outliers'):
self.dictSummary['Rotamer outliers (%)'] = float(
words[3])
elif (words[0] == 'C-beta' and words[1] == 'deviations'):
self.dictSummary['C-beta outliers'] = int(words[3])
elif (words[0] == 'Clashscore' and words[1] == '='):
self.dictSummary['Clashscore'] = float(words[2])
elif (words[0] == 'RMS(bonds)' and words[1] == '='):
self.dictSummary['RMS (bonds)'] = float(words[2])
elif (words[0] == 'RMS(angles)' and words[1] == '='):
self.dictSummary['RMS (angles)'] = float(words[2])
elif (words[0] == 'MolProbity' and words[1] == 'score'):
self.dictSummary['Overall score'] = float(words[3])
elif (words[0] == 'bond' or words[0] =='Bond' and words[1] == ':'):
self.dictBLRestraints['Number of restraints'] = int(
words[4])
self.dictBLRestraints['RMS (deviation)'] = float(
words[2])
self.dictBLRestraints['Max deviation'] = float(
words[3])
elif (words[0] == '----------Bond' and words[1] ==
'lengths----------'):
f.readline()
line = f.readline()
words = line.strip().split()
if (words[0] == 'All' and words[1] == 'restrained'):
self.dictBLRestraints['Number of outliers ' \
'> 4sigma'] = 0
elif (words[0] == 'Using' and words[1] == 'conformation-dependent'):
f.readline()
line = f.readline()
words = line.strip().split()
if (words[0] == 'All' and words[1] == 'restrained'):
self.dictBLRestraints['Number of outliers ' \
'> 4sigma'] = 0
elif (words[0] == 'atoms'):
line = f.readline()
words = line.strip().split()
self._parseFileAtom1Atom2(words, f)
self.dictBLRestraints['Number of outliers '\
'> 4sigma'] = len(self.Atom1)
self.blDataList = list(zip(self.Atom1, self.Atom2,
self.IdealValue,
self.ModelValue,
self.Deviation))
elif (words[0] == 'angle' or words[0] == 'Angle' and words[1] == ':'):
self.dictBARestraints['Number of restraints'] = int(
words[4])
self.dictBARestraints['RMS (deviation)'] = float(
words[2])
self.dictBARestraints['Max deviation'] = float(
words[3])
elif (words[0] == '----------Bond' and words[1] ==
'angles----------'):
f.readline()
line = f.readline()
words = line.strip().split()
if (words[0] == 'All' and words[1] == 'restrained'):
self.dictBARestraints[
'Number of outliers > 4sigma'] = 0
elif (words[0] == 'Using' and words[1] == 'conformation-dependent'):
f.readline()
line = f.readline()
words = line.strip().split()
if (words[0] == 'All' and words[1] == 'restrained'):
self.dictBARestraints[
'Number of outliers > 4sigma'] = 0
elif (words[0] == 'atoms'):
self._wrapParseFileAtom123(words, f)
elif (words[0] == 'dihedral' or words[0] == 'Dihedral' and words[1] == ':'):
self.dictDARestraints['Number of restraints'] = int(
words[4])
self.dictDARestraints['RMS (deviation)'] = float(
words[2])
self.dictDARestraints['Max deviation'] = float(
words[3])
elif (words[0] == '----------Dihedral' and words[1] ==
'angles----------'):
f.readline()
line = f.readline()
words = line.strip().split()
if (words[0] == 'All' and words[1] == 'restrained'):
self.dictDARestraints[
'Number of outliers > 4sigma'] = 0
elif (words[0] == 'Using' and words[1] == 'conformation-dependent'):
f.readline()
line = f.readline()
words = line.strip().split()
if (words[0] == 'All' and words[1] == 'restrained'):
self.dictDARestraints[
'Number of outliers > 4sigma'] = 0
elif (words[0] == 'atoms'):
line = f.readline()
words = line.strip().split()
self._parseFileAtom1234(words, f)
self.dictDARestraints[
'Number of outliers > 4sigma'] = len(self.Atom1)
for a1, a2, a3, a4, iv, mv, d in zip (self.Atom1,
self.Atom2,
self.Atom3,
self.Atom4,
self.IdealValue,
self.ModelValue,
self.Deviation):
element = a1 + ", " + a2 + ", " + a3 + ", " + a4
if len(element) > 46:
element = element.replace(element[46:],
"...")
self.daDataList.append((element,
iv, mv, d))
elif (words[0] == 'chirality' or words[0] == 'Chirality' and words[1] == ':'):
self.dictChilRestraints['Number of restraints'] = int(
words[4])
self.dictChilRestraints['RMS (deviation)'] = float(
words[2])
self.dictChilRestraints['Max deviation'] = float(
words[3])
elif (words[0] == '----------Chiral' and words[1] ==
'volumes----------'):
f.readline()
line = f.readline()
words = line.strip().split()
if (words[0] == 'All' and words[1] == 'restrained'):
self.dictChilRestraints[
'Number of outliers > 4sigma'] = 0
elif (words[0] == 'Using' and words[1] == 'conformation-dependent'):
f.readline()
line = f.readline()
words = line.strip().split()
if (words[0] == 'All' and words[1] == 'restrained'):
self.dictChilRestraints[
'Number of outliers > 4sigma'] = 0
elif (words[0] == 'atoms'):
line = f.readline()
words = line.strip().split()
self._parseFileAtom1234(words, f)
self.dictChilRestraints[
'Number of outliers > 4sigma'] = len(self.Atom1)
for a1, a2, a3, a4, iv, mv, d in zip(self.Atom1,
self.Atom2,
self.Atom3,
self.Atom4,
self.IdealValue,
self.ModelValue,
self.Deviation):
element = a1 + ", " + a2 + ", " + a3 + ", " + a4
if len(element) > 46:
element = element.replace(element[46:],
"...")
self.chilDataList.append((element, iv, mv, d))
elif (words[0] == 'planarity' or words[0] == 'Planarity' and words[1] == ':'):
self.dictPlanarRestraints['Number of restraints'] = \
int(words[4])
self.dictPlanarRestraints['RMS (deviation)'] = float(
words[2])
self.dictPlanarRestraints['Max deviation'] = float(
words[3])
elif (words[0] == '----------Planar' and words[1] ==
'groups----------'):
f.readline()
line = f.readline()
words = line.strip().split()
if (words[0] == 'All' and words[1] == 'restrained'):
self.dictPlanarRestraints[
'Number of outliers > 4sigma'] = 0
elif (words[0] == 'Using' and words[1] == 'conformation-dependent'):
f.readline()
line = f.readline()
words = line.strip().split()
if (words[0] == 'All' and words[1] == 'restrained'):
self.dictPlanarRestraints[
'Number of outliers > 4sigma'] = 0
elif (words[0] == 'atoms'):
line = f.readline()
words = line.strip().split()
self._parseFileGroups(words, f)
self.dictPlanarRestraints[
'Number of outliers > 4sigma'] = int(self.cnt)
for a, md, rd, d in zip(self.groups,
self.MaxDelta,
self.RMSDelta,
self.Deviation):
element = str()
for i in range(len(a) -1):
element += a[i] + ", "
element += a[len(a) - 1]
if len(element) > 35:
element = element.replace(element[35:],
"...")
self.planarDataList.append(
(element, md, rd, d))
line = f.readline()
def _parseFileAtom1Atom2(self, words, f):
self.Atom1 = []
self.Atom2 = []
self.IdealValue = []
self.ModelValue = []
self.Deviation = []
while (len(words) > 1):
if len(words) == 3:
self.Atom1.append(words[0] + ' ' +
words[1] + ' ' + words[2])
elif len(words) == 4:
self.Atom1.append(words[0] + ' ' + words[1] + ' ' +
words[2] + ' ' + words[3])
elif len(words) == 10:
self.Atom2.append(words[0] + ' ' + words[1] + ' ' +
words[2] + ' ' + words[3])
self.IdealValue.append((words[4]))
self.ModelValue.append((words[5]))
self.Deviation.append(
(words[9].split('*')[0]))
elif len(words) == 9:
self.Atom2.append(words[0] + ' ' +
words[1] + ' ' + words[2])
self.IdealValue.append((words[3]))
self.ModelValue.append((words[4]))
self.Deviation.append(
(words[8].split('*')[0]))
line = f.readline()
words = line.strip().split()
def _wrapParseFileAtom123(self, words, f):
line = f.readline()
words = line.strip().split()
self._parseFileAtom123(words, f)
self.dictBARestraints[
'Number of outliers > 4sigma'] = len(self.Atom1)
for a1, a2, a3, iv, mv, d in zip(self.Atom1,
self.Atom2,
self.Atom3,
self.IdealValue,
self.ModelValue,
self.Deviation):
self.baDataList.append((a1 + ", " + a2 + ", "
"" +
a3, iv, mv, d))
def _parseFileAtom123(self, words, f):
self.Atom1 = []
self.Atom2 = []
self.Atom3 = []
Atom123 = [self.Atom1, self.Atom2, self.Atom3]
self.IdealValue = []
self.ModelValue = []
self.Deviation = []
while len(words) > 1:
for atom in Atom123:
if len(words) == 4:
atom.append(words[0] + ' ' + words[1] +
' ' + words[2] + ' ' + words[3])
if (len(words) == 10):
atom.append(words[0] + ' ' + words[1] +
' ' + words[2] + ' ' + words[3])
self.IdealValue.append(float(words[4]))
self.ModelValue.append(float(words[5]))
self.Deviation.append(
float(words[9].split('*')[0]))
if len(words) == 3:
atom.append(words[0] + ' ' + words[1] +
' ' + words[2])
if (len(words) == 9):
atom.append(words[0] + ' ' + words[1] +
' ' + words[2])
self.IdealValue.append(float(words[3]))
self.ModelValue.append(float(words[4]))
self.Deviation.append(
float(words[8].split('*')[0]))
line = f.readline()
words = line.strip().split()
def _parseFileAtom1234(self, words, f):
self.Atom1 = []
self.Atom2 = []
self.Atom3 = []
self.Atom4 = []
Atom1234 = [self.Atom1, self.Atom2, self.Atom3, self.Atom4]
self.IdealValue = []
self.ModelValue = []
self.Deviation = []
while (len(words) > 1):
for atom in Atom1234:
if len(words) == 4:
atom.append(words[0] + ' ' + words[1] +
' ' + words[2] + ' ' + words[3])
if (len(words) == 10):
atom.append(words[0] + ' ' + words[1] +
' ' + words[2] + ' ' + words[3])
self.IdealValue.append(float(words[4]))
self.ModelValue.append(float(words[5]))
self.Deviation.append(
float(words[9].split('*')[0]))
if len(words) == 3:
atom.append(words[0] + ' ' + words[1] +
' ' + words[2])
if (len(words) == 9):
atom.append(words[0] + ' ' + words[1] +
' ' + words[2])
self.IdealValue.append(float(words[3]))
self.ModelValue.append(float(words[4]))
self.Deviation.append(
float(words[8].split('*')[0]))
line = f.readline()
words = line.strip().split()
def _parseFileGroups(self, words, f):
self.cnt = 0
self.groups = []
Atoms = []
self.MaxDelta = []
self.RMSDelta = []
self.Deviation = []
while (len(words) > 1):
if len(words) == 4:
Atoms.append(words[0] + " " + words[1] +
" " + words[2] + " " +
words[3])
if len(words) == 8:
self.cnt += 1
Atoms.append(words[0] + " " + words[1] +
" " + words[2] + " " +
words[3])
aminoacid = Atoms
Atoms = []
self.groups.append(aminoacid)
self.MaxDelta.append(float(words[5]))
self.RMSDelta.append(float(words[4]))
self.Deviation.append(
float(words[7].split('*')[0]))
if len(words) == 3:
Atoms.append(words[0] + " " + words[1] +
" " + words[2])
if len(words) == 7:
self.cnt += 1
Atoms.append(words[0] + " " + words[1] +
" " + words[2])
aminoacid = Atoms
Atoms = []
self.groups.append(aminoacid)
self.MaxDelta.append(float(words[4]))
self.RMSDelta.append(float(words[3]))
self.Deviation.append(
float(words[6].split('*')[0]))
line = f.readline()
words = line.strip().split()
def _writePickleData(self):
ANALYSISTMPFILENAME = self.protocol._getExtraPath(
self.ANALYSISTMPFILE)
command = """import pickle
import collections
import json
def pickleData(file):
with open(file,"r") as f:
return pickle.load(f)
# process file %s"
data = pickleData('%s')
dictOverall = collections.OrderedDict()
# missing atoms
if data.missing_atoms is not None:
dictOverall['_missing_atoms'] = data.missing_atoms
dictOverall['_len_missing_atoms'] = len(data.missing_atoms)
else:
dictOverall['_len_missing_atoms'] = 0
# Protein group
if data.ramalyze is None:
dictOverall['_protein'] = False
else:
dictOverall['_protein'] = True
# Ramachandran analysis
dictOverall['_percent_rama_outliers'] = data.ramalyze.percent_outliers
dictOverall['_rama_outliers'] = data.ramalyze.as_gui_table_data()
dictOverall['_rama_headers'] = data.ramalyze.gui_list_headers
# Rotamer analysis
dictOverall['_percent_rota_outliers'] = data.rotalyze.percent_outliers
dictOverall['_rota_outliers'] = data.rotalyze.as_gui_table_data()
dictOverall['_rota_headers'] = data.rotalyze.gui_list_headers
# C-beta outliers
dictOverall['_n_cbeta_outliers'] = data.cbetadev.n_outliers
dictOverall['_cbeta_outliers'] = data.cbetadev.as_gui_table_data()
dictOverall['_cbeta_headers'] = data.cbetadev.gui_list_headers
# Backwards Asn/Gln/His sidechains
dictOverall['_n_nqh_flips_outliers'] = data.nqh_flips.n_outliers
dictOverall['_nqh_flips_outliers'] = data.nqh_flips.as_gui_table_data()
dictOverall['_nqh_flips_headers'] = data.nqh_flips.gui_list_headers
# Cis and Twisted peptides
dictOverall['_n_omega_outliers'] = data.omegalyze.n_outliers
dictOverall['_omega_outliers'] = data.omegalyze.as_gui_table_data()
dictOverall['_omega_headers'] = data.omegalyze.gui_list_headers
# RNA group
if data.rna is None:
dictOverall['_rna_group'] = False
else:
dictOverall['_rna_group'] = True
dictOverall['_n_bonds_rna_outliers'] = data.rna.bonds.n_outliers
dictOverall['_n_angles_rna_outliers'] = data.rna.angles.n_outliers
dictOverall['_n_puckers_rna_outliers'] = data.puckers.angles.n_outliers
dictOverall['_n_suites_rna_outliers'] = data.suites.angles.n_outliers
# Clashes
if data.clashes is None:
dictOverall['_clashes'] = False
else:
dictOverall['_clashes'] = True
dictOverall['_n_clashes_outliers'] = data.clashes.n_outliers
dictOverall['_clashes_outliers'] = data.clashes.as_gui_table_data()
dictOverall['_clashes_headers'] = data.clashes.gui_list_headers
# correlation coefficients
if data.real_space is None:
dictOverall['_overall_rsc'] = False
dictOverall['_fsc'] = False
else:
if data.real_space.overall_rsc is None:
dictOverall['_overall_rsc'] = False
else:
dictOverall['_overall_rsc'] = True
dictOverall['Mask CC'] = data.real_space.overall_rsc[0]
dictOverall['Volume CC'] = data.real_space.overall_rsc[1]
dictOverall['Peak CC'] = data.real_space.overall_rsc[2]
# real_space_correlation_coefficients table
dictOverall['_rs_protein'] = []
for i in range(len(data.real_space.protein)):
dictOverall['_rs_protein'].append(data.real_space.protein[
i].as_table_row_phenix())
dictOverall['_rs_other'] = []
for i in range(len(data.real_space.other)):
dictOverall['_rs_other'].append(data.real_space.other[
i].as_table_row_phenix())
dictOverall['_rs_water'] = []
for i in range(len(data.real_space.water)):
dictOverall['_rs_water'].append(data.real_space.water[
i].as_table_row_phenix())
dictOverall['_rs_everything'] = []
for i in range(len(data.real_space.everything)):
dictOverall['_rs_everything'].append(data.real_space.everything[
i].as_table_row_phenix())
dictOverall['_rs_headers'] = data.real_space.gui_list_headers
# fsc
if data.real_space.fsc is None:
dictOverall['_fsc'] = False
else:
dictOverall['_fsc'] = True
# atom mask radius
dictOverall['_atom_radius'] = data.real_space.fsc.atom_radius
# fsc graph data
x_elements = []
y_elements = []
for x in data.real_space.fsc.d_inv:
x_elements.append(x)
for y in data.real_space.fsc.fsc:
y_elements.append(y)
dictOverall['_x_fsc'] = x_elements
dictOverall['_y_fsc'] = y_elements
# occupancy and suspicious B-factors table
dictOverall['_occ_bf_outliers'] = data.model_stats.all.as_gui_table_data()
dictOverall['_occ_bf_headers'] = data.model_stats.all.gui_list_headers
# isotropic B (B-factors/ADPs)
dictOverall['_n_aniso_h'] = data.model_stats.all.n_aniso_h
dictOverall['_n_zero_b'] = data.model_stats.all.n_zero_b
dictOverall['_b_min'] = data.model_stats.all.b_min
dictOverall['_b_max'] = data.model_stats.all.b_max
dictOverall['_b_mean'] = data.model_stats.all.b_mean
if data.model_stats.macromolecules is not None:
dictOverall['_b_min_macromolecules'] = data.model_stats.macromolecules.b_min
dictOverall['_b_max_macromolecules'] = data.model_stats.macromolecules.b_max
dictOverall['_b_mean_macromolecules'] = data.model_stats.macromolecules.b_mean
if data.model_stats.ligands is not None:
dictOverall['_b_min_ligands'] = data.model_stats.ligands.b_min
dictOverall['_b_max_ligands'] = data.model_stats.ligands.b_max
dictOverall['_b_mean_ligands'] = data.model_stats.ligands.b_mean
""" % (self.MOLPROBITYPKLFILENAME, self.MOLPROBITYPKLFILENAME)
command += """with open('%s',"w") as f:
f.write(json.dumps(dictOverall))
""" % (ANALYSISTMPFILENAME)
pythonFileName = ANALYSISTMPFILENAME.replace('.txt', '.py')
# write script file
with open(pythonFileName, "w") as f:
f.write(command)
# execute file with phenix.python
Plugin.runPhenixProgram("", pythonFileName)
# read file in scipion python
with open(ANALYSISTMPFILENAME, "r") as f:
self.dictOverall = f.read()
# self.dataDict = json.loads(f.read())
self._store()
def _writeCommand(self, listName):
self.command ="""import pickle
def pickleData(file):
with open(file,"r") as f:
return pickle.load(f)
# process file %s"
data = pickleData('%s')
"""% (self.MOLPROBITYPKLFILENAME, self.MOLPROBITYPKLFILENAME)
if (listName == "Multi-criterion plot"):
self.command += """#RSC section
if data.real_space.overall_rsc is not None:
"""
else:
self.command += """# Protein group
if data.ramalyze is not None:
"""
self.command +="""
try :
import wxtbx.app
except ImportError, e :
raise Sorry("wxPython not available.")
else :
app = wxtbx.app.CCTBXApp(0)
"""
# TODO:
# Get appropriate functioning of data._multi_criterion.display_wx_plots()
if (listName == "Multi-criterion plot"):
self.command += """
# data._multi_criterion.display_wx_plots()
data.display_wx_plots()
"""
elif (listName == "Ramachandran plot"):
self.command += """
data.ramalyze.display_wx_plots()
"""
elif (listName == "Chi1-Chi2 plot"):
self.command += """
data.rotalyze.display_wx_plots()
"""
self.command +="""
app.MainLoop()
"""
def _computeOccBFactor(self, listL):
self.suspiciousBFList = []
self.occupancyList = []
if not listL:
pass
else:
for i in range(len(listL)):
if listL[i][2] == 1.:
self.suspiciousBFList.append(listL[i])
else:
self.occupancyList.append(listL[i])
def _computeCCTable(self):
decimal_index = int(self.ccIndex)
residueType_index = int(self.residueType)
self.RSCCList = []
listL = []
listName = self.residueTypeList[residueType_index]
if listName == self.residueTypeList[0]:
listL = self.dictOverall['_rs_protein']
elif listName == self.residueTypeList[1]:
listL = self.dictOverall['_rs_other']
elif listName == self.residueTypeList[2]:
listL = self.dictOverall['_rs_water']
elif listName == self.residueTypeList[3]:
listL = self.dictOverall['_rs_everything']
if not listL:
pass
else:
for i in range(len(listL)):
if listL[i][5] <= float(self.ccBelowList[decimal_index]):
self.RSCCList.append((str(listL[i][0]),
str(listL[i][1]),
str(listL[i][2]),
str(listL[i][3]),
str(listL[i][4]),
str(listL[i][5])))