class SuperImposeAtomsCommand(MVCommand):

    def onAddCmdToViewer(self):
        self.rigidfitAligner = RigidfitBodyAligner()
        
    def doit(self, refAtoms, mobAtoms):
        """
        The SuperImposeAtomsCommand takes two set of Atoms of the same length
        compute the rotation and translation matrices to superimpose the
        mobAtoms onto the refAtoms using rigidFit module and then transform the
        corresponding geometry.
        """
        refCoords = refAtoms.coords
        mobCoords = mobAtoms.coords
        
        self.rigidfitAligner.setRefCoords(refCoords)

        # Nothing can be done if the two sets of coords are not of the same
        # size
        if not len(refCoords) == len(mobCoords):
            print " ERROR: Cannot perform the superimposition because the 2 \
            mv.lsets of Atoms are not of the same length"
            return

        # Get the rotation and the translation ysing mglutil.math.rigidFit
        self.rigidfitAligner.rigidFit(mobCoords)
        #rotation, translation= rigidFit.rigid_fit( refCoords, inCoords)
        rotMat =  Numeric.identity(4).astype('f')
        rotMat[:3,:3] = self.rigidfitAligner.rotationMatrix
        rotMat = Numeric.reshape(rotMat, (16,))
        transMat = Numeric.array(self.rigidfitAligner.translationMatrix)
        
        # transform the geometry representing the atoms only if a gui has been
        # created:
        if not self.vf.hasGui:
            return

        # Transform the mob geometry
        mobMol = mobAtoms.top.uniq()[0]
        mob = mobMol.geomContainer.masterGeom
        self.vf.transformObject('rotation', mob.fullName, matrix=tuple(rotMat))
        self.vf.transformObject('translation', mob.fullName, matrix=tuple(transMat))
        

    def __call__(self, refAtoms, mobAtoms, **kw):
        """
        None <- superimposeAtoms(refAtoms, mobAtoms, **kw)
        """
        if not kw.has_key('redraw'): kw['redraw'] = 1
        apply(self.doitWrapper, (refAtoms, mobAtoms), kw)
Ejemplo n.º 2
0
class SuperImposeAtomsCommand(MVCommand):

    def onAddCmdToViewer(self):
        self.rigidfitAligner = RigidfitBodyAligner()
        
    def doit(self, refAtoms, mobAtoms):
        """
        The SuperImposeAtomsCommand takes two set of Atoms of the same length
        compute the rotation and translation matrices to superimpose the
        mobAtoms onto the refAtoms using rigidFit module and then transform the
        corresponding geometry.
        """
        refCoords = refAtoms.coords
        mobCoords = mobAtoms.coords
        
        self.rigidfitAligner.setRefCoords(refCoords)

        # Nothing can be done if the two sets of coords are not of the same
        # size
        if not len(refCoords) == len(mobCoords):
            print " ERROR: Cannot perform the superimposition because the 2 \
            mv.lsets of Atoms are not of the same length"
            return

        # Get the rotation and the translation ysing mglutil.math.rigidFit
        self.rigidfitAligner.rigidFit(mobCoords)
        #rotation, translation= rigidFit.rigid_fit( refCoords, inCoords)
        rotMat =  Numeric.identity(4).astype('f')
        rotMat[:3,:3] = self.rigidfitAligner.rotationMatrix
        rotMat = Numeric.reshape(rotMat, (16,))
        transMat = Numeric.array(self.rigidfitAligner.translationMatrix)
        
        # transform the geometry representing the atoms only if a gui has been
        # created:
        #if not self.vf.hasGui:
        #    return

        # Transform the mob geometry
        mobMol = mobAtoms.top.uniq()[0]
        mob = mobMol.geomContainer.masterGeom
        self.vf.transformObject('rotation', mob.fullName, matrix=tuple(rotMat))
        self.vf.transformObject('translation', mob.fullName, matrix=tuple(transMat))
        

    def __call__(self, refAtoms, mobAtoms, **kw):
        """
        None <- superimposeAtoms(refAtoms, mobAtoms, **kw)
        """
        if not kw.has_key('redraw'): kw['redraw'] = 1
        apply(self.doitWrapper, (refAtoms, mobAtoms), kw)
