Source code for schrodinger.test.stu.outcomes.compareDesmondSystems
"""script used to compare two desmond systems"""
from past.utils import old_div
from schrodinger.application.desmond.cms import get_box
from schrodinger.application.desmond.cms import get_boxvolume
from schrodinger.application.desmond.constants import CT_TYPE
from schrodinger.structure import MaestroReader as _MaestroReader
from schrodinger.structutils.rmsd import superimpose as _superimpose
[docs]class System(dict):
"""
A very basic class to hold cms data. Inherits the dict class to do most
of the heavy lifting.
"""
[docs] def __init__(self, fileName):
"""Initializes the class by loading the cts of the filename"""
self.name = fileName
for ct in _MaestroReader(fileName):
self[ct.property[CT_TYPE]] = ct
[docs] def getFFIOblock(self):
"""Gets a dictionary of ffio block values"""
def _findFFIOdiffs(self, other):
"""Returns a list of diffs between the ffio blocks of self and other"""
def _findCTdiffs(self, other, name):
"""
Returns a list of diffs between the named ct in self and other.
Only the solute CT has its positions compared. The other CTs use
comparisons of number of molecules.
"""
diffs = []
#Does this ct type exist in both?
if name not in self:
diffs.append(f"{name} missing from {self.name}")
if name not in other:
diffs.append(f"{name} missing from {other.name}")
#Compare box sizes
size1 = get_boxvolume(get_box(self[name]))
size2 = get_boxvolume(get_box(other[name]))
sizeDiff = abs(old_div((size1 - size2), size1))
if sizeDiff > 0.04:
diffs.append("Box size difference is %.1f%%" % (sizeDiff * 100))
#Compare number of molecules
nmol1 = self[name].mol_total
nmol2 = other[name].mol_total
if name == "solute":
if nmol1 != nmol2:
diffs.append(
"Different number of %s molecules: %s:%s and %s:%s" %
(name, self.name, nmol1, other.name, nmol2))
else:
diffs.extend(self._RMSDdiff(other, name))
elif abs(old_div(float(nmol1 - nmol2), nmol1)) > 0.05:
#Need to cast as float - int division always results in an int.
diffs.append("Different number of %s molecules: %s:%s and %s:%s" %
(name, self.name, nmol1, other.name, nmol2))
return diffs
def _RMSDdiff(self, other, name):
atoms = list(range(1, len(self[name].atom) + 1))
rmsd = _superimpose(self[name], atoms, other[name], atoms)
if rmsd > 1.04:
return ["RMSD above tolerance (RMSD = %s)" % rmsd]
else:
return []
[docs] def diff(self, other):
"""Returns a list of differences between self and other."""
diffs = []
for name in set(list(self.keys()) + list(other)):
diffs.extend(self._findCTdiffs(other, name))
return diffs
[docs]def compareDesmondSystems(filename1, filename2, log=None):
"""
Function used to compare two desmond systems. Takes as arguments
the file names of the two systems and an optional argument
-log=loglocation. If the log file location is provided,
differences are saved to file. Otherwise, they are printed to screen
"""
log = ""
try:
cms1 = System(filename1)
cms2 = System(filename2)
except:
msg = f"Problem reading files {filename1} and {filename2}"
raise AssertionError(msg)
diffs = cms1.diff(cms2)
if diffs:
if log:
file = open(log, "w")
file.write("The cms files are not identical")
for line in diffs:
file.write(line + "\n")
raise AssertionError("See diffs in %s" % log)
else:
msg = "The cms files are not identical:"
for line in diffs:
msg += "\n\t" + line
raise AssertionError(msg)
return True
if __name__ == "__main__":
from sys import argv
if compareDesmondSystems(argv[1:]):
print(" Same (pass)")
else:
print(" Difference (fail)")