def test_relative_position_mover(self, ): """ Test the RelativePositionMover """ log.info("test RelativePositionMover") fn_rec1 = self.get_input_file_name("1suvA_xlinked.pdb") fn_rec2 = self.get_input_file_name("1suvC_xlinked.pdb") fn_lig = self.get_input_file_name("1suvE_xlinked.pdb") fn_tr1 = \ self.get_input_file_name("transforms-1suvA-1suvE_reduced.txt") fn_tr2 = \ self.get_input_file_name("transforms-1suvC-1suvE_filtered.txt") m = IMP.kernel.Model() sel = atom.ATOMPDBSelector() h_rec1 = atom.read_pdb(fn_rec1, m, sel) rb_rec1 = atom.create_rigid_body(h_rec1) rec1_coords = [core.XYZ(l).get_coordinates() for l in atom.get_leaves(h_rec1)] h_rec2 = atom.read_pdb(fn_rec2, m, sel) rb_rec2 = atom.create_rigid_body(h_rec2) rec2_coords = [core.XYZ(l).get_coordinates() for l in atom.get_leaves(h_rec2)] h_ligand = atom.read_pdb(fn_lig, m, sel) rb_lig = atom.create_rigid_body(h_ligand) Ts = get_relative_transforms(fn_tr1) Tis1 = [] for i, T in enumerate(Ts): V = get_internal_transform3(T, rb_rec1, rb_lig) Tis1.append(V) docked_refs1 = get_docked_reference_frames(Ts, rb_lig) Ts = get_relative_transforms(fn_tr2) Tis2 = [] for i, T in enumerate(Ts): V = get_internal_transform3(T, rb_rec2, rb_lig) Tis2.append(V) docked_refs2 = get_docked_reference_frames(Ts, rb_lig) mv = em2d.RelativePositionMover(rb_lig, 10, 20) mv.add_internal_transformations(rb_rec1, Tis1) mv.add_internal_transformations(rb_rec2, Tis2) for i in range(2): # prob_random = 0 ref_before = rb_lig.get_reference_frame() ps = mv.propose() # _move(prob_random) ref_after = rb_lig.get_reference_frame() found = False current_coords = [core.XYZ(l).get_coordinates() for l in atom.get_leaves(h_ligand)] # check all possible reference frames where the ligand could be for r in itertools.chain(docked_refs1, docked_refs2): rb_lig.set_reference_frame(r) docked_coords = [core.XYZ(l).get_coordinates() for l in atom.get_leaves(h_ligand)] rmsd = alg.get_rmsd(current_coords, docked_coords) if rmsd < 0.1: found = True self.assertTrue(found, msg="the proposed move is not " "in the relative solutions") mv.accept()
def test_rigid_body_image_fit_restraint(self): """Test scoring with RigidBodiesImageFitRestraint""" m = IMP.Model() # read full complex fn = self.get_input_file_name("1z5s.pdb") prot = atom.read_pdb(fn, m, IMP.atom.ATOMPDBSelector()) # read components names = ["1z5sA", "1z5sB", "1z5sC", "1z5sD"] fn_pdbs = [self.get_input_file_name(name + ".pdb") for name in names] components = [atom.read_pdb(fn, m, IMP.atom.ATOMPDBSelector()) for fn in fn_pdbs] components_rbs = [atom.create_rigid_body(c) for c in components] # img R = alg.get_identity_rotation_3d() reg = em2d.RegistrationResult(R) img = em2d.Image() img.set_size(80, 80) srw = em2d.SpiderImageReaderWriter() resolution = 5 pixel_size = 1.5 options = em2d.ProjectingOptions(pixel_size, resolution) ls = core.get_leaves(prot) em2d.get_projection(img, ls, reg, options) # img.write("rbfit_test_image.spi",srw) # set restraint score_function = em2d.EM2DScore() rb_fit = em2d.RigidBodiesImageFitRestraint(score_function, components_rbs, img) pp = em2d.ProjectingParameters(pixel_size, resolution) rb_fit.set_projecting_parameters(pp) # set the trivial case: n_masks = 1 for rb in components_rbs: # set as the only possible orientation the one that the rigid # body already has rb_fit.set_orientations(rb, [rb.get_reference_frame().get_transformation_to().get_rotation()]) self.assertEqual(rb_fit.get_number_of_masks(rb), n_masks, "Incorrect number rigid body masks") # Calculate the positions of the rigid bodies respect to the centroid # of the entire molecule ls = core.get_leaves(prot) xyzs = core.XYZs(ls) centroid = core.get_centroid(xyzs) coords = [rb.get_coordinates() - centroid for rb in components_rbs] for rb, coord in zip(components_rbs, coords): rb.set_coordinates(coord) # Check that the value is a perfect registration score = rb_fit.evaluate(False) # print "score ...", score # It seems that projecting with the masks is slightly less accurate # I have to establish a tolerance of 0.03 self.assertAlmostEqual(score, 0, delta=0.03, msg="Wrong value for the score %f " % (score))
def create_simplified_assembly(assembly, components_rbs, n_res): """ Simplifies an assembly, by creating a hierarchy with one ball per n_res residues. Each of the chains in the new hierarchy are added to the rigid bodies for each of the components. There must be correspondence between the children of the assembly (components) and the rigid bodies. I check for the ids. """ molecule = assembly.get_as_molecule() if (not molecule.get_is_valid(True)): raise TypeError("The argument is not a valid hierarchy") model = assembly.get_model() n_children = molecule.get_number_of_children() sh = IMP.kernel.Particle(model) simplified_hierarchy = atom.Molecule.setup_particle(sh) for i in range(n_children): # for all members of the assembly component = molecule.get_child(i) name = component.get_name() rb = components_rbs[i] if (rb.get_name() != get_rb_name(name)): raise ValueError("Rigid body and component do not match") hchains = atom.get_by_type(component, atom.CHAIN_TYPE) ch = IMP.kernel.Particle(model) coarse_component_h = atom.Molecule.setup_particle(ch) # simplify all the chains in the member for h in hchains: chain = atom.Chain(h.get_particle()) coarse_h = None if (name == "DNA"): # print "simplifying DNA" coarse_h_particle = create_simplified_dna(h, n_res) coarse_h = atom.Hierarchy(coarse_h_particle) else: coarse_h = atom.create_simplified_along_backbone(chain, n_res) # does not work for DNA chain_rb = atom.create_rigid_body(coarse_h) # chain_rb = atom.setup_as_rigid_body(coarse_h) # works with DNA chain_rb.set_name("sub_rb" + name) rb.add_member(chain_rb) # are required to have excluded volume coarse_component_h.add_child(atom.Chain(coarse_h)) coarse_component_h.set_name(name) simplified_hierarchy.add_child(coarse_component_h) return simplified_hierarchy
def create_simplified_assembly(assembly, components_rbs, n_res): """ Simplifies an assembly, by creating a hierarchy with one ball per n_res residues. Each of the chains in the new hierarchy are added to the rigid bodies for each of the components. There must be correspondence between the children of the assembly (components) and the rigid bodies. I check for the ids. """ molecule = assembly.get_as_molecule() if(not molecule.get_is_valid(True)): raise TypeError("The argument is not a valid hierarchy") model = assembly.get_model() n_children = molecule.get_number_of_children() sh = IMP.Particle(model) simplified_hierarchy = atom.Molecule.setup_particle(sh) for i in range(n_children): # for all members of the assembly component = molecule.get_child(i) name = component.get_name() rb = components_rbs[i] if(rb.get_name() != get_rb_name(name)): raise ValueError("Rigid body and component do not match") hchains = atom.get_by_type(component, atom.CHAIN_TYPE) ch = IMP.Particle(model) coarse_component_h = atom.Molecule.setup_particle(ch) # simplify all the chains in the member for h in hchains: chain = atom.Chain(h.get_particle()) coarse_h = None if(name == "DNA"): # print "simplifying DNA" coarse_h_particle = create_simplified_dna(h, n_res) coarse_h = atom.Hierarchy(coarse_h_particle) else: coarse_h = atom.create_simplified_along_backbone(chain, n_res) # does not work for DNA chain_rb = atom.create_rigid_body(coarse_h) # chain_rb = atom.setup_as_rigid_body(coarse_h) # works with DNA chain_rb.set_name("sub_rb" + name) rb.add_member(chain_rb) # are required to have excluded volume coarse_component_h.add_child(atom.Chain(coarse_h)) coarse_component_h.set_name(name) simplified_hierarchy.add_child(coarse_component_h) return simplified_hierarchy
def test_filter_transformations(self): """ Check if the filtered conformation are the conformations that I computed before """ try: import subprocess import IMP.EMageFit.buildxlinks as bx except ImportError as e: self.skipTest(str(e)) dock = self.import_python_application('emagefit_dock') sel = atom.NonWaterNonHydrogenPDBSelector() ligand = IMP.Model() fn_ligand = self.get_input_file_name("3sfdB-3sfdA_initial_docking.pdb") h_ligand = atom.read_pdb(fn_ligand, ligand, sel) rb_ligand = atom.create_rigid_body(h_ligand) receptor = IMP.Model() fn_receptor = self.get_input_file_name("3sfdB.pdb") h_receptor = atom.read_pdb(fn_receptor, receptor, sel) # read_hex_transformations fn = self.get_input_file_name("hex_solutions_3sfdB-3sfdA.txt") residue_receptor = 23 residue_ligand = 456 distance = 30 xl = bx.Xlink("3sfdB", "B", residue_receptor, "3sfdA", "A", residue_ligand, distance) xlinks_list = [xl] fn_filtered = "filtered_transforms.txt" dock.filter_docking_results(h_receptor, h_ligand, xlinks_list, fn, fn_filtered) fn_stored = self.get_input_file_name( "hex_solutions_3sfdB-3sfdA_filtered.txt") filtered = dock.read_hex_transforms(fn_filtered) stored = dock.read_hex_transforms(fn_stored) # check that the filtered transforms match the stored ones self.assertEqual(len(filtered), len(stored)) for Tf, Ts in zip(filtered, stored): tf = Tf.get_translation() ts = Ts.get_translation() qf = Tf.get_rotation().get_quaternion() qs = Ts.get_rotation().get_quaternion() for k in range(3): self.assertAlmostEqual(tf[k], ts[k]) for k in range(4): self.assertAlmostEqual(qf[k], qs[k]) os.remove(fn_filtered)
def test_filter_transformations(self): """ Check if the filtered conformation are the conformations that I computed before """ try: import subprocess import IMP.em2d.buildxlinks as bx except ImportError as e: self.skipTest(str(e)) dock = self.import_python_application('emagefit_dock') sel = atom.NonWaterNonHydrogenPDBSelector() ligand = IMP.kernel.Model() fn_ligand = self.get_input_file_name("3sfdB-3sfdA_initial_docking.pdb") h_ligand = atom.read_pdb(fn_ligand, ligand, sel) rb_ligand = atom.create_rigid_body(h_ligand) receptor = IMP.kernel.Model() fn_receptor = self.get_input_file_name("3sfdB.pdb") h_receptor = atom.read_pdb(fn_receptor, receptor, sel) # read_hex_transformations fn = self.get_input_file_name("hex_solutions_3sfdB-3sfdA.txt") residue_receptor = 23 residue_ligand = 456 distance = 30 xl = bx.Xlink("3sfdB", "B", residue_receptor, "3sfdA", "A", residue_ligand, distance) xlinks_list = [xl] fn_filtered = "filtered_transforms.txt" dock.filter_docking_results(h_receptor, h_ligand, xlinks_list, fn, fn_filtered) fn_stored = self.get_input_file_name( "hex_solutions_3sfdB-3sfdA_filtered.txt") filtered = dock.read_hex_transforms(fn_filtered) stored = dock.read_hex_transforms(fn_stored) # check that the filtered transforms match the stored ones self.assertEqual(len(filtered), len(stored)) for Tf, Ts in zip(filtered, stored): tf = Tf.get_translation() ts = Ts.get_translation() qf = Tf.get_rotation().get_quaternion() qs = Ts.get_rotation().get_quaternion() for k in range(3): self.assertAlmostEqual(tf[k], ts[k]) for k in range(4): self.assertAlmostEqual(qf[k], qs[k]) os.remove(fn_filtered)
def create_dockings_from_xlinks(exp): """ Perform dockings that satisfy the cross-linking restraints. 1) Based on the number of restraints, creates an order for the docking between pairs of subunits, favouring the subunits with more crosslinks to be the "receptors" 2) Moves the subunits that are going to be docked to a position that satisfies the x-linking restraints. There is no guarantee that this position is correct. Its purpose is to help the docking algorithm with a clue of the proximity/orientation between subunits 3) Performs docking between the subunits 4) Filters the results of the docking that are not consistent with the cross-linking restraints 5) Computes the relative transformations between the rigid bodies of the subunits that have been docked @param exp Class with the parameters for the experiment """ log.info("Creating initial assembly from xlinks and docking") import docking_related as dock import buildxlinks as bx m = DominoModel.DominoModel() m.set_assembly_components(exp.fn_pdbs, exp.names) set_xlink_restraints(exp, m) order = bx.DockOrder() order.set_xlinks(m.xlinks) docking_pairs = order.get_docking_order() if hasattr(exp, "have_hexdock"): if not exp.have_hexdock: return for rec, lig in docking_pairs: pair_xlinks = m.xlinks.get_xlinks_for_pair((rec,lig)) log.debug("Xlinks for the pair %s %s %s",rec, lig, pair_xlinks) h_receptor = representation.get_component(m.assembly, rec) h_ligand = representation.get_component(m.assembly, lig) rb_receptor = representation.get_rigid_body(m.components_rbs, representation.get_rb_name(rec)) rb_ligand = representation.get_rigid_body(m.components_rbs, representation.get_rb_name(lig)) initial_ref = rb_ligand.get_reference_frame() # move to the initial docking position mv = bx.InitialDockingFromXlinks() mv.set_xlinks(pair_xlinks) mv.set_hierarchies(h_receptor, h_ligand) mv.set_rigid_bodies(rb_receptor, rb_ligand) mv.move_ligand() fn_initial_docking = "%s-%s_initial_docking.pdb" % (rec,lig) mv.write_ligand(fn_initial_docking) # dock hex_docking = dock.HexDocking() receptor_index = exp.names.index(rec) fn_transforms = "hex_solutions_%s-%s.txt" % (rec, lig) fn_docked = "%s-%s_hexdock.pdb" % (rec, lig) hex_docking.dock(exp.fn_pdbs[receptor_index], fn_initial_docking, fn_transforms, fn_docked, False) sel = atom.ATOMPDBSelector() new_m = IMP.Model() # After reading the file with the initial solution, the reference frame # for the rigid body of the ligand is not necessarily the same one # that it had when saved. # Thus reading the file again ensures consisten results when # using the HEXDOCK transforms new_h_ligand = atom.read_pdb(fn_initial_docking, new_m, sel) new_rb_ligand = atom.create_rigid_body(new_h_ligand) Tlig = new_rb_ligand.get_reference_frame().get_transformation_to() fn_filtered = "hex_solutions_%s-%s_filtered.txt" % (rec, lig) # h_ligand contains the coordinates of the ligand after moving it # to the initial position for the docking dock.filter_docking_results(h_receptor, new_h_ligand, pair_xlinks, fn_transforms, fn_filtered) # transforms to apply to the ligand as it is in the file # fn_initial_docking Thex = dock.read_hex_transforms(fn_filtered) Trec = rb_receptor.get_reference_frame().get_transformation_to() Tinternal = [] for i,T in enumerate(Thex): Tdock = alg.compose(T, Tlig) ref = alg.ReferenceFrame3D(Tdock) new_rb_ligand.set_reference_frame(ref) # internal transformation. The relationship is Tdock = Trec * Ti Ti = alg.compose(Trec.get_inverse(), Tdock) Tinternal.append(Ti) fn_relative = "relative_positions_%s-%s.txt" % (rec, lig) io.write_transforms(Tinternal, fn_relative) rb_ligand.set_reference_frame(initial_ref)
args = parser.parse_args() if(not args.fn_receptor): parser.print_help() sys.exit() if(args.log): logging.basicConfig(filename=args.log, filemode="w") else: logging.basicConfig(stream=sys.stdout) logging.root.setLevel(logging.DEBUG) sel = atom.ATOMPDBSelector() m = IMP.Model() h_receptor = atom.read_pdb(args.fn_receptor, m, sel) rb_receptor = atom.create_rigid_body(h_receptor) h_ligand = atom.read_pdb(args.fn_ligand, m, sel) rb_ligand = atom.create_rigid_body(h_ligand) if args.dock: check_for_hexdock() if not args.fn_transforms or not args.fn_internal_transforms: raise IOError("Docking requires the --int and --hex arguments") hex_docking = HexDocking() hex_docking.dock(args.fn_receptor, args.fn_ligand, args.fn_transforms) # read the HEX file of solutions and get the internal transformations # giving the relative orientation of the ligand respect to the receptor Ts = read_hex_transforms(args.fn_transforms) rb_receptor = atom.create_rigid_body(h_receptor) Tis = [get_internal_transform(T, rb_receptor, rb_ligand) for T in Ts] io.write_transforms(Tis, args.fn_internal_transforms) elif args.write:
def test_rigid_body_image_fit_restraint(self): """Test scoring with RigidBodiesImageFitRestraint""" m = IMP.kernel.Model() # read full complex fn = self.get_input_file_name("1z5s.pdb") prot = atom.read_pdb(fn, m, IMP.atom.ATOMPDBSelector()) # read components names = ["1z5sA", "1z5sB", "1z5sC", "1z5sD"] fn_pdbs = [self.get_input_file_name(name + ".pdb") for name in names] components = [ atom.read_pdb(fn, m, IMP.atom.ATOMPDBSelector()) for fn in fn_pdbs ] components_rbs = [atom.create_rigid_body(c) for c in components] # img R = alg.get_identity_rotation_3d() reg = em2d.RegistrationResult(R) img = em2d.Image() img.set_size(80, 80) srw = em2d.SpiderImageReaderWriter() resolution = 5 pixel_size = 1.5 options = em2d.ProjectingOptions(pixel_size, resolution) ls = core.get_leaves(prot) em2d.get_projection(img, ls, reg, options) # img.write("rbfit_test_image.spi",srw) # set restraint score_function = em2d.EM2DScore() rb_fit = em2d.RigidBodiesImageFitRestraint(score_function, components_rbs, img) pp = em2d.ProjectingParameters(pixel_size, resolution) rb_fit.set_projecting_parameters(pp) # set the trivial case: n_masks = 1 for rb in components_rbs: # set as the only possible orientation the one that the rigid # body already has rb_fit.set_orientations(rb, [ rb.get_reference_frame().get_transformation_to().get_rotation( ) ]) self.assertEqual(rb_fit.get_number_of_masks(rb), n_masks, "Incorrect number rigid body masks") # Calculate the positions of the rigid bodies respect to the centroid # of the entire molecule ls = core.get_leaves(prot) xyzs = core.XYZs(ls) centroid = core.get_centroid(xyzs) coords = [rb.get_coordinates() - centroid for rb in components_rbs] for rb, coord in zip(components_rbs, coords): rb.set_coordinates(coord) # Check that the value is a perfect registration m.add_restraint(rb_fit) score = rb_fit.evaluate(False) # print "score ...", score # It seems that projecting with the masks is slightly less accurate # I have to establish a tolerance of 0.03 self.assertAlmostEqual(score, 0, delta=0.03, msg="Wrong value for the score %f " % (score))