Ejemplo n.º 3
0
def test_superimpose():
    from mglutil.math.rigidFit import RigidfitBodyAligner
    rigidfitAligner = RigidfitBodyAligner()
    refCoords = [[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]]
    mobCoords = [[10, 0, 0], [11, 0, 0], [10, 1, 0], [10, 0, 1]]
    rigidfitAligner.setRefCoords(refCoords)
    rigidfitAligner.rigidFit(mobCoords)
    rmsd = rigidfitAligner.rmsdAfterSuperimposition(mobCoords)
    assert diff(rmsd, 0.0)
Ejemplo n.º 4
0
def test_superimpose():
    from mglutil.math.rigidFit import RigidfitBodyAligner
    rigidfitAligner = RigidfitBodyAligner()
    refCoords=[[0,0,0] , [1,0,0], [0,1,0], [0,0,1]]
    mobCoords=[[10,0,0] , [11,0,0], [10,1,0], [10,0,1]]
    rigidfitAligner.setRefCoords(refCoords)                
    rigidfitAligner.rigidFit(mobCoords)
    rmsd=rigidfitAligner.rmsdAfterSuperimposition(mobCoords)
    assert diff(rmsd, 0.0 )
Ejemplo n.º 5
0
    def doit(self, refAtoms, mobAtoms, updateGeom=True, showRMSD=True):
        """
        The SuperImposeAtomsCommand takes two set of Atoms of the same length
        compute the rotation and translation matrices to superimpose the
        mobAtoms onto the refAtoms using rigidFit module and then transform the
        corresponding geometry.

        updateGeom = True : transform the masterGeom of mobAtoms.
        showRMSD   = True : print and return RMSD 
        """

        if refAtoms is None or mobAtoms is None: return
        assert isinstance(refAtoms, TreeNodeSet)
        assert isinstance(mobAtoms, TreeNodeSet)

        refAtoms = refAtoms.findType(Atom)
        mobAtoms = mobAtoms.findType(Atom)
        # validate the inputs
        if len(refAtoms) != len(mobAtoms):
            print "The two atomSet are not of equal length"
            return
        if len(refAtoms) < 3:
            print "At least three atoms are needed for superimposition"
            return

        refCoords = refAtoms.coords
        mobCoords = mobAtoms.coords

        rigidfitAligner = RigidfitBodyAligner()
        rigidfitAligner.setRefCoords(refCoords)
        rigidfitAligner.rigidFit(mobCoords)

        if updateGeom:
            rotMat = Numeric.identity(4).astype('d')
            rotMat[:3, :3] = rigidfitAligner.rotationMatrix
            transMat = Numeric.array(rigidfitAligner.translationMatrix)
            rotMat[3, :3] = transMat
            #print rotMat  # the matrix
            mGeom = mobAtoms[0].top.geomContainer.masterGeom
            mGeom.SetRotation(Numeric.reshape(rotMat, (16, )).astype('f'))
            mGeom.viewer.Redraw()

        if showRMSD:
            rmsd = rigidfitAligner.rmsdAfterSuperimposition(mobCoords)
            print "RMSD = ", rmsd
            return rmsd
        else:
            return
    def doit(self, refAtoms, mobAtoms, updateGeom=True, showRMSD=True):
        """
        The SuperImposeAtomsCommand takes two set of Atoms of the same length
        compute the rotation and translation matrices to superimpose the
        mobAtoms onto the refAtoms using rigidFit module and then transform the
        corresponding geometry.

        updateGeom = True : transform the masterGeom of mobAtoms.
        showRMSD   = True : print and return RMSD 
        """

        if refAtoms is None or mobAtoms is None: return
        assert isinstance(refAtoms, TreeNodeSet)
        assert isinstance(mobAtoms, TreeNodeSet)

        refAtoms = refAtoms.findType(Atom)
        mobAtoms = mobAtoms.findType(Atom)
        # validate the inputs
        if len(refAtoms) !=len(mobAtoms):
            print "The two atomSet are not of equal length"
            return
        if len(refAtoms) < 3 :
            print "At least three atoms are needed for superimposition"
            return
        
        refCoords = refAtoms.coords
        mobCoords = mobAtoms.coords
        
        rigidfitAligner = RigidfitBodyAligner()
        rigidfitAligner.setRefCoords(refCoords)                
        rigidfitAligner.rigidFit(mobCoords)

        if updateGeom:
            rotMat =  Numeric.identity(4).astype('d')
            rotMat[:3,:3] = rigidfitAligner.rotationMatrix               
            transMat = Numeric.array(rigidfitAligner.translationMatrix)
            rotMat[3,:3] = transMat
            #print rotMat  # the matrix
            mGeom = mobAtoms[0].top.geomContainer.masterGeom        
            mGeom.SetRotation(Numeric.reshape(rotMat, (16,)).astype('f'))
            mGeom.viewer.Redraw()

        if showRMSD:
            rmsd=rigidfitAligner.rmsdAfterSuperimposition(mobCoords)
            print "RMSD = ", rmsd
            return rmsd
        else:
            return
 def onAddCmdToViewer(self):
     self.rigidfitAligner = RigidfitBodyAligner()
