Skip to content

Commit

Permalink
Remove code duplication in precision_rmsd. Fixes issue #11
Browse files Browse the repository at this point in the history
  • Loading branch information
shruthivis committed Jan 6, 2022
1 parent 1e6994b commit 80bfbf4
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 77 deletions.
10 changes: 2 additions & 8 deletions pyext/src/exhaust.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,16 +388,10 @@ def main():

# get superposition of each model to cluster center and the
# RMSD between the two
if args.symmetry_groups:
rmsd, superposed_ps, trans = \
precision_rmsd.get_particles_from_superposed_amb(
conforms[model_index], conform_0, args.align, ps,
trans, symm_groups)
else:
rmsd, superposed_ps, trans = \
rmsd, superposed_ps, trans = \
precision_rmsd.get_particles_from_superposed(
conforms[model_index], conform_0, args.align,
ps, trans)
ps, trans, symm_groups)

model.update() # why not?

Expand Down
84 changes: 15 additions & 69 deletions pyext/src/precision_rmsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,30 @@ def parse_custom_ranges(ranges_file):


def get_particles_from_superposed(
cluster_conform_i, cluster_conform_0, align, ps, trans):
cluster_conform_i, cluster_conform_0, align, ps, trans,
symm_groups=None):
def _to_vector3ds(numpy_array):
# No need to fit the whole array - we only need 4 non-coplanar points,
# so 100 should be plenty
return [IMP.algebra.Vector3D(c) for c in numpy_array[:100]]

if align:
calculator_name = "QCP_SERIAL_CALCULATOR"
else:
calculator_name = "NOSUP_SERIAL_CALCULATOR"

conforms = numpy.array([cluster_conform_0, cluster_conform_i])

if symm_groups is None:
calculator = pyRMSD.RMSDCalculator.RMSDCalculator(
"QCP_SERIAL_CALCULATOR",
numpy.array([cluster_conform_0, cluster_conform_i]))
calculator_name,
conforms)
else:
calculator = pyRMSD.RMSDCalculator.RMSDCalculator(
"NOSUP_SERIAL_CALCULATOR",
numpy.array([cluster_conform_0, cluster_conform_i]))
calculator_name,
fittingCoordsets=conforms,
calcSymmetryGroups=symm_groups,
fitSymmetryGroups=symm_groups)

rmsd, superposed_fit = calculator.pairwise(
0, 1, get_superposed_coordinates=True)
Expand All @@ -48,70 +58,6 @@ def _to_vector3ds(numpy_array):

return rmsd, ps, trans


def get_particles_from_superposed_amb(
cluster_conform_i, cluster_conform_0, align, ps, trans, symm_groups):

'''Modified superposed function to work with symmetric copies'''

def _to_vector3ds(numpy_array):
# No need to fit the whole array - we only need 4 non-coplanar points,
# so 100 should be plenty
return [IMP.algebra.Vector3D(c) for c in numpy_array[:100]]

min_rmsd = 10000.0

superposed_final_coords = []

for perm in pyRMSD.symmTools.symm_permutations(symm_groups):
# for each permutation

new_cluster_conform_i = cluster_conform_i

for sg in perm: # for each symmetric group in perm

for [particle0, particle1] in sg:
# swap the particles if they are in non-standard order
# in this permutation
if particle0 > particle1:
pyRMSD.symmTools.swap_atoms(
new_cluster_conform_i, particle0, particle1)

if align:
calculator = pyRMSD.RMSDCalculator.RMSDCalculator(
"QCP_SERIAL_CALCULATOR",
numpy.array([cluster_conform_0, new_cluster_conform_i]))
else:
calculator = pyRMSD.RMSDCalculator.RMSDCalculator(
"NOSUP_SERIAL_CALCULATOR",
numpy.array([cluster_conform_0, new_cluster_conform_i]))

rmsd, superposed_fit = calculator.pairwise(
0, 1, get_superposed_coordinates=True)

if rmsd < min_rmsd:
min_rmsd = rmsd
superposed_final_coords = superposed_fit

# Get transformation from pyRMSD reference on the first call.
# This is somewhat inefficient (since we are essentially repeating
# the pyRMSD calculation) but pyRMSD doesn't appear to make its
# reference orientation available.
if trans is None:
trans = IMP.algebra.get_transformation_aligning_first_to_second(
_to_vector3ds(superposed_final_coords[0]),
_to_vector3ds(cluster_conform_0))

for particle_index in range(len(superposed_final_coords[1])):

# Transform from pyRMSD back to original reference
IMP.core.XYZ(ps[particle_index]).set_coordinates(
trans * IMP.algebra.Vector3D(
superposed_final_coords[1][particle_index]))

return min_rmsd, ps, trans


class GetModelDensity(object):
"""Compute mean density maps from structures.
Keeps a dictionary of density maps,
Expand Down

0 comments on commit 80bfbf4

Please sign in to comment.