Esempio n. 1
0
 def set_complementarity_restraint(self, name1, name2, rname,
                                      max_sep_distance, max_penetration,
                                      weight,max_score=1e10):
     """
         Set a restraint for geometric complementarity between 2 components
         @param name1 name of
         @param name2 - The restraint is applied to this components
         @param rname - The name given to the restraint
         @param max_sep_distance - maximum distance between molecules
                             tolerated by the restraint
         @param max_penetration - Maximum penetration allowd (angstrom)
         @param weight
         @param max_score
     """
     log.info("Setting geometric complementarity restraint %s: %s - %s",
                         rname, name1, name2)
     A = representation.get_component(self.assembly, name1)
     B = representation.get_component(self.assembly, name2)
     restraint = multifit.ComplementarityRestraint(atom.get_leaves(A),
                               atom.get_leaves(B), rname)
     restraint.set_maximum_separation(max_sep_distance)
     restraint.set_maximum_penetration(max_penetration)
     log.debug("Maximum separation: %s Maximum penetration score: %s",
                  max_sep_distance, max_penetration)
     self.add_restraint(restraint, rname, weight, max_score)
Esempio n. 2
0
 def set_connectivity_restraint(self, names, rname,
                                distance=10,
                                weight=1.0, max_score=None, n_pairs=1,
                                stddev=2):
     """
         Set a connectivity restraint between the elements of the assembly
         @param names List with all the elements to be connected
         @param distance  Maximum distance tolerated by the restraint
         @param rname Name for the restraint
         @param weight Weight for the restraint
         @param max_score Maximum score for the restraint
         @param n_pairs Number of pairs of particles used in the
                     KClosePairScore of the connecitivity restraint
         @param stddev Standard deviation used to approximate the
                             HarmonicUpperBound function to a Gaussian
     """
     components = []
     for name in names:
         c = representation.get_component(self.coarse_assembly,name)
         components.append(c)
     log.info("Connectivity restraint for %s",components)
     spring_constant = core.Harmonic.get_k_from_standard_deviation(stddev)
     if max_score == None:
         max_score = weight * spring_constant * n_pairs * (stddev)**2
     r = restraints.get_connectivity_restraint(components, distance, n_pairs,
                                    spring_constant)
     self.add_restraint(r, rname, weight, max_score)
Esempio n. 3
0
    def set_pair_score_restraint(self, name1, name2,
                        restraint_name, distance=10,
                        weight=1.0, n_pairs = 1, stddev=2, max_score=None):
        """
            Set a pair_score restraint between the coarse representation
            of two components
            @param name1 Name of the first component
            @param name2 Name of the second component
            @param restraint_name Name for the restraint
            @param distance Maximum distance tolerated between particles
            @param weight Weight of the restraint
            @param n_pairs
            @param max_score Maximum value tolerated for the restraint
            @param stddev Standard deviation used to approximate the
                HarmonicUpperBound function to a Gaussian
        """
        table_refiner = core.TableRefiner()

        # The particles in A are attached to a marker particle via a refiner.
        # When the refiner gets a request for marker1, it returns the attached
        # particles
        A = representation.get_component(self.coarse_assembly, name1)
        marker1 = IMP.kernel.Particle(self.model, "marker1 "+restraint_name)
        table_refiner.add_particle(marker1, atom.get_leaves(A))
        # same for B
        B = representation.get_component(self.coarse_assembly, name2)
        marker2 = IMP.kernel.Particle(self.model, "marker2 "+restraint_name)
        table_refiner.add_particle(marker2, atom.get_leaves(B))

        k = core.Harmonic.get_k_from_standard_deviation(stddev)
        score = core.HarmonicUpperBoundSphereDistancePairScore(distance, k)
        # The score is set for the n_pairs closest pairs of particles
        pair_score = core.KClosePairsPairScore(score, table_refiner, n_pairs)
        #  When KClosePairsPairScore is called, the refiner will provide the
        # particles for A and B
        if not max_score:
            # Build a maximum score based on the function type that is used,
            # an HarmonicUpperBound
            temp_score = core.HarmonicUpperBound(distance, k)
            error_distance_allowed = 10
            max_score = weight * n_pairs * \
                        temp_score.evaluate(distance + error_distance_allowed)

        log.info("Setting pair score restraint for %s %s. k = %s, max_score " \
            "= %s, stddev %s", name1, name2, k, max_score,stddev)
        r = core.PairRestraint(pair_score, IMP.kernel.ParticlePair( marker1, marker2 ) )
        self.add_restraint(r, restraint_name, weight, max_score)
Esempio n. 4
0
 def set_xlink_restraint(self, id1, chain1, residue1, id2, chain2, residue2,
                              distance, weight, stddev, max_score=False):
     """
         Set a restraint on the maximum distance between 2 residues
         @param id1 Name of the first component
         @param chain1
         @param residue1 Residue number for the aminoacid in the first
             component.The number is the number in the PDB file, not the
             number relative to the beginning of the chain
         @param id2 Name of the second component
         @param chain2
         @param residue2 Residue number for the aminoacid in the second
           component.
         @param distance Maximum distance tolerated
         @param weight Weight of the restraint
         @param stddev Standard deviation used to approximate the
             HarmonicUpperBound function to a Gaussian
         @param max_score See help for add_restraint(). If none is given,
         the maximum score is set to allow a maximum distance of 10 Angstrom
         greater than the parameter "distance".
     """
     xlink = buildxlinks.Xlink(id1, chain1, residue1, id2, chain2, residue2, distance)
     log.info("Setting cross-linking restraint ")
     log.info("%s", xlink.show())
     self.xlinks_dict.add(xlink)
     # setup restraint
     A = representation.get_component(self.assembly, xlink.first_id)
     s1=IMP.atom.Selection(A, chain=xlink.first_chain,
                             residue_index=xlink.first_residue)
     p1 = s1.get_selected_particles()[0]
     B = representation.get_component(self.assembly, xlink.second_id)
     s2=IMP.atom.Selection(B, chain=xlink.second_chain,
                             residue_index=xlink.second_residue)
     p2 = s2.get_selected_particles()[0]
     k = core.Harmonic.get_k_from_standard_deviation(stddev)
     score = core.HarmonicUpperBound(xlink.distance, k)
     pair_score = IMP.core.DistancePairScore(score)
     r = IMP.core.PairRestraint(pair_score, IMP.kernel.ParticlePair(p1, p2))
     if not max_score:
         error_distance_allowed = 100
         max_score = weight * score.evaluate(distance + error_distance_allowed)
     log.info("%s, max_score %s", xlink.show(), max_score)
     self.add_restraint(r, xlink.get_name(), weight, max_score)
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)