class SuperimposeAtomsCommand(MVCommand):

    def onAddCmdToViewer(self):
        self.rigidfitAligner = RigidfitBodyAligner()
        
    def doit(self, refAtoms, mobAtoms):
        """
        The SuperImposeAtomsCommand takes two set of Atoms of the same length
        compute the rotation and translation matrices to superimpose the
        mobAtoms onto the refAtoms using rigidFit module and then transform the
        corresponding geometry.
        """

        refCoords = refAtoms.coords
        mobCoords = mobAtoms.coords
        
        self.rigidfitAligner.setRefCoords(refCoords)

        # Nothing can be done if the two sets of coords are not of the same
        # size
        if not len(refCoords) == len(mobCoords):
            print " ERROR: Cannot perform the superimposition because the 2 \
            mv.lsets of Atoms are not of the same length"
            return

        # Get the rotation and the translation ysing mglutil.math.rigidFit
        self.rigidfitAligner.rigidFit(mobCoords)
        #rotation, translation= rigidFit.rigid_fit( refCoords, inCoords)
        rotMat =  Numeric.identity(4).astype('d')
        rotMat[:3,:3] = self.rigidfitAligner.rotationMatrix
               
        transMat = Numeric.array(self.rigidfitAligner.translationMatrix)
        
        # transform the geometry representing the atoms only if a gui has been
        # created:
        if not self.vf.hasGui:
            return

        # build the geometry name:
        mobMol = mobAtoms.top.uniq()[0]
        mob = mobMol.geomContainer.masterGeom
        #gName = 'root|'+ mobMol[0].name
        vi = self.vf.GUI.VIEWER
        
        oldCurrent = vi.currentObject
        vi.SetCurrentObject(mob)
        
        # transform only the given geometry.
        if vi.redirectTransformToRoot == 1:
            old = vi.redirectTransformToRoot
            vi.TransformRootOnly(0)
        else:
            old = 0

        
        # apply the rotation to the masterGeom of the inMol
        mob.SetRotation(Numeric.reshape(rotMat, (16,)))
        # apply the translation to the masterGeom of the inMol
        mob.SetTranslation(transMat)


##         refMol = refAtoms.top.uniq()[0]
##         refmg = refMol.geomContainer.masterGeom
        
##         refmg = refAtoms.top.uniq()[0].geomContainer.masterGeom
##         mat = refmg.GetMatrix(refmg)
##         tmat = Numeric.transpose(mat)
        
##         rot, trans, scale = refmg.Decompose4x4(Numeric.reshape(tmat, (16,)))
##         rot_1 = refmg.rotation
##         trans_1 = refmg.translation
##         print 'rot',rot
##         print 'trans',trans
##         print 'rot_1',rot_1
##         print 'trans_1',trans_1
        
##         mobPivot = list(mob.pivot)
##         mobPivot.append(1.)
##         transfo = Numeric.identity(4).astype('d')
##         transfo[:3,:3] = rotMat[:3,:3]
##         transfo[3, :3] = transMat
##         hc = Numeric.array(mobPivot)
##         tPivot = Numeric.dot(hc, transfo)
##         print tPivot[:3]
##         mob.SetPivot(tPivot[:3])
        
        #self.vf.centerOnNodes(refMol)
        #mob.ConcatRotationRelative(Numeric.reshape(rot, (16,)))
        #mob.ConcatTranslation(trans_1)
        
        if old == 1:
            vi.TransformRootOnly(1)
        vi.SetCurrentObject(oldCurrent)

        # Not sure to put that here ?
        # Need to concatenate with the transformation of the reference molecule
        # to have the two molecule aligned:
        # - Get the transformatiom matrix of the ref molecule and decompose it
        
##         refmg = refAtoms.top.uniq()[0].geomContainer.masterGeom
##         mat = refmg.GetMatrix(refmg)
##         tmat = Numeric.transpose(mat)
        
##         rot, trans, scale = refmg.Decompose4x4(Numeric.reshape(tmat, (16,)))
        
##         self.vf.transformObject('rot', gName, rot)
##         self.vf.transformObject('tra', gName, trans)
##         #self.vf.transformObject('sca', gName, scale)
        

    def __call__(self, refAtoms, mobAtoms, **kw):
        """
        None <- superimposeAtoms(refAtoms, mobAtoms, **kw)
        """
        if not kw.has_key('redraw'): kw['redraw'] = 1
        apply(self.doitWrapper, (refAtoms, mobAtoms), kw)
    ref_ats = AtomSet()
    ref_indices = list(map(int, ref_ll.split(',')))
    num_ref_indices = len(ref_indices)
    if num_ref_indices < 3:
        print(" At least 3 indices are required! only %d indices found!!!" %
              (num_ref_indices))
        exit()
    for i in ref_indices:
        #ref_ats.append(ref_mol.allAtoms[i-1])
        ref_ats.append(ref_mol.allAtoms.get(lambda x: x.number == i)[0])

    num_ref_ats = len(ref_ats)

    #setup the tool for the rigid fit
    from mglutil.math.rigidFit import RigidfitBodyAligner
    RFA = RigidfitBodyAligner()
    RFA.setRefCoords(ref_ats.coords)

    #transform the rest of the molecules
    for l in lines[1:]:
        name, ll = l.split()
        ll.strip()
        moving_mol = Read(name)[0]
        indices = list(map(int, ll.split(',')))
        moving_ats = AtomSet()
        for i in indices:
            new_atoms = moving_mol.allAtoms.get(lambda x: x.number == i)
            if not len(new_atoms):
                print("There is no atom in %s with number %d" % (name, i))
                break
            else:
     lines = fptr.readlines()
     fptr.close()
     for l in lines:
         #handle blank lines gracefully
         l = l.strip()
         if len(l):
             first, second = list(map(int, l.split('-')))
             moblist.append((first, second))
     if verbose: print("moblist=", moblist)
 else:
     moblist = reflist[:]
 #refMol.chains.residues.atoms       # all levels of hierarchical data structure
 #refMol.allAtoms                    # short cut to lowest level....
 #mobMol.allAtoms                    #each atom has 'coords' attribute
 from mglutil.math.rigidFit import RigidfitBodyAligner
 rigidfitAligner = RigidfitBodyAligner()
 if string_for_atoms_to_use is None:
     string_for_atoms_to_use = "N_CA_C"
 names_to_use = string_for_atoms_to_use.split('_')
 refAtoms = get_atoms(refMol, reflist, names_to_use, verbose)
 refCoords = refAtoms.coords  #or refMol.chains.residues.atoms.get('backbone').coords
 #check that there are some
 if len(refCoords) == 0:
     print("NO REF COORDS!!!")
     raise Exception(
         'Unable to superimpose because no reference coordinates were specified!!!'
     )
 mobAtoms = get_atoms(mobMol, moblist, names_to_use, verbose)
 mobCoords = mobAtoms.coords
 if len(mobCoords) == 0:
     print("NO MOB COORDS!!!")
            atom_to_attach = otherAt
            if verbose: print "found bond_to_break in receptor => %s" %(b.atom1.name +':'+ b.atom2.name)
            # break the bond
            if verbose: print "receptor atom for ligand attachment in residue %s is %s" %(resP.full_name(),otherAt.full_name())
            otherAt.bonds.remove(b)
            rat3.bonds.remove(b)
            if verbose: print "removed %s-%s bond from %s and from %s"%(b.atom1.name, b.atom2.name, otherAt.full_name(), rat3.full_name())
    if bond_to_break is None:
        print "unable to locate the bond to break in receptor residue %s: expected a bond from %s to an atom other than %s"%(resP.full_name(), rat3.name, rat2.name)
        raise 'invalid input'

    #setup for the superposition
    ref_coords = ref_atoms.coords 
    lig_coords = lig_atoms.coords
    #(1) create the tool
    rigidfitAligner = RigidfitBodyAligner()
    rigidfitAligner.setRefCoords(ref_coords)
    rigidfitAligner.rigidFit(lig_coords)
    #(2) get new coordinates for the moving atoms
    #    here all the ligand atoms move
    new_coords = rigidfitAligner.transformCoords(lM.allAtoms.coords)
    # get the correct shape for the coords (natoms,3)
    #new_coords.shape
    #(25, 4)
    new_coords=new_coords[:,:3] 
    #(3) add the new to ligand
    lM.allAtoms.addConformation(new_coords)
    confNum = len(lM.allAtoms[0]._coords)-1
    #(4) set the coordinates to use to the new ones 
    lM.allAtoms.setConformation(confNum)
    if verbose: print "new coordinates added to ligand"
Ejemplo n.º 12
0
    ref_mol = Read(ref_name)[0]
    ref_ats = AtomSet()
    ref_indices = map(int, ref_ll.split(','))
    num_ref_indices = len(ref_indices)
    if num_ref_indices<3: 
        print " At least 3 indices are required! only %d indices found!!!"%(num_ref_indices)
        exit()
    for i in ref_indices:
        #ref_ats.append(ref_mol.allAtoms[i-1])
        ref_ats.append(ref_mol.allAtoms.get(lambda x: x.number==i)[0])

    num_ref_ats = len(ref_ats)

    #setup the tool for the rigid fit
    from mglutil.math.rigidFit import RigidfitBodyAligner
    RFA = RigidfitBodyAligner()
    RFA.setRefCoords(ref_ats.coords)

    #transform the rest of the molecules
    for l in lines[1:]:
        name, ll = l.split() 
        ll.strip()
        moving_mol = Read(name)[0]
        indices = map(int, ll.split(','))
        moving_ats = AtomSet()
        for i in indices: 
            new_atoms = moving_mol.allAtoms.get(lambda x: x.number==i)
            if not len(new_atoms):
                print "There is no atom in %s with number %d" %(name, i)
                break
            else:
Ejemplo n.º 13
0
 def onAddCmdToViewer(self):
     self.rigidfitAligner = RigidfitBodyAligner()
Ejemplo n.º 14
0
class SuperimposeAtomsCommand(MVCommand):
    def onAddCmdToViewer(self):
        self.rigidfitAligner = RigidfitBodyAligner()

    def doit(self, refAtoms, mobAtoms):
        """
        The SuperImposeAtomsCommand takes two set of Atoms of the same length
        compute the rotation and translation matrices to superimpose the
        mobAtoms onto the refAtoms using rigidFit module and then transform the
        corresponding geometry.
        """

        refCoords = refAtoms.coords
        mobCoords = mobAtoms.coords

        self.rigidfitAligner.setRefCoords(refCoords)

        # Nothing can be done if the two sets of coords are not of the same
        # size
        if not len(refCoords) == len(mobCoords):
            print " ERROR: Cannot perform the superimposition because the 2 \
            mv.lsets of Atoms are not of the same length"

            return

        # Get the rotation and the translation ysing mglutil.math.rigidFit
        self.rigidfitAligner.rigidFit(mobCoords)
        #rotation, translation= rigidFit.rigid_fit( refCoords, inCoords)
        rotMat = Numeric.identity(4).astype('d')
        rotMat[:3, :3] = self.rigidfitAligner.rotationMatrix

        transMat = Numeric.array(self.rigidfitAligner.translationMatrix)

        # transform the geometry representing the atoms only if a gui has been
        # created:
        #if not self.vf.hasGui:
        #    return

        # build the geometry name:
        mobMol = mobAtoms.top.uniq()[0]
        mob = mobMol.geomContainer.masterGeom
        #gName = 'root|'+ mobMol[0].name
        if not self.vf.hasGui:
            vi = self.vf.GUI.VIEWER
            oldCurrent = vi.currentObject
            vi.SetCurrentObject(mob)

            # transform only the given geometry.
            if vi.redirectTransformToRoot == 1:
                old = vi.redirectTransformToRoot
                vi.TransformRootOnly(0)
            else:
                old = 0

        # apply the rotation to the masterGeom of the inMol
        mob.SetRotation(Numeric.reshape(rotMat, (16, )))
        # apply the translation to the masterGeom of the inMol
        mob.SetTranslation(transMat)

        ##         refMol = refAtoms.top.uniq()[0]
        ##         refmg = refMol.geomContainer.masterGeom

        ##         refmg = refAtoms.top.uniq()[0].geomContainer.masterGeom
        ##         mat = refmg.GetMatrix(refmg)
        ##         tmat = Numeric.transpose(mat)

        ##         rot, trans, scale = refmg.Decompose4x4(Numeric.reshape(tmat, (16,)))
        ##         rot_1 = refmg.rotation
        ##         trans_1 = refmg.translation
        ##         print 'rot',rot
        ##         print 'trans',trans
        ##         print 'rot_1',rot_1
        ##         print 'trans_1',trans_1

        ##         mobPivot = list(mob.pivot)
        ##         mobPivot.append(1.)
        ##         transfo = Numeric.identity(4).astype('d')
        ##         transfo[:3,:3] = rotMat[:3,:3]
        ##         transfo[3, :3] = transMat
        ##         hc = Numeric.array(mobPivot)
        ##         tPivot = Numeric.dot(hc, transfo)
        ##         print tPivot[:3]
        ##         mob.SetPivot(tPivot[:3])

        #self.vf.centerOnNodes(refMol)
        #mob.ConcatRotationRelative(Numeric.reshape(rot, (16,)))
        #mob.ConcatTranslation(trans_1)

        if not self.vf.hasGui:
            if old == 1:
                vi.TransformRootOnly(1)
            vi.SetCurrentObject(oldCurrent)

        # Not sure to put that here ?
        # Need to concatenate with the transformation of the reference molecule
        # to have the two molecule aligned:
        # - Get the transformatiom matrix of the ref molecule and decompose it

##         refmg = refAtoms.top.uniq()[0].geomContainer.masterGeom
##         mat = refmg.GetMatrix(refmg)
##         tmat = Numeric.transpose(mat)

##         rot, trans, scale = refmg.Decompose4x4(Numeric.reshape(tmat, (16,)))

##         self.vf.transformObject('rot', gName, rot)
##         self.vf.transformObject('tra', gName, trans)
##         #self.vf.transformObject('sca', gName, scale)

    def __call__(self, refAtoms, mobAtoms, **kw):
        """
        None <- superimposeAtoms(refAtoms, mobAtoms, **kw)
        """
        if not kw.has_key('redraw'): kw['redraw'] = 1
        apply(self.doitWrapper, (refAtoms, mobAtoms), kw)
     lines = fptr.readlines()
     fptr.close()
     for l in lines:
         #handle blank lines gracefully
         l = l.strip()
         if len(l):
             first,second  = map(int, l.split('-'))
             moblist.append((first,second))
     if verbose: print "moblist=", moblist
 else:
     moblist = reflist[:]
 #refMol.chains.residues.atoms       # all levels of hierarchical data structure
 #refMol.allAtoms                    # short cut to lowest level....
 #mobMol.allAtoms                    #each atom has 'coords' attribute
 from mglutil.math.rigidFit import RigidfitBodyAligner
 rigidfitAligner = RigidfitBodyAligner()
 if  string_for_atoms_to_use is None:
     string_for_atoms_to_use = "N_CA_C"
 names_to_use = string_for_atoms_to_use.split('_')
 refAtoms = get_atoms(refMol, reflist, names_to_use, verbose)
 refCoords = refAtoms.coords #or refMol.chains.residues.atoms.get('backbone').coords
 #check that there are some
 if len(refCoords)==0:
     print "NO REF COORDS!!!"
     raise 'Unable to superimpose because no reference coordinates were specified!!!' 
 mobAtoms = get_atoms(mobMol, moblist, names_to_use, verbose)
 mobCoords = mobAtoms.coords
 if len(mobCoords)==0:
     print "NO MOB COORDS!!!"
     raise 'Unable to superimpose because no mobile coordinates were specified!!!' 
 #check that moblist and reflist are of the same length    
            otherAt.bonds.remove(b)
            rat3.bonds.remove(b)
            if verbose:
                print "removed %s-%s bond from %s and from %s" % (
                    b.atom1.name, b.atom2.name, otherAt.full_name(),
                    rat3.full_name())
    if bond_to_break is None:
        print "unable to locate the bond to break in receptor residue %s: expected a bond from %s to an atom other than %s" % (
            resP.full_name(), rat3.name, rat2.name)
        raise 'invalid input'

    #setup for the superposition
    ref_coords = ref_atoms.coords
    lig_coords = lig_atoms.coords
    #(1) create the tool
    rigidfitAligner = RigidfitBodyAligner()
    rigidfitAligner.setRefCoords(ref_coords)
    rigidfitAligner.rigidFit(lig_coords)
    #(2) get new coordinates for the moving atoms
    #    here all the ligand atoms move
    new_coords = rigidfitAligner.transformCoords(lM.allAtoms.coords)
    # get the correct shape for the coords (natoms,3)
    #new_coords.shape
    #(25, 4)
    new_coords = new_coords[:, :3]
    #(3) add the new to ligand
    lM.allAtoms.addConformation(new_coords)
    confNum = len(lM.allAtoms[0]._coords) - 1
    #(4) set the coordinates to use to the new ones
    lM.allAtoms.setConformation(confNum)
    if verbose: print "new coordinates added to ligand"